1

I have uploaded an Image in to my database as byte[] and now im trying to display it out.

There was an error - Argument Exception was unhandled by user code Parameter is not valid

At this line

newImage = System.Drawing.Image.FromStream(stream);

Here is my codes

for (int i = 0; i < topRatingList.Count; i++)
            {
                int commentRating = topRatingList[i].CommentRating;
                int drinkID = topRatingList[i].DrinkID;

                if (i == 0)
                {
                    DrinkMenuDAO drink = DrinkMenuBLL.getDrinkMenu(drinkID);
                    LinkButton1.Text = drink.DrinkName; 
                    ImageButton1.ImageUrl = byteArrayToImage(drink.DrinkImage);
                }
            }


private string byteArrayToImage(byte[] byteArrayIn)
    {
        System.Drawing.Image newImage;
        string strFileName = Server.MapPath("~/Temp/images/") + ".jpg";
        if (byteArrayIn != null)
        {
            using (MemoryStream stream = new MemoryStream(byteArrayIn))
            {
                newImage = System.Drawing.Image.FromStream(stream);
                newImage.Save(strFileName);
            }
            return strFileName;
        }
        else
        {
            return "";
        }
    }

the code that i used to store the image

protected void bn_upload_Click(object sender, EventArgs e)
    {
        lbl_msg.Text = "";
        Stream imgStream = FileUpload1.PostedFile.InputStream;
        BinaryReader imgBinary = new BinaryReader(imgStream);
        bytes = imgBinary.ReadBytes((Int32)imgStream.Length);
        imgBinary.Close();
        imgStream.Close();
        string src = byteArrayToImage(bytes);
        if (src.Equals(""))
        {
        }
        else
        {
            Image1.ImageUrl = "~/Temp/UploadedImage.jpg";
        }
    }

    private string byteArrayToImage(byte[] byteArrayIn)
    {
        System.Drawing.Image newImage;
        string strFileName = Server.MapPath("~/Temp/") + "UploadedImage.jpg";
        if (byteArrayIn != null)
        {
            using (MemoryStream stream = new MemoryStream(byteArrayIn))
            {
                newImage = System.Drawing.Image.FromStream(stream);
                newImage.Save(strFileName);
            }
            return strFileName;
        }
        else
        {
            return "";
        }
    }

    protected void btn_submit_Click(object sender, EventArgs e)
    {
        DrinkMenuBLL.uploadImg(bytes);
        lbl_msg.Text = "uploaded";
    }

I used varbinary(MAX) in the database and the sql that i used

public static void UploadImg(byte[] drinkImage)
    {

        SqlConnection con = new SqlConnection(Constring.getConString());

        string sql = "Update DrinkMenu set drinkImage = (@imgData) where drinkID = 4";

        SqlCommand cmd = new SqlCommand(sql, con);
        cmd.Parameters.Add("@imgData", SqlDbType.Binary).Value = drinkImage;
        try
        {
            con.Open();
            cmd.ExecuteNonQuery();
        }
        finally
        {
            con.Close();
            cmd.Dispose();
            con.Dispose();
        }
    }
sihao
  • 273
  • 2
  • 5
  • 19
  • 4
    Are you sure your `byte[]` represents the image correctly? Can we see the code that stores it? – bluevector Jan 16 '13 at 14:09
  • 1
    bytes = imgBinary.ReadBytes((Int32)imgStream.Length); This is not a good way to read a file. Jon Skeet has a good answer here: http://stackoverflow.com/questions/221925/creating-a-byte-array-from-a-stream (he used to have an excellent blog post discussing various methods, but I can't find it). – Pete Jan 16 '13 at 14:21

1 Answers1

1

One problem could be the following one:

bytes = imgBinary.ReadBytes((Int32)imgStream.Length);

What if the stream Length is more than Int32.MaxValue as it's a Int64? Maybe you are truncating your image... use this method instead to read the stream to a buffer:

public static Byte[] ReadStream(Stream input)
{
    Byte[] buffer = new Byte[(16 * 1024)];

    using (MemoryStream stream = new MemoryStream())
    {
        Int32 read;

        while ((read = input.Read(buffer, 0, buffer.Length)) > 0)
            stream.Write(buffer, 0, read);

        return stream.ToArray();
    }
}

protected void bn_upload_Click(object sender, EventArgs e)
{
    lbl_msg.Text = "";

    Byte[] bytes = ReadStream(FileUpload1.PostedFile.InputStream);
    String src = byteArrayToImage(bytes);

    if (!src.Equals(""))
        Image1.ImageUrl = "~/Temp/UploadedImage.jpg";
}
Tommaso Belluzzo
  • 23,232
  • 8
  • 74
  • 98
  • sry but i dun quite get it.. how should i use it? – sihao Jan 16 '13 at 14:24
  • does the upload code have problem? it's not with the display part with the memory stream? that is mention above it? – sihao Jan 16 '13 at 14:29
  • See my comment to the original question. – Pete Jan 16 '13 at 14:31
  • Next time I'll use something different in you prefer D: Anyway, this is how a Stream should be correctly read :S – Tommaso Belluzzo Jan 16 '13 at 14:33
  • For the upload portion I have a `img1` and it does show the picture that I am going to upload. The problem is with after storing in database where i am taking from the database the bytes and convert it back to image – sihao Jan 16 '13 at 14:34
  • I agree. I just thought it was funny that I posted the link and at almost the same moment, you posted the code from the link... But the link also explains why his method will fail (because Stream.Read won't necessarily return as much as you ask for, and particularly, network streams that will return a packet at a time). – Pete Jan 16 '13 at 14:36
  • This is what i get after changing the codes. `System.Data.SqlClient.SqlException: The parameterized query '(@imgData binary(8000))Update DrinkMenu set drinkImage = (@imgDa' expects the parameter '@imgData', which was not supplied.` – sihao Jan 16 '13 at 14:39
  • Have you tried debugging byte data to see if everything is correct now for what concerns Stream reading? Have you checked the content of Byte[] in SQL upload function? Seems something is going wrong in between... – Tommaso Belluzzo Jan 16 '13 at 14:46
  • SqlCommand command = .... command.Text="INSERT INTO YOUR_TABLE_NAME (image) values (@image)"; command.Parameters.AddWithValue("@imgData", drinkImage); command.ExecuteNonQuery(); – Tommaso Belluzzo Jan 16 '13 at 14:49
  • Im updating the database which currently do not have the image value in the first place – sihao Jan 16 '13 at 14:56