Is there any way of converting Stream to Image?
I tried Bitmap, but it states that I don't have System.Drawing... so I tried this:
var bitMap = new BitmapImage();
bitMap.SetSourceAsync(stream);
image.Source = bitMap;
EDIT:
I am trying to build UWP app + using VS 2015.
2 - It just states that System.Drawing does not exist in the namespace.
EDIT2:
Ok, I might have explained it wrong. The idea is: I have an Image, and I want to change its source to something different and then for it to reload, so I can see the image.
The image is effectively a "Stream", so I assume I need to convert it to Bitmap and then load somehow.
EDIT3:
Ok, so I think it will be easier to describe and then use the code above:
There is a picture box and I am using:
var stream = new InMemoryRandomAccessStream();
await mediaCapture.CapturePhotoToStreamAsync(ImageEncodingProperties.CreateJpeg(), stream);
Now I would like this Captured Photo to be displayed as an Image. ( Image "box" is created at the start, so the idea is to change source).
Right, so I managed to fix it:
var bitMap = new BitmapImage();
stream.seek(0); // LINE ADDED
bitMap.SetSourceAsync(stream);
image.Source = bitMap;
I turned out that the error that was being produced was : "The component cannot be found.", so I managed to fix it by using this trick.
I am not sure if this is what you are looking for but if you would like to use stream with BitMapImage you should use:
var image = new BitmapImage();
await image.SetSourceAsync(stream);
For instance when you have your photo stored as a byte[] array you can use the stream to convert it to image:
using (InMemoryRandomAccessStream stream = new InMemoryRandomAccessStream())
{
DataWriter writer = new DataWriter(stream.GetOutputStreamAt(0))
writer.WriteBytes(<<here your byte[] array>>);
await writer.StoreAsync();
var image = new BitmapImage();
await image.SetSourceAsync(stream);
}
Is that what you need?
Related
I have a WPF project and captured an image from a usb camera to a System.Drawing.Bitmap (I also can capture System.Windows.Media.Imaging.BitmapSource) and need to convert it to a Windows.Graphics.Imaging.SoftwareBitmap to make a "VideoFrame" to compare to an Onnx model.
The camera driver is a .net assembly and will not bind to a uwp project. I've tried creating a .net standard assembly to bridge the gap with no success. I simply need a bitmap converted to a SoftwareBitmap. Please help!
I'm using this code for the basis of the compassion of the Bitmap image from the camera - https://github.com/Azure-Samples/cognitive-services-onnx12-customvision-sample
There is no direct conversion. You'll need to extract the image data from the System.Drawing.Bitmap and then create the new SoftwareBitmap from that data.
For example, you could use Save(Stream, ImageFormat) method to save this image to the specified stream in the specified format.
Then, you could try to call BitmapDecoder.CreateAsync method to create the decoder from the stream.
After that you could call GetSoftwareBitmapAsync to get a SoftwareBitmap object.
The following is a simple code sample:
Bitmap bitmap = getyourbitmap();
using (var stream = new Windows.Storage.Streams.InMemoryRandomAccessStream())
{
bitmap.Save(stream.AsStream(),ImageFormat.Jpeg);//choose the specific image format by your own bitmap source
Windows.Graphics.Imaging.BitmapDecoder decoder = await Windows.Graphics.Imaging.BitmapDecoder.CreateAsync(stream);
SoftwareBitmap softwareBitmap = await decoder.GetSoftwareBitmapAsync();
}
I found that you can use Windows.Security.Cryptography to create a IBuffer from the image array bytes. Then you can copy the IBuffer to the SoftwareBitmap.
using Windows.Security.Cryptography;
IBuffer buffer = CryptographicBuffer.CreateFromByteArray(ImageByteArray);
SoftwareBitmap softwareBitmap = new SoftwareBitmap(BitmapPixelFormat.Gray8, 800, 600);
softwareBitmap.CopyFromBuffer(buffer);
VideoFrame inputImage = VideoFrame.CreateWithSoftwareBitmap(softwareBitmap);
This worked for me:
Bitmap bitmap = ...;
var memoryStream = new MemoryStream();
using (var graphics = Graphics.FromImage(bitmap))
{
bitmap.Save(memoryStream, ImageFormat.Bmp);
}
var decoder = await Windows.Graphics.Imaging.BitmapDecoder.CreateAsync(stream);
var bitmap = await decoder.GetSoftwareBitmapAsync();
I'm trying to get a SoftwareBitmap to be usable by stuff in WPF as a Bitmap.
Approaches like this question shows look promising, but they seem to be using objects from different namespaces that don't quite work in my case. For context, I'm using MediaCapture from UWP land for webcam streaming in my app which is WPF.
public static WriteableBitmap WriteableBitmapFromSoftwareBitmap(SoftwareBitmap soft)
{
WriteableBitmap writeable = new
WriteableBitmap(soft.PixelWidth, soft.PixelHeight);
soft.CopyToBuffer(writeable.PixelBuffer);
return writeable;
}
public static Bitmap BitmapFromWriteableBitmap(WriteableBitmap writeBmp)
{
Bitmap bmp;
using (MemoryStream outStream = new MemoryStream())
{
System.Windows.Media.Imaging.BitmapEncoder enc = new
BmpBitmapEncoder();
enc.Frames.Add(BitmapFrame.Create(writeBmp)); // Error here
enc.Save(outStream);
bmp = new Bitmap(outStream);
}
return bmp;
}
Unfortunately, in BitmapFromWriteableBitmap, the call to BitmapFrame.Create is complaining that it can't create a URI from that kind of WriteableBitmap.
Note that the WriteableBitmap is a Windows.UI.Xaml.Media.Imaging.WriteableBitmap,
the SoftwareBitmap is a Windows.Graphics.Imaging.SoftwareBitmap,
and the desired Bitmap is a System.Drawing.Bitmap.
There is no direct conversion. You'll need to extract the image data from the SoftwareBitmap and then create the new Bitmap from that data.
This is essentially what the linked question does: it encodes the data from the WriteableBitmap into a .BMP stream and then loads the System.Drawing.Bitmap from that stream.
You can do the same from the SoftwareBitmap by using Windows.Graphics.Imaging.BitmapEncoder.SetSoftwareBitmap to convert its contents to an image stream and then create a new System.Drawing.Bitmap from that stream.
See Save a SoftwareBitmap to a file with BitmapEncoder for sample code. You can render to an InMemoryRandomAccessStream instead of a StorageFile's stream to avoid saving to disk, and can use AsStream to convert it to a .Net System.IO.Stream to read into the System.Drawing.Bitmap something like the following (untested) snippet:
using (var stream = new Windows.Storage.Streams.InMemoryRandomAccessStream())
{
BitmapEncoder encoder = await BitmapEncoder.CreateAsync(BitmapEncoder.PngEncoderId, stream);
encoder.SetSoftwareBitmap(softwareBitmap);
await encoder.FlushAsync();
bmp = new System.Drawing.Bitmap(stream.AsStream());
}
I have written a little game using IronPython and WPF for didactic purpose and now I want to translate the project to Metro APP for test Shared Projects.
The guilty code is:
def LoadImage(name, sourceRect):
bmp = BitmapImage()
bmp.BeginInit()
bmp.UriSource = Uri("./data/images/" + name, UriKind.Relative)
bmp.SourceRect = sourceRect
bmp.EndInit()
image = Image()
image.Source = bmp
return image
How on the earth I can obtain the same result in a Metro app (using C#)? There must be a way to do this in a simple manner like old BitmapImage. I need this because I have tiled images and I want a portion of it to display. WriteableBitmap work but ignore transparency of the image, so it's useless.
I've been using this code to load an image scaled:
public static async Task SetSourceAsync(
this WriteableBitmap writeableBitmap,
IRandomAccessStream streamSource,
uint decodePixelWidth,
uint decodePixelHeight)
{
var decoder = await BitmapDecoder.CreateAsync(streamSource);
using (var inMemoryStream = new InMemoryRandomAccessStream())
{
var encoder = await BitmapEncoder.CreateForTranscodingAsync(inMemoryStream, decoder);
encoder.BitmapTransform.ScaledWidth = decodePixelWidth;
encoder.BitmapTransform.ScaledHeight = decodePixelHeight;
await encoder.FlushAsync();
inMemoryStream.Seek(0);
await writeableBitmap.SetSourceAsync(inMemoryStream);
}
}
You might use something similar, but you'd specify encoder.BitmapTransform.Bounds instead of ScaledWidth/Height to do the cropping. If you have more specific questions - please clarify.
I am trying to change an image for image1 during runtime. However the image turns blank(blank), what am I doing wrong?
ImageAsBytes is a Byte[] containing an image.
ScrollViewer1 is the where image1 is located.
using (MemoryStream ms = new MemoryStream(ImagesAsBytes, 0, ImagesAsBytes.Length))
{
BitmapImage image = new BitmapImage();
image.BeginInit();
image.StreamSource = ms;
image.EndInit();
}
image1.Source = image;
scrollViewer1.UpdateLayout();
I think your Image can't be displayed because the MemoryStream you are using is being disposed. Remove the surrounding using block and see if that helps. (you would need to dispose of the stream manually if you don't need it anymore then)
I have a byte[] that is represented by an Image. I am downloading this Image via a WebClient. When the WebClient has downloaded the picture and I reference it using its URL, I get a byte[]. My question is, how do I load a byte[] into an Image element in WPF? Thank you.
Note: This is complementary to the question I asked here: Generate Image at Runtime. I cannot seem to get that approach to work, so I am trying a different approach.
Create a BitmapImage from the MemoryStream as below:
MemoryStream byteStream = new MemoryStream(bytes);
BitmapImage image = new BitmapImage();
image.BeginInit();
image.StreamSource = byteStream;
image.EndInit();
And in XAML you can create an Image control and set the above image as the Source property.
You can use a BitmapImage, and sets its StreamSource to a stream containing the binary data. If you want to make a stream from a byte[], use a MemoryStream:
MemoryStream stream = new MemoryStream(bytes);
In .Net framework 4.0
using System.Drawing;
using System.Web;
private Image GetImageFile(HttpPostedFileBase postedFile)
{
if (postedFile == null) return null;
return Image.FromStream(postedFile.InputStream);
}
One way that I figured out how to do it so that it was both fast and thread safe was the following:
var imgBytes = value as byte[];
if (imgBytes == null)
return null;
using (var stream = new MemoryStream(imgBytes))
return BitmapFrame.Create(stream,BitmapCreateOptions.None, BitmapCacheOption.OnLoad);
I threw that into a converter for my WPF application after running the images as Varbinary from the DB.