Change System.Windows.Controls.Image to MemoryStream? - silverlight

I have a problem in silverlight which I need to convert this image(from database probably will be in bytes) and convert it to MemoryStream. I need to do this so I can use it to export images to PDF files. Any Ideas?
Image myImage = new Image();
myImage.Source = new BitmapImage(new Uri("Resources/cancel.jpg", UriKind.RelativeOrAbsolute));
For starters, I am trying to convert an Image object to a memory stream object in a sample project(that's why UriSource is coded). Because I'm not familiar with creating dummy data in bytes. Any help on this one? Can I convert an Image to MemoryStream? if not, I believe bytes can be converted to stream, how can I do dummy data?
Thanks for all the replies.

You just need to pass byte[] to MemoryStream constructor
byte[] bytes = GetBytes();
MemoryStream ms = new MemoryStream(bytes);
Hope this helps

Related

WPF what is the best way to cache an image data

I have an application where I get lot of images in the form of byte[],
I store them in the memory for later use by the user demand
Should I store them in byte[]? or there is another way to store them for quicker loading on user demand?
My code that loads the image is like this
private static BitmapImage LoadImage(byte[] imageData)
{
if (imageData == null || imageData.Length == 0) return null;
var image = new BitmapImage();
using (var mem = new MemoryStream(imageData))
{
image.BeginInit();
image.CacheOption = BitmapCacheOption.OnLoad;
image.StreamSource = mem;
image.EndInit();
}
image.Freeze();
return image;
}
Thank you!
Ron
Could store the images in a Dictionary.
The key is the unique identifier (E.G. Int32).
The image could be stored as byte[] or BitmapImage
If you store it as BitmapImage you have to convert the byte[] up front
But then you don't need to convert on demand
Dictionary<Int32, byte[]>
or
Dictionary<Int32, BitmapImage>
Pretty sure BitmapImage is going to be bigger so converting on demand would use less memory.
Your question said a lot of images but you also asked for quicker user loading.
Test both ways.

Create a FrameworkElement out of an BitmapImage file, and then destroy?

I have a WPF project, which we using some WindowsForm control(PivotTable from OWC, Office Web Component). However, since the PivotTable doesn't support print very well, the only way we can think of is to print the image file PivotTable exports(another way is to print from exported Excel file, but we want to avoid it since it is not guaranteed that Excel is installed on the machine).
We already have one print project, which will print WPF ElementFramework nicely. So I want to use that piece of code. Now my question is: how I can generate a FrameworkElement out of a BitmapImage from code. Since this FrameworkElement is purely for printing, so I guess I must create it from the code, probably assign a parent to it, not show it on the screen, and after the printing destroy the FrameworkElement so that ultimately I can delete the temp BitmapImage file.
So this is beyond my knowledge. I don't even know whether that's a proper way: create a UI element for some non-UI related work? Any advice on that? Thanks!
You should load the temp image file's bytes into memory and create a Image from those bytes.
Your Image will not use the temp file directly and you can delete it immediately after reading the bytes, the rest is GarbageCollector's job. Here is a function to create your BitmapImage from bytes:
public static BitmapImage GetImageFromByteArray(byte[] rawImageBytes)
{
BitmapImage imageSource = null;
try
{
using (MemoryStream stream = new MemoryStream(rawImageBytes))
{
stream.Seek(0, SeekOrigin.Begin);
BitmapImage bi = new BitmapImage();
bi.BeginInit();
bi.CacheOption = BitmapCacheOption.OnLoad;
bi.StreamSource = stream;
bi.EndInit();
imageSource = bi;
}
}
catch (System.Exception)
{
}
return imageSource;
}
And use it like this:
testImage.Source = GetImageFromByteArray(rawImageBytes);

Converting a BitmapSource to Image keeping all frames

I have a method here that is supposed to produce a System.Drawing.Image instance. Consider the following prerequesites:
I get a BitmapSource as a method parameter
Below you find the code that does
the transformation from BitmapSource to Image.
Conversion:
public Image ConvertBitmapSourceToImage(BitmapSource input)
{
MemoryStream transportStream = new MemoryStream();
BitmapEncoder enc = new BmpBitmapEncoder();
enc.Frames.Add(BitmapFrame.Create(input));
enc.Save(transportStream);
transportStream.Seek(0, SeekOrigin.Begin);
return Image.FromStream(transportStream);
}
Now imagine the BitmapSource has been created from a Multipage Tif file. What I need to do is make any nth page available in code. The BitmapSource class offers no support for this, so do you know a way how the get any one but the first frame out of my input? Or does BitmapSource read in the whole Tif as one frame, losing the framing information?
If it were possible, I could add another parameter to my method signature, like so:
public Image ConvertBitmapSourceToImage(BitmapSource input, int frame)
{
///[..]
}
Any Ideas?
Thanks in advance!
As you've said already, a BitmapSource does not support multiple frames. Perhaps it would be an option to step in at the point where the TIFF is decoded and convert an Image from every frame:
TiffBitmapDecoder decoder = new TiffBitmapDecoder(...) // use stream or uri here
System.Drawing.Image[] images = new System.Drawing.Image[decoder.Frames.Count];
for (int i = 0; i < decoder.Frames.Count; i++)
{
// use your converter function here
images[i] = ConvertBitmapSourceToImage(decoder.Frames[i]));
}
I didn't test the above code, so sorry for any flaws.

Get image from resource dll as MemoryStream

I use WPF and my program has images in a DLL resource file. I have this well working way to read in images from disk:
Private Function GetImageFromFile(ByVal fileName As String) As BitmapImage
Dim buffer As Byte() = IO.File.ReadAllBytes(fileName)
Dim memoryStream As New IO.MemoryStream(buffer)
Dim bitmap As New BitmapImage()
bitmap.BeginInit()
bitmap.StreamSource = memoryStream
bitmap.EndInit()
bitmap.Freeze()
Return bitmap
End Function
Now, how can I get images in this MemoryStream-way from a DLL resource?
The basic problem: If I use simply the "bitmap.UriSource = whatever uri" way and load many images in sequence like an animation it builds up the memory. I tried with the above memorystream way and it worked perfectly fine, but then I store my images in a dll and I don't know how to do this trick. If anybody knows how to read many images from a managed dll without building up the memory pls, let me know.
I found the answer to my question. I put it here for others who may need it. There are more ways to load images from a resource dll file. The easiest way to initialize the BitmapImage and set bi.UriSource=uriPath (where the path looks like I show below) but when you load images in a sequence, as an animation for example, it seems to take a lot of memory. Then you can use a StreamResourceInfo as shown below and just put like bi.StreamSource = sri.Stream. That works, too, but memorywise it has same results. So in practice I found the following way the fastest and most memory efficient way to load hundreds of images in a sequence:
Public Function GetImageFromDLL(ByVal uriPath As String) As BitmapImage
Dim sri As Windows.Resources.StreamResourceInfo = Application.GetResourceStream(New Uri(uriPath, UriKind.Absolute))
Dim binReader As New System.IO.BinaryReader(sri.Stream)
Dim buffer As Byte() = binReader.ReadBytes(sri.Stream.Length)
Dim memoryStream As New IO.MemoryStream(buffer)
Dim bi As New BitmapImage()
bi.BeginInit()
bi.CacheOption = BitmapCacheOption.Default
bi.CreateOptions = BitmapCreateOptions.None
bi.StreamSource = memoryStream
bi.EndInit()
bi.Freeze()
Return bi
End Function
Where the uriPath is something like: "pack://application:,,,/YourDLL;Component/YourImageFile.jpg"

Is there a way to display a image in WPF stored in memory?

What I got is something like a screenshot making application. (managed to serialize, thank god!!!) When a button is clicked a screenshot is taken by accessing a handling classe's method. now the tricky part is that the class has another method for operating with the above said result, in such a manner than when the respective handling method is called, a window is created(shown) and the bitmap image should go into a display container in that window. The problem is that so far, I've noticed that in WPF the image control's source cannot be attribuited to a variable which stores the image. How can i display the image stored in that variable without having to save it first,get uri,etc. ?
You need to create an image from a memory stream, this has been well documented by many people. Here are two links that may get you started:
http://forums.silverlight.net/forums/p/44637/166282.aspx
http://www.wpftutorial.net/Images.html
thanks for the links slugster. Here's how I did it:
MemoryStream ms = new MemoryStream();
sBmp = gBmp; //note: gBmp is a variable that stores the captured image and passes it on to the method that uses sBMP as a distribuitor of the variable holding the captured image data
//variable that holds image
sBmp.Save(ms,ImageFormat.Bmp);
//my buffer byte
byte[] buffer = ms.GetBuffer();
//Create new MemoryStream that has the contents of buffer
MemoryStream bufferPasser = new MemoryStream(buffer);
//Creates a window with parents classthatholdsthismethod and null
Edit childEdit = new Edit(this, null);
childEdit.Show();
//I create a new BitmapImage to work with
BitmapImage bitmap = new BitmapImage();
bitmap.BeginInit();
bitmap.StreamSource = bufferPasser;
bitmap.EndInit();
//I set the source of the image control type as the new BitmapImage created earlier.
childEdit.imgImageCanvas.Source = bitmap;
childEdit.Activate();
I've basically combined what I had found on those pages with some info I found on how to pass on a bmp to a memstream. I got this to work 100% :)

Resources