ASP MVC can't display image in view - c#

So I've got this image in the shape of a byte[] that I want to display in my view.
This is my model of the image:
public class ImageModel
{
public Byte[] imageFirst { get; set; }
}
This is my controller picking out the image from a db:
public ActionResult Image()
{
string cs = "Data Source=" + Environment.CurrentDirectory + "\\ImageDB.db";
using (SQLiteConnection con = new SQLiteConnection(cs))
{
var listOfImages = new List<ImageModel>();
string stm = "SELECT * FROM Image";
con.Open();
using (SQLiteCommand cmd = new SQLiteCommand(stm, con))
{
using (SQLiteDataReader rdr = cmd.ExecuteReader())
{
while (rdr.Read())
{
listOfImages.Add(new ImageModel
{
imageFirst = Serialize(rdr["image_first"]),
});
}
rdr.Close();
Images = listOfImages;
}
}
con.Close();
}
return View(Images);
}
public static byte[] Serialize(object obj)
{
var binaryFormatter = new BinaryFormatter();
var ms = new MemoryStream();
binaryFormatter.Serialize(ms, obj);
return ms.ToArray();
}
And this is when I try to show the image in the view:
<img src="data:image/jpg;base64,#(Convert.ToBase64String(#item.imageFirst))" width="300px"/>
But all I get is this icon:
I can't for the love of me figure out why it can't be shown. The images are stored as what I can only assume is a blob in the database, but right now I wish they were just image files on the disc, as that seems to make it a lot easier to attach them to the view.

Assuming the imageFirst property is a valid image byte array, you may need to include html raw mode on the output:
<img src="data:image/jpg;base64,#Html.Raw(Convert.ToBase64String(item.imageFirst))" width="300px"/>
Also, use item instead of #item since you are already inside of #(), or in the example #Html.Raw.

Which browser you are using. IE has a size limit on the data URI, I think it is 32 KB. What is the size of your image string after converting to base64.

Related

I want to save image in jpg format from SQL Server database but when I download it , it has only 1KB size and cannot be opened

private void Msg1_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
{
string SaveFileTo = "D:\\DA.jpg";
// string SaveFileTo = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
// string filename = "jmk.jpg";
// SaveFileTo = Path.Combine(SaveFileTo, filename);
CN.Open();
SqlCommand cmd = new SqlCommand("select photo from edistindata where enrollno='" + CboEnroll.Text + "' ", CN);
DR = cmd.ExecuteReader();
byte[] data = null;
while (DR.Read())
{
data = (byte[])DR["Photo"];
}
using (var fs = new FileStream(SaveFileTo, FileMode.Create, FileAccess.Write))
{
fs.Write(data,0,data.Length);
}
MessageBox.Show("Success");
}
I have run the code in the question, even it has some of not good coding practices, if the data in the photo column is not corrupted it should produce the image file.
so I have put down your code with proper enhancements that will flag you early before saving corrupted data.
private void Msg1_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
{
ImageCodecInfo theJpgCodecInfo = ImageCodecInfo.GetImageEncoders()
.FirstOrDefault(encoder => encoder.MimeType == "image/jpeg");
var myEncoder = Encoder.Quality;
var myEncoderPrams = new EncoderParameters(1);
myEncoderPrams.Param[0] = new EncoderParameter(myEncoder, 100L);
string SaveFileTo = "D:\\DA";
// string SaveFileTo = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
// string filename = "jmk.jpg";
// SaveFileTo = Path.Combine(SaveFileTo, filename);
CN.Open();
SqlCommand cmd = new SqlCommand("select photo from edistindata where
enrollno=#Enrol;", CN);
cmd.Parameters.AddWithValue("#Enrol", CboEnroll.SelectedItem.ToString());
DR = cmd.ExecuteReader();
byte[] data = null;
int idx = 0;
while (DR.Read())
{
data = (byte[])DR["Photo"];
Image tempImage;
try
{
tempImage = ByteArrayToImage(data);
}
catch (Exception exc)
{
MessageBox.Show(exc.GetType().ToString()
+Environment.NewLine+exc.Message);
continue;
}
var tempBitmap = new Bitmap(tempImage);
var tempFname = "D:\\DA"+(idx++).ToString()+".jpg";
tempBitmap.Save(tempFname, theJpgCodecInfo, myEncoderPrams);
}
}
public static Image ByteArrayToImage(byte[] byteArrayIn)
{
using (MemoryStream ms = new MemoryStream(byteArrayIn))
{
Image returnImage = Image.FromStream(ms);
return returnImage;
}
}
The enhancements that I suggested as follow:
As #derpirscher mentioned in his comment use parameters not string concatenation when building SQL commands and the easiest most lazy way to do it is Parameters.AddWithValue().
Use CboBox.SelectedItem.ToString in place of the .Text as been in your code.
instead of dumping the byte[] directly through a FileStream.Write() I transferred the byte array into Image() then into Bitmap().
this way if the byte[] (and hence the data in the db column photo) is not one of the binary formats the the class Image() can handle it will throw exception and I used that to show the related error.
Also, this way we over came some issues that may rise if we used Bitmap() directly if the data byte[] contains PNG format.
No matter what image format is stored in the photo column it will be legitimately re-encoded as Jpeg then saved.

How to save an image into a database?

I am using WPF to insert an image to my MySQL database. I can upload the file to image control but I don't know how to save it.
Here is what I've done so far. The emp_image is the image control that displays the photo.
private void btn_save_image_click(object sender,...)
{
Mysqlconnection cn= new mysqlconnection(connectionstring);
byte[] imagedata;
imagedata=File.ReadAllBytes(emp_img); //..here is error,it says has invalid arguments..//
mysqlcommand= new mysqlcommand("insert into dep_table(photo)values(?data)",cn);
cmd.parameters.addwithvalue("?data", imagedata);
cn.open();
cmd.executeNonQuery();
cn.close();
}
you need to convert the image source to byte[] :
public static byte[] ImageToArray(BitmapSource image)
{
var encoder = new JpegBitmapEncoder();
encoder.Frames.Add(BitmapFrame.Create(image));
using (var stream = new MemoryStream())
{
encoder.Save(stream);
return stream.ToArray();
}
}
Then, call the function:
imagedata = ImageToArray((BitmapSource)emp_img.Source);
Seems you are not passing the file path.
Please check File::ReadAllBytes Method
Should be something like
var imagedata=File.ReadAllBytes(filepath);

Image isn't showing up in sql server database after sending image to it from MVC WCF service

I send the image from a Windows Phone 8 App to an MVC WCF service. I know it is receiving the image, because when it does receive the image, it is instructed to save the image in a local folder called "uploads". Every time the image gets there it is put into this folder so I can tell that it was uploaded. My trouble is with uploading it to my SQL Server database. Everything compiles, but when I check my database table, it is not there. Please help.
namespace MVCImageUpload.Controllers
{
public class FileUploadController : Controller
{
// GET: /FileUpload/
[HttpPost]
public ActionResult Index()
{
var fileUploaded = false;
foreach (string upload in Request.Files)
{
if (!HasFile(Request.Files[upload]))
continue;
string path = Path.Combine(
AppDomain.CurrentDomain.BaseDirectory,
"uploads");
string filename = Path.GetFileName(
Request.Files[upload].FileName);
if (!Directory.Exists(path))
Directory.CreateDirectory(path);
Request.Files[upload].SaveAs(Path.Combine(
path, filename));
fileUploaded = true;
updatedata(filename);
}
this.ViewData.Add("uploaded", fileUploaded);
return View();
}
private static bool HasFile(HttpPostedFileBase file)
{
return (file != null && file.ContentLength > 0) ? true : false;
}
private void updatedata(string imagename)
{
//use filestream object to read the image.
//read to the full length of image to a byte array.
//add this byte as an oracle parameter and insert it into database.
try
{
//proceed only when the image has a valid path
if (imagename != "")
{
FileStream fs;
fs = new FileStream(#imagename, FileMode.Open, FileAccess.Read);
//a byte array to read the image
byte[] picbyte = new byte[fs.Length];
fs.Read(picbyte, 0, System.Convert.ToInt32(fs.Length));
fs.Close();
//open the database using odp.net and insert the data
string connstr = #".\SQLEXPRESS;Database=ImageDB;Trusted_Connection=True;";
SqlConnection conn = new SqlConnection(connstr);
conn.Open();
string query;
query = "insert into Images(ActualImage) values(#ActualImage)";
SqlParameter picparameter = new SqlParameter();
picparameter.SqlDbType = SqlDbType.Image;
picparameter.ParameterName = "ActualImage";
picparameter.Value = picbyte;
SqlCommand cmd = new SqlCommand(query, conn);
cmd.Parameters.Add(picparameter);
cmd.ExecuteNonQuery();
//MessageBox.Show("Image Added");
cmd.Dispose();
conn.Close();
conn.Dispose();
//Connection();
}
}
catch (Exception ex)
{
//MessageBox.Show(ex.Message);
}
}
}
}
You can skip a step and save the file directly into the database.
HttpPostedFileBase Picture = Request.Files["Picture"];
Byte[] Bytes = new byte[Picture.ContentLength];
string ContentType = Picture.ContentType;
string FileName = Picture.FileName;
Picture.InputStream.Read(Bytes, 0, Picture.ContentLength);
You now have Name, Bytes, and content type which u can store in the database.

How to get Image data from SQL Server, Write To File, Save File to Disk using C#

I'm trying to get attachments (images, word documents, etc.) stored as an Image datatype from a SQL Server database. The attachments can be of any file type, but I'm just trying to get a .jpg to download successfully.
I'm able to save the file to my local drive, but it appears to be corrupting the file in the process.
What I'm trying to do:
Retrieve binary data of type IMAGE from SQL Server Database.
Create a file from the binary data.
Save the file to a local directory.
My CODE:
public void ProcessRequest()
{
//Get the ticket number from query string
_ticketNumber = context.Request.QueryString["ID"];
SqlConnection conn = new SqlConnection(_DBConn);
SqlCommand cmd = new SqlCommand();
string fileName = ""; //Holds the file name retrieved from DB
byte[] data; // Holds the IMAGE data from DB
using (conn)
{
using (cmd)
{
cmd.CommandType = CommandType.Text;
cmd.CommandText = #"SELECT File_Name, Data FROM Tickets_All INNER JOIN Attachments ON Tickets_All.ID = Attachments.[Object_ID] WHERE Ticket = #Ticket";
cmd.Parameters.AddWithValue("#Ticket", _ticketNumber);
cmd.Connection = conn;
conn.Open();
SqlDataReader reader = cmd.ExecuteReader();
if (reader.HasRows)
{
while (reader.Read())
{
fileName = reader.GetString(0);
data = (byte[])reader["Data"];
if (data != null)
{
SaveData(fileName, data);
}
}
}
reader.Close();
}
}
protected bool SaveData(string FileName, byte[] Data)
{
string path = #"C:\Windows\temp\test.jpg";
try
{
BinaryWriter writer = new BinaryWriter(File.OpenWrite(path));
writer.Write(Data);
writer.Flush();
writer.Close();
}
catch (Exception ex)
{
return false;
}
return true;
}
Please forgive me if the code isn't up to par with best practices, I'm more of a VB programmer and I've never had to do this before. I'm just trying to get a working example.
Thanks in advance.
I would use the Image.FromStream method to do this :
http://msdn.microsoft.com/en-us/library/system.drawing.image.fromstream(v=vs.110).aspx
protected bool SaveData(string FileName, byte[] Data)
{
using (Image image = Image.FromStream(new MemoryStream(Data)))
{
image.Save("MyImage.jpg", ImageFormat.Jpeg);
}
return true;
}
Thanks for the input everyone. After doing some additional testing, I think that the data being retrieved from the database has been compressed in some way. I'm able to insert and pull out files programmatically just fine, the problem comes in when the application puts the data into the database (3rd party software). I'm going to look into the compression what I can come up with.

showing image in gridview from byte array

I have a following problem:
I am using c# and .aspx pages. On .aspx page i have a GridView. I set a GridView datasource to be:
GridView1.DataSource = PictureInfo.PictureInfoList;
My "PictureInfo" class looks like this:
public class PictureInfo
{
public static List<PictureInfo> PictureInfoList = new List<PictureInfo>();
public string PictureDescription { get; set; }
public byte[] Picture { get; set; }
}
Is it possible and how to show a picture which is in "byte[] Picture" in a GridView? Or which way it is possible? I'm saving data in this way before i send it to a database. And i would like to show it in a GridView before i send it to a database. As you can see I'm a beginner but i would be very happy if i could make this work. My head hearts already from reading some solutions online, none helped until now.
thank you very much
I suggest you a solution for: Converting byte[] to Bitmap (may it will be useful for you):
public BitmapSource ByteArrayToBitmap(byte[] byteArray) {
BitmapSource res;
try {
using (var stream = new MemoryStream(byteArray)) {
using (var bmp = new Bitmap(stream)) {
res = ToBitmap(bmp);
}
}
} catch {
res = null;
}
return res;
}
public BitmapSource ToBitmap(Bitmap bitmap) {
using (var stream = new MemoryStream()) {
bitmap.Save(stream, ImageFormat.Bmp);
stream.Position = 0;
var result = new BitmapImage();
result.BeginInit();
result.CacheOption = BitmapCacheOption.OnLoad;
result.StreamSource = stream;
result.EndInit();
result.Freeze();
return result;
}
}
Next, you should adapt, and include the Bitmap in your GridView.
on your handler.ashx
public void ProcessRequest(HttpContext context)
{
context.Response.ContentType = "image/jpeg";
string ImageID=request["ID"];
//byte[] ImageByte=pictureInfo.Picture;//local imageByte
byte[] ImageByte=getImage(ImageId);//image byte from any other sour,e.g database
Stream strm = new MemoryStream(ImageByte));
long length = strm.Length;
byte[] buffer = new byte[length];
int byteSeq = strm.Read(buffer, 0, 2048);
while (byteSeq > 0)
{
context.Response.OutputStream.Write(buffer, 0, byteSeq);
byteSeq = strm.Read(buffer, 0, 2048);
}
}
now set image url for your asp:image inside your gridview as follows
Image1.ImageUrl = "somthing.ashx?ID="+userImageID;
i hope you have unique id for your image to be visible. I hope you have all set now. Comments and query are well comed.
retrieve image byte from database
public byte[] GetImage(string ImageId)
{ byte[] img = null;
DataTable dt = new DataTable();
SqlCommand cmd = new SqlCommand();
cmd.CommandType = CommandType.StoredProcedure;
cmd.CommandText = "SlikaHendler";
cmd.Parameters.AddWithValue("#Id", ImageId);
cmd.Connection = yourConnection();
SqlDataReader dr = null;
dr = cmd.ExecuteReader();
if (dr.Read())
{
img = (byte[])dr[0];
}
dr.Close();
return img;//returns array of byte
}
I know pictures are recorded as binaries to databases. In this aspect, your problem turns to a "converting binary to byte".
If you can reach your picture info as binary data, you can convert it as taking 3 digits for 1 byte, and convert & show as bytes.
http://en.wikipedia.org/wiki/ASCII

Categories

Resources