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.
Related
I use the following codes to compress an image file to jpg:
// _rawBitmap = a Bitmap object
ImageCodecInfo encoder = GetEncoder(ImageFormat.Jpeg);
System.Drawing.Imaging.Encoder myEncoder = System.Drawing.Imaging.Encoder.Quality;
EncoderParameters myEncoderParameters = new EncoderParameters(1);
EncoderParameter myEncoderParameter = new EncoderParameter(myEncoder, 50L);
myEncoderParameters.Param[0] = myEncoderParameter;
ImageConverter imageConverter = new ImageConverter();
byte[] b = (byte[])imageConverter.ConvertTo(_rawBitmap, typeof(byte[]));
using (MemoryStream ms = new MemoryStream())
{
ms.Write(b, 0, b.Length);
ms.Seek(0, SeekOrigin.Begin);
rawBitmap.Save(ms, encoder, myEncoderParameters);
bmp = ToBitmap(ms.ToArray());
return (Bitmap)bmp.Clone();
}
but when I try to compress a png file with same way but only change:
ImageCodecInfo encoder = GetEncoder(ImageFormat.Jpeg);
to
ImageCodecInfo encoder = GetEncoder(ImageFormat.Png);
my png file lost transparent data.
so how to compress a PNG file properly?
There are a couple of problems here.
First, you don't need to set those EncoderParams for quality for PNG.
Second, you don't need ImageConverter
Third, you are writing whatever ImageConverter produces to your memory stream, rewinding, and then writing the encoded PNG over the top of it-- it is likely that you have a PNG file with a bunch of garbage at the end of it as a result.
The simplified approach should be:
using (MemoryStream ms = new MemoryStream())
{
rawBitmap.Save(ms, ImageFormat.Png);
}
If you want to load your bitmap back, open it from the stream, but don't close the stream (the stream will be disposed when your returned Bitmap is disposed):
var ms = new MemoryStream();
rawBitmap.Save(ms, ImageFormat.Png);
ms.Seek(0, SeekOrigin.Begin);
return Bitmap.FromStream(ms);
You can use nQuant (https://www.nuget.org/packages/nQuant/)
With it, you convert 32 bit PNGs to high quality 8 bit PNGs
private static int alphaTransparency = 10;
private static int alphaFader = 70;
var quantizer = new WuQuantizer();
using(var bitmap = new Bitmap(sourcePath))
{
using(var quantized = quantizer.QuantizeImage(bitmap, alphaTransparency, alphaFader))
{
quantized.Save(targetPath, ImageFormat.Png);
}
}
This question already has an answer here:
System.Drawing.Bitmap to JPEG XR
(1 answer)
Closed 8 years ago.
I want to write an application that takes an image(jpeg, png, tiff, gif,...) as stream and convert it to jrx(jpeg xr) with lossless compression.
Thats is what i have tried so far with no useable result:
using System.Windows.Media.Imaging;
//decode jpg
public static BitmapSource ReadJpeg(Stream imageStreamSource)
{
JpegBitmapDecoder decoder = new JpegBitmapDecoder(imageStreamSource, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.Default);
BitmapSource bitmapSource = decoder.Frames[0];
return bitmapSource;
}
//encode
public static Stream Encode(BitmapSource image)
{
WmpBitmapEncoder encoder = new WmpBitmapEncoder();
MemoryStream s = new MemoryStream();
encoder.Frames.Add(BitmapFrame.Create(image));
encoder.Save(s);
return s;
}
Can someone point me in the right direction? I am hanging here for some time now.
If you need more informations please ask.
System.Drawing.Bitmap to JPEG XR is working for the given input formats but doesnt fully cover my question because the part of decoding the image is missing.
Thank you all for pointing me in the right direction!
I do know now, how to proceed.
try this:
public static MemoryStream SaveJpegXr(this Bitmap bitmap, float quality)
{
var stream = new MemoryStream();
SaveJpegXr(bitmap, quality, stream);
stream.Seek(0, SeekOrigin.Begin);
return stream;
}
public static void SaveJpegXr(this Bitmap bitmap, float quality, Stream output)
{
var bitmapSource = bitmap.ToWpfBitmap();
var bitmapFrame = BitmapFrame.Create(bitmapSource);
var jpegXrEncoder = new WmpBitmapEncoder();
jpegXrEncoder.Frames.Add(bitmapFrame);
jpegXrEncoder.ImageQualityLevel = quality / 100f;
jpegXrEncoder.Save(output);
}
public static BitmapSource ToWpfBitmap(this Bitmap bitmap)
{
using (var stream = new MemoryStream())
{
bitmap.Save(stream, ImageFormat.Bmp);
stream.Position = 0;
var result = new BitmapImage();
result.BeginInit();
result.CacheOption = BitmapCacheOption.OnLoad;
result.StreamSource = stream;
result.EndInit();
result.Freeze();
return result;
}
}
My .png image is stored on a Uri object and it has the following format
"pack://application:,,,/AppName.Modules.App.Shared;component/Images/AppName_logo.png"
How do I load this image onto a System.Drawing.Bitmap object?
Assuming you are using WPF, you can first load the image as a BitmapImage and then convert it.
See this answer to "Converting BitmapImage to Bitmap and vice versa"
BitmapImage bi = new BitmapImage(
new Uri("pack://application:,,,/AppName.Modules.App.Shared;component/Images/AppName_logo.png"));
Bitmap b = BitmapImage2Bitmap(bi);
private Bitmap BitmapImage2Bitmap(BitmapImage bitmapImage)
{
using (MemoryStream outStream = new MemoryStream())
{
BitmapEncoder enc = new BmpBitmapEncoder();
enc.Frames.Add(BitmapFrame.Create(bitmapImage));
enc.Save(outStream);
System.Drawing.Bitmap bitmap = new System.Drawing.Bitmap(outStream);
return new Bitmap(bitmap);
}
}
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;
}
}
what is the easiest way to translate a Bitmap & Png to string AND BACK AGAIN. Ive been trying to do some saves through memory streams and such but i cant seem to get it to work!
Appearently i wasnt clear,
what i want, is to be able to translate a Bitmap class, with an image in it.. into a system string. from there i want to be able to throw my string around for a bit, and then translate it back into a Bitmap to be displayed in a PictureBox.
Based on #peters answer I've ended up using this:
string bitmapString = null;
using (MemoryStream memoryStream = new MemoryStream())
{
image.Save(memoryStream, ImageFormat.Png);
byte[] bitmapBytes = memoryStream.GetBuffer();
bitmapString = Convert.ToBase64String(bitmapBytes, Base64FormattingOptions.InsertLineBreaks);
}
and
Image img = null;
byte[] bitmapBytes = Convert.FromBase64String(pictureSourceString);
using (MemoryStream memoryStream = new MemoryStream(bitmapBytes))
{
img = Image.FromStream(memoryStream);
}
From bitmap to string:
MemoryStream memoryStream = new MemoryStream();
bitmap.Save (memoryStream, ImageFormat.Png);
byte[] bitmapBytes = memoryStream.GetBuffer();
string bitmapString = Convert.ToBase64String(bitmapBytes, Base64FormattingOptions.InsertLineBreaks);
From string to image:
byte[] bitmapBytes = Convert.FromBase64String(bitmapString);
MemoryStream memoryStream = new MemoryStream(bitmapBytes);
Image image = Image.FromStream(memoryStream);