I have this code (C#):
unsafe private Bitmap Test()
{
Bitmap test = null;
byte[] data = memRenderAll.CurrentData;
fixed (byte* m_pBuffer = _data)
{
using (System.IO.MemoryStream ms = new System.IO.MemoryStream())
{
Bitmap a = new Bitmap(720, 576, 2160, System.Drawing.Imaging.PixelFormat.Format24bppRgb, new IntPtr(m_pBuffer));
a.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg);
test =(Bitmap) Image.FromStream(ms);
a.Dispose();
}
}
return _test;
}
By saving the stream as this:
a.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg);
I get a 10:1 reduction is size.
Is there a way of avoiding this:
a.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg);
and specifying it somewhere/somehow in:
Bitmap a = new Bitmap(720, 576, 2160, System.Drawing.Imaging.PixelFormat.Format24bppRgb, new IntPtr(m_pBuffer));
as I would like to create the Bitmap only once.
thanks,
Andrew
I think its impossible todo in one code line using standard System.Drawing.
You use that constructor: http://msdn.microsoft.com/en-us/library/zy1a2d14(v=vs.110).aspx
Your code:
new Bitmap(720, 576, 2160, System.Drawing.Imaging.PixelFormat.Format24bppRgb, new IntPtr(m_pBuffer));
What does it mean? Bitmap read memory pointed by m_pBuffer using fixed width, height, stride and pixel format. You can't read it as jpeg, because jpeg - image zipping fomat. Look on it: http://en.wikipedia.org/wiki/JPEG#JPEG_codec_example . Jpeg codec need all your image for ziping, it can't zip parts and join them after.
Related
I write this code to read files from folder in directory(#"D:\\test\\ISIC_2020_Training_JPEG"), then convert each file to bitmap in c#
foreach (string img in Directory.EnumerateFiles(#"D:\\test\\ISIC_2020_Training_JPEG"))
Bitmap bmp = new Bitmap(img);
But there is an error that appears in the last line, which is:
Out of memory Exception
what is the problem in this code?
I suppose that you have all jpeg files on provided directory, you could load image file in memory stream and check if everything okay when you load image in memory stream.
foreach (string imgPath in Directory.GetFiles(#"D:\test\ISIC_2020_Training_JPEG"))
{
Bitmap bmp;
byte[] buff = System.IO.File.ReadAllBytes(imgPath);
using(System.IO.MemoryStream ms = new System.IO.MemoryStream(buff))
{
bmp = new Bitmap(ms);
}
}
Probably the best approach would be to stream the image files so if there's a large file it won't hog up too much memory. Then check if the file is in the correct format before trying to convert to a Bitmap, hopefully this helps:
Bitmap bitmap;
Image image;
foreach (string imgFile in Directory.EnumerateFiles(#"D:\test\ISIC_2020_Training_JPEG"))
{
using (Stream bmpStream = File.Open(imgFile, FileMode.Open))
{
image = Image.FromStream(bmpStream);
if (ImageFormat.Jpeg.Equals(image.RawFormat)) // Check it's the correct format
{
bitmap = new Bitmap(image);
}
}
}
I have the following code trying to compress a bitmap and use it for uploading.
Bitmap bitmap1 = BitmapFactory.DecodeByteArray(imageFileByte, 0, imageFileByte.Length);
byte[] compressedData = null;
using (var stream = new MemoryStream())
{
bitmap1.Compress(Bitmap.CompressFormat.Jpeg, 50, stream);
compressedData = stream.ToArray();
}
//load compressed bitmap from memory
using (var anotherStream = new MemoryStream(compressedData))
{
var compressedBitmap = BitmapFactory.DecodeStream(anotherStream);
}
When I debug, bitmap1 on line 1 shows 3021330 bytes, when come to the compressedData on line 6, it did shrink to 70128 bytes.
Now I want to convert again the compressedData to a bitmap again since it is a byte array but not a bitmap, when it comes to line 11, the compressedBitmap shows exactly same number of bytes with the bitmap1.
How can I actually use the bitmap that has already been compressed?
Is it possible to compress a bitmap and save the compressed one as a bitmap again?
Thanks for any comment.
I load a bitmap from a DataStream. I try to return the loaded bitmap from a method, and later use it as a source to clone a new bitmap. Unfortunately, the Clone() call results in an OutOfMemoryException. Through testing I realized that Clone() succeeds until the underlying data stream is disposed.
How can I create a bitmap that exists independent from the stream it was loaded from?
DxScreenCapture cap = new DxScreenCapture();
var surface = cap.CaptureScreen();
Bitmap png;
Rectangle rect;
PixelFormat fmt;
using (DataStream stream = Surface.ToStream(surface, ImageFileFormat.Bmp))
{
png = new Bitmap(stream);
fmt = png.PixelFormat;
rect = new Rectangle(911, 170, 32, 14);
// Works
Bitmap rgn1 = png.Clone(rect, fmt);
}
// Throws OutOfMemoryException
Bitmap rgn2 = png.Clone(rect, fmt);
Building on Hans' comment, I simply created a new bitmap from the original one.
Bitmap copy;
using (DataStream stream = Surface.ToStream(surface, ImageFileFormat.Bmp))
{
Bitmap orig = new Bitmap(stream);
copy = new Bitmap(orig);
}
// Able to use copy after stream is disposed
Is there any way for converting WriteableBitmap to Bitmap in C# ?
It's pretty straightforward, actually. Here's some code that should work. I haven't tested it and I'm writing it from the top of my head.
private System.Drawing.Bitmap BitmapFromWriteableBitmap(WriteableBitmap writeBmp)
{
System.Drawing.Bitmap bmp;
using (MemoryStream outStream = new MemoryStream())
{
BitmapEncoder enc = new BmpBitmapEncoder();
enc.Frames.Add(BitmapFrame.Create((BitmapSource)writeBmp));
enc.Save(outStream);
bmp = new System.Drawing.Bitmap(outStream);
}
return bmp;
}
The WriteableBitmap inherits from a BitmapSource, which can be saved directly to a stream. Then, you build a Bitmap from this stream.
I've a byte array which contains an image binary data in bitmap format. How do I display it using the PictureBox control in C#?
I went thru a couple of posts listed below but not sure if I need to convert the byte array into something else before sending it to a picturebox. I'd appreciate your help. Thanks!
How to put image in a picture box from Bitmap
Load Picturebox Image From Memory?
This function converts byte array into Bitmap which can be use to set the Image Property of the picturebox.
public static Bitmap ByteToImage(byte[] blob)
{
MemoryStream mStream = new MemoryStream();
byte[] pData = blob;
mStream.Write(pData, 0, Convert.ToInt32(pData.Length));
Bitmap bm = new Bitmap(mStream, false);
mStream.Dispose();
return bm;
}
Sample usage:
pictureBox.Image = ByteToImage(byteArr); // byteArr holds byte array value
byte[] imageSource = **byte array**;
Bitmap image;
using (MemoryStream stream = new MemoryStream(imageSource))
{
image = new Bitmap(stream);
}
pictureBox.Image = image;
using System.IO;
byte[] img = File.ReadAllBytes(openFileDialog1.FileName);
MemoryStream ms = new MemoryStream(img);
pictureBox1.Image = Image.FromStream(ms);
or you can access like this directly,
pictureBox1.Image = Image.FromFile(openFileDialog1.FileName);
You can also convert pictureBox image to byte array like this,
MemoryStream ms = new MemoryStream();
pictureBox1.Image.Save(ms,System.Drawing.Imaging.ImageFormat.Jpeg);
byte[] img = ms.ToArray();
The ImageConverter class in the System.Drawing namespace can do the conversion:
byte[] imageArray = **byte array**
ImageConverter converter = new ImageConverter();
pictureButton.Image = (Image)converter.ConvertFrom(imageArray);
If you want to use BinaryReader to convert then use like this,
FileStream fs = new FileStream(openFileDialog1.FileName, FileMode.Open, FileAccess.Read);
BinaryReader br = new BinaryReader(fs);
byte[] img = br.ReadBytes((int)fs.Length);
Try this for Converting Bitmap Images to array of bytes for jpeg pictures and png file types:
public byte[] UdfConvertPicToByte(Bitmap bitmapImages)
{
using (MemoryStream stream = new MemoryStream())
{
bitmapImages.Compress(Bitmap.CompressFormat.Png, 0, stream);
byte[] bitmapData = stream.ToArray();
bitmap.Compress(Bitmap.CompressFormat.Jpeg, 50, stream);
bitmapData = stream.ToArray();
return bitmapData;
}
}