I'm in a scenario where I'm manipulating bitmaps using AForge.net in Unity. However, a Bitmap can't be applied to a texture in Unity, so I visibly can see my output, so how is this done?
I believe I have to use the MemoryStream, but in what fashion is unknown to me.
I managed to achieve this by using a memorystream, i.e.:
MemoryStream msFinger = new MemoryStream();
bitmapCurrentframeRed.Save(msFinger, bitmapCurrentframeRed.RawFormat);
redCamera.LoadImage(msFinger.ToArray());
redFilter.GetComponent<Renderer>().material.mainTexture = redCamera;
With bitmapCurrentframeRed being a Bitmap,
redCamera being a texture2D and redFilter being a GameObject(plane) used to view my output.
you can try these line to convert System.Drawing.Bitmap to UnityEngine.Texture2D
Bitmap bmp = new Bitmap;
MemoryStream ms= new MemoryStream();
bmp.Save(ms,ImageFormat.PNG);
var buffer = new byte[ms.Length];
ms.position = 0;
ms.Read(buffer,0,buffer.Length);
Texture2D t = new Texture2D(1,1);
t.LoadImage(buffer);
Related
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());
}
Is it possible to get something drawn with default .net paint methods (System.Drawing methods) to a SharpDX Texture2D object so that i can display it as a texture?
Preferably with the SharpDX Toolkit.
If yes, how?
edit: what i am trying so far:
Bitmap b = new Bitmap(100,100);
MemoryStream ms = new MemoryStream();
b.Save(ms, System.Drawing.Imaging.ImageFormat.Png);
Texture2D tex = Texture2D.Load(g.device, ms); // crashing here
ms.Close();
b.Save(ms, System.Drawing.Imaging.ImageFormat.Png);
Texture2D tex = Texture2D.Load(g.device, ms);
The Save() call leaves the memory stream positioned at the end of the stream. Which will confuzzle the Load() method, it can't read any data from the stream. You'll have to rewind the stream explicitly. Insert this statement between the two lines of code:
ms.Position = 0;
XNA.Texture2D to System.Drawing.Bitmap I am sure this answered my question but it linked an external site and is no longer available.
I am using a windows form in an xna game. I want to use a background image for one of my panels. It is easy enough to do the loading from file, but when the game is deployed to another system obviously the file location will be different.
Bitmap bmp = new Bitmap(#"c:\myImage.png");
In the above mentioned question, someone had suggested usign Texture2d.saveToPng then open the bitmap from the memory stream. This sounds great, if someone could steer me in that direction. Any other ideas?
This works for me. If there are problems with it please let me know.
public static Image Texture2Image(Texture2D texture)
{
Image img;
using (MemoryStream MS = new MemoryStream())
{
texture.SaveAsPng(MS, texture.Width, texture.Height);
//Go To the beginning of the stream.
MS.Seek(0, SeekOrigin.Begin);
//Create the image based on the stream.
img = Bitmap.FromStream(MS);
}
return img;
}
You can use two methods that allow you to create a Bitmap, use Texture2D.SaveAsJpeg() or Texture2D.SaveAsPng().
MemoryStream memoryStream = new MemoryStream();
Texture2D texture = Content.Load<Texture2D>( "Images\\test" );
texture.SaveAsJpeg( memoryStream, texture.Width, texture.Height ); //Or SaveAsPng( memoryStream, texture.Width, texture.Height )
System.Drawing.Bitmap bmp = new System.Drawing.Bitmap( memoryStream );
I'm having some difficulty saving a stream of bytes from an image (in this case, a jpg) to a System.IO.MemoryStream object. The goal is to save the System.Drawing.Image to a MemoryStream, and then use the MemoryStream to write the image to an array of bytes (I ultimately need to insert it into a database). However, inspecting the variable data after the MemoryStream is closed shows that all of the bytes are zero... I'm pretty stumped and not sure where I'm doing wrong...
using (Image image = Image.FromFile(filename))
{
byte[] data;
using (MemoryStream m = new MemoryStream())
{
image.Save(m, image.RawFormat);
data = new byte[m.Length];
m.Write(data, 0, data.Length);
}
// Inspecting data here shows the array to be filled with zeros...
}
Any insights will be much appreciated!
To load data from a stream into an array, you read, not write (and you would need to rewind). But, more simply in this case, ToArray():
using (MemoryStream m = new MemoryStream())
{
image.Save(m, image.RawFormat);
data = m.ToArray();
}
If the purpose is to save the image bytes to a database, you could simply do:
byte[] imgData = System.IO.File.ReadAllBytes(#"path/to/image.extension");
And then plug in your database logic to save the bytes.
I found for another reason this article some seconds ago, maybe you will find it useful:
http://www.codeproject.com/KB/recipes/ImageConverter.aspx
Basically I don't understand why you try to write an empty array over a memory stream that has an image. Is that your way to clean the image?
If that's not the case, read what you have written in your memorystream with ToArray method and assign it to your byte array
And that's all
Try this way, it works for me
MemoryStream ms = new MemoryStream();
Bitmap bmp = new Bitmap(panel1.Width, panel1.Height);
panel1.DrawToBitmap(bmp, panel1.Bounds);
bmp.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg);
byte[] Pic_arr = new byte[ms.Length];
ms.Position = 0;
ms.Read(Pic_arr, 0, Pic_arr.Length);
ms.Close();
Well instead of a Image control, I used a Panel Control.
I would like to create the Bitmap from BitmapSource Collection and Each source source should be one frame.
I wrote the following code
MemoryStream memStream = new MemoryStream();
BitmapEncoder enCoder = new GifBitmapEncoder();
foreach (BitmapSource source in BitmapSources)
enCoder.Frames.Add(BitmapFrame.Create(source));
enCoder.Save(memStream);
_Bitmap = new DrawingCtrl.Bitmap(memStream);
DrawingCtrl.ImageAnimator.Animate(_Bitmap, OnFrameChanged);
and
private void OnFrameChangedInMainThread()
{
DrawingCtrl.ImageAnimator.UpdateFrames(_Bitmap);
Source = GetBitmapSource(_Bitmap);
InvalidateVisual();
}
But it shows "Exception has been thrown by the target of an invocation.". Could anyone help me?
I don’t know about BitmapSources in WPF, but I notice an error in how you use MemoryStream, so maybe this is the issue:
enCoder.Save(memStream);
This will write the content to the memory stream and leave the stream pointer at the end.
_Bitmap = new DrawingCtrl.Bitmap(memStream);
This will then try to read the bitmap from the stream, starting at the end of the stream. Of course that can’t work. Try adding a seek in between:
enCoder.Save(memStream);
memStream.Seek(0, SeekOrigin.Begin);
_Bitmap = new DrawingCtrl.Bitmap(memStream);