I want to display images on browser by converting them to base64 string.
Method of conversion is very simple as follows
string convertedfile = Convert.ToBase64String(fileData);
base64 string
<img src="data:image/jpeg;base64,DQoaCgAAAA1JSERSAAAAFAAAABQIBgAAAI2JHQ0AAAABc1JHQgCuzhzpAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAOxAAADsQBlSsOGwAAAAl2cEFnAAAAgAAAAIAAMOExmgAAAAZiS0dEAAAAAAAA+UO7fwAAACJ6VFh0U29mdHdhcmUAAHjaKy8v18vMyy5OTixI1csvSgcANtgGWBBTylwAAADzSURBVDhPY/wPBAxUBExUNAts1KiBlIfoaBhiD8N1NycwHLi/mqgAJhiGp15uYtj1aCbD5OMZDDdenSJsKCjr4QJvfzz977GZAS5t2Mvw//P3j/i0/EeoRlP299/v/667UaX//vv7X6MOpxawCThlw04z/H//8zmGa158fPDfsBq3oYzYSpusW8IMPgJVDEa8gQxff31k+P8PaPE/Bob/fxkYuNkEGfZeXskwZ1cnw6Hm9xhhimHgn/8/Gea9SGP485OR4fu37wx/fzIw/PkBwTA2818OIP8fQ0P4XAY2FjYUQ7G6kHBU4lZBMNmQavjgNxAArnYq4oN7ItkAAAAASUVORK5CYII=" alt="Original File"/>
For some reason my browser is not able to display it. Is there any MIME type I have to set in IIS? or what could be the problem?
Edit:
To write file data to SQL
Stream fs = imgUpload.PostedFile.InputStream;
BinaryReader br = new BinaryReader(fs);
Byte[] bytes = br.ReadBytes((Int32)fs.Length);
//string base64String = Convert.ToBase64String(bytes);
//imgPicture.Src = "data:image/png;base64," + base64String;
SqlConnection conn = new SqlConnection(System.Configuration.ConfigurationManager.ConnectionStrings["connectionString"].ToString());
conn.Open();
using (SqlCommand cmd = new SqlCommand("update tbEHUsers set photo=#binaryValue where UserID=101", conn))
{
// Replace 8000, below, with the correct size of the field
cmd.Parameters.Add("#binaryValue", SqlDbType.VarBinary, -1).Value = bytes;
cmd.ExecuteNonQuery();
}
conn.Close();
My method to get image data from SQL(column datatype varbinary)
byte[] fileData =null;
using (SqlDataReader rdr = CMD.ExecuteReader(CommandBehavior.SequentialAccess))
{
if (rdr.Read())
{
// For some reason the data being returned is blank
// When I run it in SQL I get data being returned.
fileData = (byte[])rdr.GetValue(0);
using (System.IO.FileStream fs = new System.IO.FileStream("D:\\Testing.jpg", System.IO.FileMode.Create, System.IO.FileAccess.ReadWrite))
{
using (System.IO.BinaryWriter bw = new System.IO.BinaryWriter(fs))
{
bw.Write(fileData);
bw.Close();
}
}
}
rdr.Close();
}
The data that you have isn't a PNG image at all. Exchange it for a real PNG image, and it will work.
Example, a 10x10 red square:
<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAXSURBVChTY/jPwPCfGDyqEC+mtkKG/wCSw8c5Wcde4gAAAABJRU5ErkJggg==">
Here is your original image in base64 form:
<img src="data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRofHh0aHBwgJC4nICIsIxwcKDcpLDAxNDQ0Hyc5PTgyPC4zNDL/2wBDAQkJCQwLDBgNDRgyIRwhMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjL/wAARCAAUABQDASIAAhEBAxEB/8QAGAABAAMBAAAAAAAAAAAAAAAAAAQFBgf/xAAiEAABBAEDBQEAAAAAAAAAAAABAAIDBBEFEkETITFDUbH/xAAWAQEBAQAAAAAAAAAAAAAAAAAAAgP/xAAZEQEBAQADAAAAAAAAAAAAAAAAAQIDERL/2gAMAwEAAhEDEQA/AO/oot+62jW6hALnO2MDjgFx+ngck/pwFUQaxFSuwwyaky7HaeGEtxuilPjDR6ye3JacZJBJbneXM15TdyXpoURFooREQEREH//Z">
Related
I followed the code from this guide in order to resize an image before storing it in a database:
https://www.aspsnippets.com/questions/876401/Resize-image-and-save-into-Database-with-Binary-format-using-C-and-VBNet-in-ASPNet/
Here is the code:
protected void Save(object sender, EventArgs e)
{
if (fuImage.HasFile)
{
Byte[] bytes;
string contentType = fuImage.PostedFile.ContentType;
string fileName = Path.GetFileName(fuImage.FileName);
string filePath = fuImage.PostedFile.FileName;
System.Drawing.Image image = System.Drawing.Image.FromFile(filePath);
// Resize image
using (System.Drawing.Image thumbnail = image.GetThumbnailImage(130, 170, new System.Drawing.Image.GetThumbnailImageAbort(ThumbnailCallback), IntPtr.Zero))
{
using (MemoryStream memoryStream = new MemoryStream())
{
thumbnail.Save(memoryStream, ImageFormat.Png);
bytes = new Byte[memoryStream.Length];
memoryStream.Position = 0;
memoryStream.Read(bytes, 0, (int)bytes.Length);
}
}
// Insert uploaded image to Database
string constr = ConfigurationManager.ConnectionStrings["constr"].ConnectionString;
using (SqlConnection con = new SqlConnection(constr))
{
string query = "INSERT INTO tblFiles1 VALUES (#Name, #ContentType, #Data)";
using (SqlCommand cmd = new SqlCommand(query))
{
cmd.Connection = con;
cmd.Parameters.AddWithValue("#Name", fileName);
cmd.Parameters.AddWithValue("#ContentType", contentType);
cmd.Parameters.AddWithValue("#Data", bytes);
con.Open();
cmd.ExecuteNonQuery();
con.Close();
}
}
}
// Display image after upload to Database
Image1.Visible = true;
byte[] byteData = (byte[])GetData("SELECT Data FROM tblFiles1").Rows[0]["Data"];
string base64String = Convert.ToBase64String(byteData, 0, byteData.Length);
Image1.ImageUrl = "data:image/png;base64," + base64String;
}
public bool ThumbnailCallback()
{
return false;
}
The problem I am getting however, is once I select an image using the FileUploader and try to run the save method, I get a System.IO.FileNotFoundException at the line:
System.Drawing.Image image = System.Drawing.Image.FromFile(filePath);
Thanks in advance!
The FileName property is the file name property from the client (https://learn.microsoft.com/en-us/dotnet/api/system.web.httppostedfilebase.filename?view=netframework-4.8#System_Web_HttpPostedFileBase_FileName) so you can't load the file using that property. I can upload an image from c:\yfeyhcdrt\image.png, but this folder will probably not exist on your server. You should load it using the InputStream property instead using https://learn.microsoft.com/en-us/dotnet/api/system.drawing.image.fromstream?view=windowsdesktop-5.0
I am trying to retrieve jpeg files stored in SQL Server and present these in html using img src="filepath" but my C# code is returning the actual image, not a URL path to the image and this just displays a tiny image box with an x in it.
How can I display the image directly as an image variable.
Here is the HTML page with Razor C#:
#{
int iFileID = 8;
string sPhotoDesc = "";
Image iPhotoImage = null;
}
<form>
<fieldset>
<legend>FileInput</legend>
<input type="file" id="fileinput" />
<input type='button' id='btnLoad' value='Load' onclick="#{iPhotoImage =
PhotoLibraryApp.PhotoData.SelectPhoto(iFileID, out sPhotoDesc); }">
<div id="editor"></div>
</fieldset>
<img src="#iPhotoImage" width="500" height="377">
Here is the relevant C# code in a separate file called PhotoData.cs:
using System;
using System.Data;
using System.Data.SqlClient;
using System.Data.SqlTypes;
using System.Drawing;
using System.IO;
using System.Transactions;
namespace PhotoLibraryApp
{
public class PhotoData
{
private const string ConnStr =
"Data Source=.;Integrated Security=True;Initial
Catalog=PhotoLibrary;";
public static Image SelectPhoto(int photoId, out string desc)
{
const string SelectTSql = #"
SELECT
Description,
Photo.PathName(),
GET_FILESTREAM_TRANSACTION_CONTEXT()
FROM PhotoAlbum
WHERE PhotoId = #PhotoId";
Image photo;
string serverPath;
byte[] serverTxn;
using (TransactionScope ts = new TransactionScope())
{
using (SqlConnection conn = new SqlConnection(ConnStr))
{
conn.Open();
using (SqlCommand cmd = new SqlCommand(SelectTSql, conn))
{
cmd.Parameters.Add("#PhotoId", SqlDbType.Int).Value = photoId;
using (SqlDataReader rdr = cmd.ExecuteReader())
{
rdr.Read();
desc = rdr.GetSqlString(0).Value;
serverPath = rdr.GetSqlString(1).Value;
serverTxn = rdr.GetSqlBinary(2).Value;
rdr.Close();
}
}
photo = LoadPhotoImage(serverPath, serverTxn);
}
ts.Complete();
}
return photo;
}
private static Image LoadPhotoImage(string filePath, byte[] txnToken)
{
Image photo;
using (SqlFileStream sfs =
new SqlFileStream(filePath, txnToken, FileAccess.Read))
{
photo = Image.FromStream(sfs);
sfs.Close();
}
return photo;
}
}
}
After trying to find an answer for 3 days, the following worked.
Summary, once the iPhotoImage is returned from the database SQLFilestream code, this was then converted to a byte array using TurnImageToByteArray and then the imgBytes bytes were converted to string imgString which displayed the image in HTML.
Here are the additional pieces of code:
#{
//Get the file ID you want to display
int iFileID = 8;
string sPhotoDesc = "";
Image iPhotoImage = null;
iPhotoImage = PhotoLibraryApp.PhotoData.SelectPhoto(iFileID, out
sPhotoDesc);
byte[] imgBytes =
PhotoLibraryApp.PhotoData.TurnImageToByteArray(iPhotoImage);
string imgString = Convert.ToBase64String(imgBytes);
}
I added the following method to my PhotoData class:
public static byte[] TurnImageToByteArray(Image img)
{
MemoryStream ms = new MemoryStream();
img.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg);
return ms.ToArray();
}
The following is the html to display the image:
<img id="JpegImage" alt="Photo Alternative" src="data:image/jpeg;base64, #imgString">
After more effort, I found that I could not save to Memory stream for JPEG images. This gave the ubiquitous General GDI error. The JPEG files had to be converted to bitmp images first using the following code before I could get them to display:
(var ms = new MemoryStream())
{
Bitmap bmp = new Bitmap(imageToConvert);
bmp.Save(ms, format);
return ms.ToArray();
}
Another note: The JPEG files come back from SQL Filestream as an image type of Bitmap, this was what clued me in to try this along with the entry by #Amir Atasin here: A generic error occurred in GDI+, JPEG Image to MemoryStream
We are trying to migrate our code from ASP.NET that was written some time ago to ASP.NET Core 2.0.
This piece of code stores a document in SQL Server and retrieves it.
***Original Code:***
protected void btnUpload_Click(object sender, EventArgs e)
{
foreach (HttpPostedFile postedFile in multipleUpload.PostedFiles)
{
string filename = Path.GetFileName(postedFile.FileName);
string contentType = postedFile.ContentType;
using (Stream fs = postedFile.InputStream)
{
using (BinaryReader br = new BinaryReader(fs))
{
byte[] bytes = br.ReadBytes((Int32)fs.Length);
string constr = ConfigurationManager.ConnectionStrings["ab"].ConnectionString;
using (SqlConnection con = new SqlConnection(constr))
{
string query = "insert into ftr_UploadMultiple (name,contentType,data) values (#Name, #ContentType, #Data)";
using (SqlCommand cmd = new SqlCommand(query))
{
cmd.Connection = con;
cmd.Parameters.AddWithValue("#Name", filename);
cmd.Parameters.AddWithValue("#ContentType", contentType);
cmd.Parameters.AddWithValue("#Data", bytes);
con.Open();
cmd.ExecuteNonQuery();
con.Close();
We did try with the following code, it only stores 0 bytes in the DB:
Any suggestions around this should be really helpful.
Our Code in ASP.NET Core 2.0
if (file.Length > 0)
{
using (var stream = new
FileStream(filePath, FileMode.Create))
{
await file.CopyToAsync(stream);
using (BinaryReader br = new BinaryReader(stream))
{
byte[] bytes = br.ReadBytes((Int32)stream.Length);
string constr = "<Connection String";
using (SqlConnection con = new SqlConnection(constr))
{
string query = "insert into ftr_UploadMultiple (data) values (#Data)";
using (SqlCommand cmd = new SqlCommand(query))
{
cmd.Connection = con;
cmd.Parameters.AddWithValue("#Data", bytes);
con.Open();
cmd.ExecuteNonQuery();
con.Close();
I have deliberately removed the closing }s. Also, facing an issue in Downloading already uploaded file as Response.Binarywrite() is not available in ASP.NET Core 2.0.
After you call CopyToAsync to copy the bytes from the upload file to the filestream, the filestream's position is at the end. When you then attempt to read from the filestream, you're only reading the null byte at the end, resulting in 0 bytes being read.
The simplest solution is to just add the following before you read:
stream.Position = 0;
However, unless you actually need to write the file to the filesystem as well, this is just extraneous work. It would be better to copy the upload file's stream to a MemoryStream and then simply use ToArray to get the bytes from that: no need for additional reader.
Try get bytes array from InputStream
// Read bytes from http input stream
BinaryReader b = new BinaryReader(file.InputStream);
byte[] binData = b.ReadBytes(file.ContentLength);
ASP.NET Core
if (file.Length > 0)
{
using (BinaryReader br = new BinaryReader(file.InputStream))
{
/* ... use file.Length or file.ContentLength */
byte[] bytes = br.ReadBytes(file.Length);
/* ... File Processing (bytes) */
}
}
.
I have a SQLite DB I have field called PersonalPic of Type BLOB
this is code in which I save image to SQLite
cm.CommandText = "insert into People(Name,FullName,FatherName,MotherName,NationalID,Mobile,Phone,Birth,Intma,Info,Address,CuAddress,PersonalPic,Pics) values('"+textBox1.Text+"','"+textBox2.Text+"','"+textBox3.Text+"','"+textBox4.Text+"','"+textBox5.Text+"','"+textBox6.Text+"','"+textBox7.Text+"','"+dateTimePicker1.Value.ToString("yyyy-MM-dd")+"','"+textBox8.Text+"','"+textBox9.Text+"','"+textBox10.Text+"','"+textBox11.Text+"','"+ConvertToString(personalpic)+"','"+ConvertToString(pic)+"')";
cm.ExecuteNonQuery();
public string ConvertToString(String path)
{
FileStream fs = new FileStream(path,
FileMode.OpenOrCreate, FileAccess.Read);
byte[] rawData = new byte[fs.Length];
fs.Read(rawData, 0, System.Convert.ToInt32(fs.Length));
fs.Close();
// Convert byte[] to Base64 String
string base64String = Convert.ToBase64String(rawData);
return base64String;
}
It`s saved without no problems when I try to retrieve image it gives me Parameter is no valid Exception
SQLiteDataReader reader = cm.ExecuteReader();
if (reader.HasRows)
{
while (reader.Read())
{
textBox1.Text = reader["Name"].ToString();
textBox2.Text = reader["FullName"].ToString();
textBox3.Text = reader["FatherName"].ToString();
textBox4.Text = reader["MotherName"].ToString();
textBox5.Text = reader["NationalID"].ToString();
textBox6.Text = reader["Mobile"].ToString();
textBox7.Text = reader["Phone"].ToString();
dateTimePicker1.Value = DateTime.Parse(reader["Birth"].ToString());
textBox8.Text = reader["Intma"].ToString();
textBox9.Text = reader["Info"].ToString();
byte[] photoarray = (byte[])reader["PersonalPic"];
MemoryStream ms = new MemoryStream(photoarray);
MessageBox.Show(photoarray.Length.ToString());
ms.Position = 0;
pictureBox1.Image = Image.FromStream(ms);
}
}
reader.Close();
Exception is in the Line (pictureBox1.Image = Image.FromStream(ms))
Please Help!!
Aside from the horrendous sql inject insert statement, you're converting your picture byte array to a B64 string. And you're not converting it back on the other side. You're passing complete garbage data to your pictureBox. Either convert it back from byte[] -> B64 string and then decode it back to a byte[].. or just don't save it as a B64 string in the first place
Replace ConvertToString with ConvertToBlob
public byte[] ConvertToBlob(String path)
{
FileStream fs = new FileStream(path,
FileMode.OpenOrCreate, FileAccess.Read);
byte[] rawData = new byte[fs.Length];
fs.Read(rawData, 0, System.Convert.ToInt32(fs.Length));
fs.Close();
return rawData;
}
And pass the raw data Byte[] directly to your SQL Query (which you need to rewrite as a parameterised query).
i am storing images to the database. How to retrieve all the images from the database.
Eg: select images from imagetable
Problem:
Data Logic:
while (dr.Read())
{
///Check for null
if (!dr.IsDBNull(0))
{
try
{
///Converting the image into bitmap
byte[] photo = (byte[])dr[0];
ms = new MemoryStream(photo);
Bitmap bm = new Bitmap(ms);
bmp[i] = bm;
ms.Close();
}
catch (Exception ex)
{
}
}
ASpx.CS page:
Bitmap[] bm= photos.GetImage();
for (int i = 0; i < bm.Length; i++)
{
MemoryStream ms = new MemoryStream();
**bm[i].Save(ms, ImageFormat.Jpeg);**(Error : A generic error occurred in GDI+.)
htmlCode.Append("<li><img ImageUrl=\\\"");
htmlCode.Append(**ms.GetBuffer()**);
htmlCode.Append("\" alt=\"\" width=\"100\" height=\"100\"></li>");
}
Image not getting displayed
Geetha
this is an example from Sql Server
connection.Open();
SqlCommand command1 = new SqlCommand("select imgfile from myimages where imgname=#param", connection);
SqlParameter myparam = command1.Parameters.Add("#param", SqlDbType.NVarChar, 30);
myparam.Value = txtimgname.Text;
byte[] img = (byte[])command1.ExecuteScalar();
MemoryStream str = new MemoryStream();
str.Write(img, 0, img.Length);
Bitmap bit = new Bitmap(str);
connection.Close();
look here
http://www.akadia.com/services/dotnet_read_write_blob.html
For SQL Server 2008 onwards, FILESTREAM is almost certainly the way to go.
Please see: SQL Server 2005 - How do I convert image data type to character format
You need to get the binary data from the DB, and then stream the binary data to the browser as image.
You are setting the Url of the image to be the byte stream - you need to save the image to the hard drive and provide the location.
A much better way would be to set the image url to be a resource handler with parameters that could then retrieve the image from the database and return it as a stream to the browser.