How to show Image from byte array in Microsoft report
Asked Answered
D

2

10

I am using a Report file and a ReportViewer control to show a report which loads data dynamically from objects during run-time.

I need to show an image which is stored as a byte array in the object.

The PictureBox's value is currently set to:

=First(Fields!ImageData.Value, "dtstItemImage")

And I set the DataSource using:

ImageBindingSource.DataSource = this.item.Image.ImageData;

The code compiles and runs but the image is not displayed in the report.

Is this because the PictureBox needs to be bound to an Image object (and not to a byte array)? Or are there perhaps some properties of the PictureBox which I need to set?

UPDATE 1

I've added a border to the PictureBox just to make sure that's its visible and it does show up in the report. It just doesn't contain the image.

UPDATE 2

I've fixed a mistake in my code. I've changed:

ImageBindingSource.DataSource = this.item.Image.ImageData;

to:

ImageBindingSource.DataSource = this.item.Image;

as the PictureBox is bound to the ImageData field BUT the DataSource is the Image object.

Now I get a small cross icon instead of nothing which (at least for me) indicates some progress but I don't know where the byte[]-bitmap conversion code needs to be.

Deirdra answered 7/9, 2012 at 13:28 Comment(12)
How is the image formatted? You probably need to deserialize a byte stream: #1157108Inwrought
What do you mean by "formatted"? The image in the byte array is taken from a database BLOB cell and is a JPEG.Deirdra
@Rachel, MrFox (and myself below) are referring to how was the image encoded into a byte array. You may need to pad the bytes out to align with boundaries. See how I did it in this Q&A #2750842Congius
@Congius The image was input into an SQLite DB using Linq, but I'm sure the format of the image is correct since I'm showing it in a PictureBox in the WinForms application itself - it's only in the report that I cannot see it.Deirdra
Stupid pedantic quibble: "without any problems" isn't true, because "image is not displayed in the report" is a problem.Clea
@Clea You're right - I was referring to the code not throwing any run-time errors. I've removed the phrase for what it's worth. Still have no clue what the actual problem is though.Deirdra
@Rachel: Now that I know that it "works" in WinForms it made me realise a mistake in my answer. See update.Congius
What is item.Image? Need more information before any more help can be given. It sounds like the problem is now becoming localized to your particular code-base.Congius
item.Image is a custom object which contains the byte[] in the ImageData field (i.e. the byte array is stored in Item.Image.ImageData). The Image object here is NOT of type System.Drawing.Image.Deirdra
I'm not sure I got it right: are you reading a BLOB field from a SQLite database in an object, and trying to display the data stored in this object in a SQL Server Reporting Services report ? If so, which version of Reporting Services ? If it's 2008, it has a wizard to configure a databound image control which fetches directly from database (not sure if it works on other than SQL Server).Daigle
@Daigle I'm reading a BLOB from an SQLite DB into an object, and trying to display the image using Microsoft Reporting in VS20120.Deirdra
@Daigle The problem seems to be that binding a PictureBox to a byte[] is not enough to display the image.Deirdra
D
6

I managed to solve this by setting the report's Image box Source property to Database (it was previously set to External).

More info about the different available Source values can be found at (MSDN) HowTo: Add an Image (Reporting Services).

Deirdra answered 10/9, 2012 at 6:27 Comment(0)
C
1

You need to create an image object from the byte array and use that as the source.

To do this, you can use a helper function like the following

public static Image LoadImage(byte[] imageBytes)
{
     Image image = null;
     using (var ms = new MemoryStream(imageBytes))
         image = Image.FromStream(ms);

     return image;
}

Edit

For WPF, you need to use BitmapSource (MSDN) instead of Image (MSDN)

public static BitmapSource LoadImage(Byte[] imageBytes)
{
    var image = new BitmapImage();
    using (var ms = new MemoryStream(binaryData))
    {
        image.BeginInit();
        image.StreamSource = ms;
        image.CacheOption = BitmapCacheOption.OnLoad;
        image.EndInit();
    }

    if (image.CanFreeze)
        image.Freeze();

    return image;
}

NB: You can could also do this using a IValueConverter, see this blog post for the source code.


and then modify your data binding

ImageBindingSource.DataSource = LoadImage(item.Image.ImageData);

...

Make sure that the image (and MemoryStream) is disposed properly when you finished with it, as otherwise you will leak memory.

Also, depending on the format of your byte array you may need to do some work. See one of my question/answers for some helpful information.

Congius answered 7/9, 2012 at 13:36 Comment(5)
I've tried that and it doesn't work either. It's as if the PictureBox isn't even in the report.Deirdra
also U should dispose memory stream. Image returnImage; using(MemoryStream ms = new MemoryStream(bytes)){returnImage = Image.FromStream(ms);}return returnImage;Merari
Still didn't work. I had to use image.StreamSource = ms because .SetSource method was not found. Could this be the problem?Deirdra
I had not actually tested anything I've written in this answer, just pulled together information from documentation and other sources. I've updated the answer again to use StreamSource method as it was done in the IValueConverter sample that I linked to. I hope that it now works. :)Congius
@Congius Kindly see the latest update. My problem now is that I don't know where the byte-image conversion code should be placed.. The PictureBox is bounnd to the byte[] ImageData field.Deirdra

© 2022 - 2024 — McMap. All rights reserved.