Question

if I try to explain why I need to do what I'm trying to do it will take a long time, but basically it's this: I have FileUpload control for the user to choose a Jpeg file, I make the upload and after it I want to convert that file to bytes and use it as the source of an Image control.

My code is this one:

string fileName = Server.MapPath("~/TempImages") + @"\foto.jpg";
fileUpload1.SaveAs(fileName);

System.IO.FileStream fs = new System.IO.FileStream(fileName, System.IO.FileMode.Open, System.IO.FileAccess.Read);
System.IO.BinaryReader binaryReader = new System.IO.BinaryReader(fs);
long byteLength = new System.IO.FileInfo(fileName).Length;
byte[] buffer = binaryReader.ReadBytes((Int32)byteLength);
fs.Close();
fs.Dispose();

string valor = System.Text.Encoding.UTF8.GetString(buffer);
img.ImageUrl = "data:image/jpg;base64," + valor;

The byte array is looking ok, but when I convert it to string it's full of unrecognized characters, I have another page where I do the same thing but instead of getting the bytes from the file I get it from a MySql database and using the same System.Text.Encoding.UTF8.GetString and it works withou a problem.

UPDATE As asked, this is the code I use when retrieving the from the MySql database:

DataView dv = (DataView)SqlDataSource3.Select(DataSourceSelectArguments.Empty);
byte[] buffer = (byte[])dv.Table.Rows[0]["BIN_FOTO"];
string valor = System.Text.Encoding.UTF8.GetString(buffer);
img.ImageUrl = "data:image/jpg;base64," + valor;

The select of this SqlDataSource3 is a simple Select BIN_FOTO from temp_image. I store this value in the database from a webcam capture WPF program, the code I use to convert the image the webcam captured is:

    private string ImageToBase64String(System.Drawing.Image imageData, ImageFormat format)
    {
        string base64;
        MemoryStream memory = new MemoryStream();
        imageData.Save(memory, format);
        base64 = System.Convert.ToBase64String(memory.ToArray());
        memory.Close();
        memory.Dispose();

        return base64;
    }

Then I save the base64 variable to the database.

Hope this clarifies my problem

Was it helpful?

Solution

So you want to read the image file and convert to base 64. After your reading code, do this:

string valor = Convert.ToBase64String(buffer);

Your original code was flawed because you're saving the image, as bytes, to the file with this line of code:

fileUpload1.SaveAs(fileName);

That's not saved as base64, so you have to convert it to base 64 after you read it. Your MySql reading worked because the data was converted to base64 before being saved.

By the way, there's no need for the BinaryReader in this code:

System.IO.FileStream fs = new System.IO.FileStream(fileName, System.IO.FileMode.Open, System.IO.FileAccess.Read);
System.IO.BinaryReader binaryReader = new System.IO.BinaryReader(fs);
long byteLength = new System.IO.FileInfo(fileName).Length;
byte[] buffer = binaryReader.ReadBytes((Int32)byteLength);
fs.Close();
fs.Dispose();

You can write this instead:

byte[] buffer;
using (FileStream fs = new FileStream(fileName, FileMode.Open, FileAccess.Read)
{
    long byteLength = fs.Length;
    buffer = new byte[byteLength];
    int bytesRead = fs.Read(buffer, 0, byteLength);
    // optional error check to see that you got all the bytes
    if (bytesRead != byteLength)
    {
        // handle error
    }
}
string valor = Convert.ToBase64String(buffer);

OTHER TIPS

I've found the problem, looking at the WPF code I used to convert the image to a Base64String. I just created the same function ImageToBase64String and now it works:

        string fileName = Server.MapPath("~/TempImages") + @"\foto.jpg";
        fileUpload1.SaveAs(fileName);

        System.Drawing.Image teste = System.Drawing.Image.FromFile(fileName);

        string valor = ImageToBase64String(teste, System.Drawing.Imaging.ImageFormat.Jpeg);

        //System.IO.FileStream fs = new System.IO.FileStream(fileName, System.IO.FileMode.Open, System.IO.FileAccess.Read);
        //System.IO.BinaryReader binaryReader = new System.IO.BinaryReader(fs);
        //long byteLength = new System.IO.FileInfo(fileName).Length;
        //byte[] buffer = binaryReader.ReadBytes((Int32)byteLength);
        //buffer = File.ReadAllBytes(fileName);
        //fs.Close();
        //fs.Dispose();

        //string valor = System.Text.Encoding.UTF8.GetString(buffer);
        img.ImageUrl = "data:image/jpg;base64," + valor;

But I still don't know what was wrong with my previous code, anyone can clarify?

This solution worked for me:

System.IO.BinaryReader binaryReader = new System.IO.BinaryReader(fs);
//Add this--------------------
fs.Seek(0, SeekOrigin.Begin);
//----------------------------
long byteLength = new System.IO.FileInfo(fileName).Length;
byte[] buffer = binaryReader.ReadBytes((Int32)byteLength);

Just add highlighted line.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top