I have the following two functions to convert bytes to image and display on Image in WPF
private JpegBitmapDecoder ConvertBytestoImageStream(byte[] imageData)
{
Stream imageStreamSource = new MemoryStream(imageData);
JpegBitmapDecoder decoder = new JpegBitmapDecoder(imageStreamSource, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.Default);
BitmapSource bitmapSource = decoder.Frames[0];
return decoder;
}
The above code does not work at all. I always get the exception that “No imaging component found” Image is not displayed.
private MemoryStream ConvertBytestoImageStream(int CameraId, byte[] ImageData, int imgWidth, int imgHeight, DateTime detectTime)
{
GCHandle gch = GCHandle.Alloc(ImageData, GCHandleType.Pinned);
int stride = 4 * ((24 * imgWidth + 31) / 32);
Bitmap bmp = new Bitmap(imgWidth, imgHeight, stride, PixelFormat.Format24bppRgb, gch.AddrOfPinnedObject());
MemoryStream ms = new MemoryStream();
bmp.Save(ms, ImageFormat.Jpeg);
gch.Free();
return ms;
}
This function works, but is very slow. I wish to optimize my code.
Your
ConvertBytestoImageStreamworks fine for me if i pass it a JPEG buffer. There are however a few things that could be improved. Depending on whether you really want to return a decoder or a bitmap, the method could be written this way:or this way:
Note that instead of using JpegBitmapDecoder this code utilizes a static factory method of the abstract base class BitmapDecoder which automatically selects the proper decoder for the provided data stream. Hence this code can be used for all image formats supported by WPF.
Note also that the Stream object is used inside a using block which takes care of disposing it when it is no longer needed. BitmapCacheOption.OnLoad ensures that the whole stream is loaded into the decoder and can be closed afterwards.