I am trying to convert png image to gif and jpg format. I am using the code that I've found at Microsoft documentation.
I've created git-hub example by modifying this code into this:
public static void Main(string[] args)
{
// Load the image.
using (Image png = Image.FromFile("test-image.png"))
{
var withBackground = SetWhiteBackground(png);
// Save the image in JPEG format.
withBackground.Save("test-image.jpg");
// Save the image in GIF format.
withBackground.Save("test-image.gif");
withBackground.Dispose();
}
}
private static Image SetWhiteBackground(Image img)
{
Bitmap imgWithBackground = new Bitmap(img.Width, img.Height);
Rectangle rect = new Rectangle(Point.Empty, img.Size);
using (Graphics g = Graphics.FromImage(imgWithBackground))
{
g.Clear(Color.White);
g.DrawImageUnscaledAndClipped(img, rect);
}
return imgWithBackground;
}
Original image (fictional data) is this:
And when I convert it to gif I get this:
So my question:
is there a way to get gif format out of png that would look the same?
Edit:
Hans Passant pointed out that the root problem was transparent background.
After some digging I found answer here.
I used code snipped mentioned in the link to set background to white:
private Image SetWhiteBackground(Image img)
{
Bitmap imgWithBackground = new Bitmap(img.Width, img.Height);
Rectangle rect = new Rectangle(Point.Empty, img.Size);
using (Graphics g = Graphics.FromImage(imgWithBackground))
{
g.Clear(Color.White);
g.DrawImageUnscaledAndClipped(img, rect);
}
return imgWithBackground;
}
So now the gif looks like this:
Something like (https://docs.sixlabors.com/articles/imagesharp/gettingstarted.html):
using SixLabors.ImageSharp;
using SixLabors.ImageSharp.Processing;
// Open the file and detect the file type and decode it.
// Our image is now in an uncompressed, file format agnostic, structure in-memory as a series of pixels.
using (Image image = Image.Load("test-image.png"))
{
// The library automatically picks an encoder based on the file extensions then encodes and write the data to disk.
image.Save("test.gif");
}
Related
I have a C# WPF application which cuts a image to the size I need it. The WPF window is used to put in a user ID to save the image into a database. When I test my application it works sometimes and sometimes i get a error in gdi+ on the line I save the image to the file system.
Here is my code:
public static void CutImage(Image image)
{
//create new image
Bitmap source = new Bitmap(image);
//cut image
Bitmap cuttedImage = source.Clone(new System.Drawing.Rectangle(250, 0, 5550, 4000), source.PixelFormat);
//copy bitmap to avoid "general error in gdi+"
Bitmap copyImage = new Bitmap(cuttedImage.Width, cuttedImage.Height, PixelFormat.Format24bppRgb);
Graphics g = Graphics.FromImage(copyImage);
g.DrawImageUnscaled(cuttedImage, 0, 0);
//dispose graphics object
g.Dispose();
//dispose image
cuttedImage.Dispose();
//save image to filesystem
copyImage.Save(#"path\tmp.jpg", ImageFormat.Jpeg);
}
//get image
Image i = Image.FromFile(path\image.jpg);
//cut image
CutImage(i);
I searched for a solution and somebody said I have to create a copy of the image I got from Image.FromFile(). But the error still happens sometimes. I tried it a few times and it seems to be random when it happens. The error is always on the Image.Save() line.
Does somebody know how to solve this problem or is there a alternative to Image.Save()?
Thanks for your help!
You're creating so many bitmaps and you're not disposing them. Every single IDisposable must be explicitly disposed when you're finished with them.
Try this and see if the error goes away:
public static void CutImage(Image image)
{
using (Bitmap source = new Bitmap(image))
{
using (Bitmap cuttedImage = source.Clone(new System.Drawing.Rectangle(250, 0, 5550, 4000), source.PixelFormat))
{
using (Bitmap copyImage = new Bitmap(cuttedImage.Width, cuttedImage.Height, System.Drawing.Imaging.PixelFormat.Format24bppRgb))
{
using (Graphics g = Graphics.FromImage(copyImage))
{
g.DrawImageUnscaled(cuttedImage, 0, 0);
copyImage.Save(#"path\tmp.jpg", System.Drawing.Imaging.ImageFormat.Jpeg);
}
}
}
}
}
I have a C# WPF application which cuts a image to the size I need it. The WPF window is used to put in a user ID to save the image into a database. When I test my application it works sometimes and sometimes i get a error in gdi+ on the line I save the image to the file system.
Here is my code:
public static void CutImage(Image image)
{
//create new image
Bitmap source = new Bitmap(image);
//cut image
Bitmap cuttedImage = source.Clone(new System.Drawing.Rectangle(250, 0, 5550, 4000), source.PixelFormat);
//copy bitmap to avoid "general error in gdi+"
Bitmap copyImage = new Bitmap(cuttedImage.Width, cuttedImage.Height, PixelFormat.Format24bppRgb);
Graphics g = Graphics.FromImage(copyImage);
g.DrawImageUnscaled(cuttedImage, 0, 0);
//dispose graphics object
g.Dispose();
//dispose image
cuttedImage.Dispose();
//save image to filesystem
copyImage.Save(#"path\tmp.jpg", ImageFormat.Jpeg);
}
//get image
Image i = Image.FromFile(path\image.jpg);
//cut image
CutImage(i);
I searched for a solution and somebody said I have to create a copy of the image I got from Image.FromFile(). But the error still happens sometimes. I tried it a few times and it seems to be random when it happens. The error is always on the Image.Save() line.
Does somebody know how to solve this problem or is there a alternative to Image.Save()?
Thanks for your help!
You're creating so many bitmaps and you're not disposing them. Every single IDisposable must be explicitly disposed when you're finished with them.
Try this and see if the error goes away:
public static void CutImage(Image image)
{
using (Bitmap source = new Bitmap(image))
{
using (Bitmap cuttedImage = source.Clone(new System.Drawing.Rectangle(250, 0, 5550, 4000), source.PixelFormat))
{
using (Bitmap copyImage = new Bitmap(cuttedImage.Width, cuttedImage.Height, System.Drawing.Imaging.PixelFormat.Format24bppRgb))
{
using (Graphics g = Graphics.FromImage(copyImage))
{
g.DrawImageUnscaled(cuttedImage, 0, 0);
copyImage.Save(#"path\tmp.jpg", System.Drawing.Imaging.ImageFormat.Jpeg);
}
}
}
}
}
private void ConvertImagestoTransparent(string filename)
{
var image = new Bitmap(filename, PixelFormat.Format32bppArgb);
using (var g = Graphics.FromImage(image))
{
g.DrawLine(Pens.Red, 0, 0, 135, 135);
}
}
This give me error the new Bitmap is not getting filename:
Error 2 Argument 2: cannot convert from
'System.Drawing.Imaging.PixelFormat' to 'bool'
Also not getting Bitmap.
In the constructor:
DirectoryInfo d = new DirectoryInfo(#"C:\temp\images\");
Files = d.GetFiles("*.png");
Is it possible to convert the png images to transparent ? Will it lost quality ?
The Bitmap constructor you're using is only for loading existing images. If you want to create one, then you need to use this one like this:
var image = new Bitmap(theWidth, theHeight, PixelFormat.Format32bppArgb);
Then, you can save your image to a file like this:
image.Save(filename);
For your 2nd question, what do you mean by "convert the png images to transparent"? Do you want to remove the background color from the images?
I am getting the following Exception at ProcessImage(bitmap1, bitmap2);
Unsupported Pixel Format of source or template image
and this is my code:
public static double FindComparisonRatioBetweenImages(
System.Drawing.Image one, System.Drawing.Image two)
{
Bitmap bitmap1 = new Bitmap(one);
Bitmap bitmap2 = new Bitmap(two);
ExhaustiveTemplateMatching tm = new ExhaustiveTemplateMatching(0);
TemplateMatch[] matchings = null;
matchings = tm.ProcessImage(bitmap1, bitmap2); // Exception occurs here!
return matchings[0].Similarity;
}
I have also passed managedImage from the below code into the method, but it still gives error:
UnmanagedImage unmanagedImageA = UnmanagedImage.FromManagedImage(bitmap1);
Bitmap managedImageA = unmanagedImageA.ToManagedImage();
UnmanagedImage unmanagedImageB = UnmanagedImage.FromManagedImage(bitmap2);
Bitmap managedImageB = unmanagedImageB.ToManagedImage();
I have passed Images randomly from my computer, they all give exception.
I have passed Blank Image edited in paint into the method,it still give exception.
Also checked, jpeg, png, bmp formats, nothing work.
Try ExhaustiveTemplateMatching:
The class implements exhaustive template matching algorithm, which performs complete scan of source image, comparing each pixel with corresponding pixel of template.
The class processes only grayscale 8 bpp and color 24 bpp images.
So, those are the image formats you must use.
As requested, to convert to a specific pixel format, you can do this:
public static Bitmap ConvertToFormat(this Image image, PixelFormat format)
{
Bitmap copy = new Bitmap(image.Width, image.Height, format);
using (Graphics gr = Graphics.FromImage(copy))
{
gr.DrawImage(image, new Rectangle(0, 0, copy.Width, copy.Height));
}
return copy;
}
The one you would use is System.Drawing.Imaging.PixelFormat.Format24bppRgb.
I'm tring to edit multipage tiff by creating Graphics from the image, but i encountered the error message: “A Graphics object cannot be created from an image that has an indexed pixel format.”
How can i edit multipage tiff?
I wrote something to extract single pages from a multipage tiff file.
// Load as Bitmap
using (Bitmap bmp = new Bitmap(file))
{
// Get pages in bitmap
int frames = bmp.GetFrameCount(System.Drawing.Imaging.FrameDimension.Page);
bmp.SelectActiveFrame(System.Drawing.Imaging.FrameDimension.Page, tiffpage);
if (bmp.PixelFormat != PixelFormat.Format1bppIndexed)
{
using (Bitmap bmp2 = new Bitmap(bmp.Width, bmp.Height))
{
bmp2.Palette = bmp.Palette;
bmp2.SetResolution(bmp.HorizontalResolution, bmp.VerticalResolution);
// create graphics object for new bitmap
using (Graphics g = Graphics.FromImage(bmp2))
{
// copy current page into new bitmap
g.DrawImageUnscaled(bmp, 0, 0);
// do whatever you migth to do
...
}
}
}
}
The snippet loads the tif file and extracts the one page (number in variable tiffpage) into a new bitmap. This is not indexed and an graphics object can be created.
The error : A Graphics object cannot be created from an image that has an indexed pixel format.
...has nothing to do with it being a multipage TIFF. An indexed image format means it has a palette of colours, e.g. it's a 256-colour image. A 1-bit image (B&W) would also count as having a palette of 2 colours.
You can't perform Graphics operations on images that use a palette, they'd need to be converted to 15-bit or more colour depth first.
Here is a link to a CodeProject sample that includes code for converting a TIFF file to a normal Bitmap, which you can then work with like any other Bitmap:
http://www.codeproject.com/KB/GDI-plus/BitonalImageConverter.aspx
I once wrote little utility to create encrypted pdfs from tiff images. Here is a piece of code to get pages from tiff image:
var bm= new System.Drawing.Bitmap('tif path');
var total = bm.GetFrameCount(System.Drawing.Imaging.FrameDimension.Page);
for(var x=0;x<total;x++)
{
bm.SelectActiveFrame(System.Drawing.Imaging.FrameDimension.Page,x);
var img=Image.GetInstance(bm,null,false);
//do what ever you want with img object
}