How to convert PNG to BMP at runtime? - c#

I need to convert PNG file to BMP file on runtime.
I can't do it like
Image dummy = Image.FromFile("image.png");
dummy.Save("image.bmp", ImageFormat.Bmp);
because i can't save the bmp image on the local disk as a file.
Thanks for any help.

You can save to stream
using(MemoryStream stream = new MemoryStream())
{
Dummy.Save(stream, ImageFormat.Bmp);
}

Precise answer given here.
Image Dummy = Image.FromFile("image.png");
Dummy.Save("image.bmp", ImageFormat.Bmp);
Since you don't want to follow this method, you can do it the way Stecya answered.
Just do it this way.
Stream stream;
Dummy.save(stream, ImageFormat.Bmp)

Related

How to compress bitmap to smaller size in C#?

My bitmap is too large for uploading to the printer. I am going to compress it to smaller size so that less data will be transmit over the printer. But I don't want reduce the length and width of the bitmap. I have done some research but all of them require a stream especially as following
bitmap.compress(Bitmap.Format.jpeg,50,outputStream);
Why do I need a stream to store the file? How can I skip that and get the compressed bitmap that I want? I have tried
originalBitmap = Bitmap.decodeByteArray(imageByteData);
//Line below not working and got error
compressedBitmap = Bitmap.compress(Bitmap.Format.jpeg,50,outputStream);
In the outputStream which is my Download folder, I did see the compressed image, but how can I access the compressed image again? Unfortunately, the compress method is not that straight forward. My question is how can I compress a bitmap and use the compressed bitmap in another action? Thank you.
You can compress it to an in-memory stream:
//Compress to a stream in memory
byte[] compressedData = null;
using(var stream = new MemoryStream())
{
bitmap.Compress(Bitmap.Format.Jpeg, 50, stream);
compressedData = stream.ToArray();
}
//load compressed bitmap from memory
using(var stream = new MemoryStream(compressedData))
{
var compressedBitmap = BitmapFactory.DecodeStream(stream);
}

Saving bitmap from clipboard into png in wpf application

i needed to send bitmap into my chat application soo my idea was save it into a temporaty folder and from there upload it like my drag and drop image thats already working. but when it saves the bitmap in windows fileviewer i can see thumbnail but everywhere else its empty any idea where the problem could be or how to do this any better way? thanks in advance.
here is a video so you can better understand ^^ https://youtu.be/p0t2byTRN58
string temp = Directory.GetParent(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData)).FullName + #"\Luxray\" + #"\clipboardimg.png";
if (File.Exists(temp))
{
File.Delete(temp);
}
BitmapSource bmpSource = Clipboard.GetImage();
MemoryStream ms = new MemoryStream();
FileStream stream = new FileStream(temp, FileMode.Create);
BitmapEncoder encoder = new PngBitmapEncoder();
encoder.Frames.Add(BitmapFrame.Create(bmpSource));
encoder.Save(stream);
stream.Close();
this code runs right after if statment that checks if clipboard has bitmap inside and ctrl+v was pressed in the video it is after msgbox with "img sent" pops up.
What are you trying to achieve? if you're trying to save a clipboard image to file the below code works for me:
var img = System.Windows.Forms.Clipboard.GetImage();
img.Save(savePath, ImageFormat.Png);

System.Drawing.Image.RotateFlip(RotateFlipType)

I have the following code to rotate an image in C#:
using (var stream = new FileStream(path, FileMode.Open))
{
using (var image = Image.FromStream(stream))
{
stream.Close();
image.RotateFlip(rotateType);
image.Save(path1, ImageFormat.Png);
image.Dispose();
}
}
If the original file size was 700 KiB, the new rotated file has size of 7+ MiB.
What is wrong with this code? Any help is much appreciated.
Update:
I tried changing the line image.Save(path1, ImageFormat.Png) to image.Save(path1) and image.Save(path1, image.RawFormt) with no improvement.
C# - How to change PNG quality or color depth
This guy's question looks similar to the same thing you are seeing.
PNG is a bitmap file format:
higher filesize compared to jpg
Because of this you should safe your image as jpg:
Thus lossless PNG format is best suited for pictures still under edition - and the lossy formats, like JPEG, are best for the final distribution of photographic images, because in this case JPG files are usually smaller [...]
Source: wikipedia
Try safing the image in JPEG via:
image.Save(path, YourClass.GetImageFormat(image));
Tests:
Rotating an JPG file with this method and the size stays the same.
Rotating a 15.7MiB BMP file, the new size is ~800kiB.
To use the existing file format, use this extension method:
public static System.Drawing.Imaging.ImageFormat GetImageFormat(System.Drawing.Image img)
{
if (img.RawFormat.Equals(System.Drawing.Imaging.ImageFormat.Jpeg))
return System.Drawing.Imaging.ImageFormat.Jpeg;
if (img.RawFormat.Equals(System.Drawing.Imaging.ImageFormat.Bmp))
return System.Drawing.Imaging.ImageFormat.Bmp;
if (img.RawFormat.Equals(System.Drawing.Imaging.ImageFormat.Png))
return System.Drawing.Imaging.ImageFormat.Png;
if (img.RawFormat.Equals(System.Drawing.Imaging.ImageFormat.Emf))
return System.Drawing.Imaging.ImageFormat.Emf;
if (img.RawFormat.Equals(System.Drawing.Imaging.ImageFormat.Exif))
return System.Drawing.Imaging.ImageFormat.Exif;
if (img.RawFormat.Equals(System.Drawing.Imaging.ImageFormat.Gif))
return System.Drawing.Imaging.ImageFormat.Gif;
if (img.RawFormat.Equals(System.Drawing.Imaging.ImageFormat.Icon))
return System.Drawing.Imaging.ImageFormat.Icon;
if (img.RawFormat.Equals(System.Drawing.Imaging.ImageFormat.MemoryBmp))
return System.Drawing.Imaging.ImageFormat.MemoryBmp;
if (img.RawFormat.Equals(System.Drawing.Imaging.ImageFormat.Tiff))
return System.Drawing.Imaging.ImageFormat.Tiff;
else
return System.Drawing.Imaging.ImageFormat.Wmf;
}
Source: StackOverflow
Remember you have to look for the format before you manipulate the image.
Otherwise the image will be recognised as MemoryBmp.
using (var stream = new FileStream(path, FileMode.Open))
{
using (var image = Image.FromStream(stream))
{
stream.Close();
var format = YourClass.GetImageFormat(image);
image.RotateFlip(RotateFlipType.Rotate180FlipNone);
image.Save(path, format);
image.Dispose();
}
}

I want to use a Texture2d as a system.drawing.bitmap

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 );

C#: Getting Error: "A generic error occurred in GDI+" When trying to copy imagebox.Image into memory stream. This stream is not being saved to file.

I am getting an odd error with Image.save(Stream, Format).
I tried looking around on here for a solution but everyone seems to think the error is from file permissions. That can't be it in my case case the Stream isn't going into a file. My code is below:
MemoryStream Stream = new MemoryStream();
this.Image_Box_1.Image.Save(Stream, System.Drawing.Imaging.ImageFormat.Jpeg);
TI.AlbumCover = Stream.ToArray();
Stream.Close();
TI.AlbumCover is a byte[].
Does anyone have any ideas on what the problem might be?
EDIT:
Ok, so I worked it out. The original file could sometimes come from a jpg file, sometimes from a byte array (part of an id3 tag). The problem was that when the image came from the file, I was closing the stream after creating the image box image. While the image remained visible, the data was no longer available.
Since I also later needed to overwrite that jpg file, I could not simply leave the filestream for it open so I left the rest of my code the same and changed the code to read from the jpg to the following:
FileStream FS = new FileStream(File, FileMode.Open, FileAccess.Read);//Read in the jpg file
Image IMG = Image.FromStream(FS);//Create an image from the file data
MemoryStream MS = new MemoryStream();
IMG.Save(MS, System.Drawing.Imaging.ImageFormat.Jpeg);//Save the image data to a memory stream
byte[] temp = MS.ToArray();//Copy the image data to a byte array
//close the streams
MS.Close();
FS.Close();
return temp; //was originally returning an image
Then after executing this code I change the code that placed the image into the image box to:
try
{
if (this.m_V2Tag.AlbumCover != null)
this.Image_Box_1.Image = Image.FromStream(new MemoryStream(this.m_V2Tag.AlbumCover));
//changed code
else
{
MemoryStream temp = new MemoryStream(this.getFolderJpg()); //create a memory stream from the byte[]. This stream can safely be left open.
this.Image_Box_1.Image = Image.FromStream(temp); // create image and assign it to the image box
}
}
catch
{
this.Image_Box_1.Image = null;
}

Categories

Resources