Search code examples
c#pngtype-conversionjpegbmp

Convert All to JPG in C#


I have a function like the following:

    // Convert To JPG 
    // 
    public string AlltoJPG(FileInfo foo)
    {
        // Get file extension
        string fileExtension = foo.Extension;

        // Get file name without extenstion
        string fileName = foo.Name.Replace(foo.Extension, string.Empty) + ".jpg";

        /*------------------------------------------------------------------------*/

        /// <Check for PNG File Format>
        if (fileExtension == ".png" || fileExtension == ".PNG")
        {
            System.Drawing.Image img = System.Drawing.Image.FromFile(foo.FullName);

            // Assumes img is the PNG you are converting
            using (Bitmap b = new Bitmap(img.Width, img.Height))
            {
                using (System.Drawing.Graphics g = System.Drawing.Graphics.FromImage(b))
                {
                    g.Clear(System.Drawing.Color.White);
                    g.DrawImageUnscaled(img, 0, 0);
                }

                // Save the image as a JPG
                b.Save(fileName, System.Drawing.Imaging.ImageFormat.Jpeg);
            }

        }

        /*------------------------------------------------------------------------*/

        /// <Check for GIF File Format>
        if (fileExtension == ".gif" || fileExtension == ".GIF")
        {
            System.Drawing.Image img = System.Drawing.Image.FromFile(foo.FullName);

            // Construct a bitmap from the image resource.
            Bitmap bmp1 = new Bitmap(img.Width, img.Height);

            // Save the image as a JPG
            bmp1.Save(fileName, System.Drawing.Imaging.ImageFormat.Jpeg);
        }

        /*------------------------------------------------------------------------*/

        /// <Check for BMP File Format>
        if (fileExtension == ".bmp" || fileExtension == ".BMP")
        {
            System.Drawing.Image img = System.Drawing.Image.FromFile(foo.FullName);

            // Construct a bitmap from the image resource.
            Bitmap bmp1 = new Bitmap(img.Width, img.Height);

            // Save the image as a JPG
            bmp1.Save(fileName, System.Drawing.Imaging.ImageFormat.Jpeg);
        }

        /*------------------------------------------------------------------------*/

        /// <Check for TIFF File Format>
        if (fileExtension == ".tiff" || fileExtension == ".TIFF")
        {
            System.Drawing.Image img = System.Drawing.Image.FromFile(foo.FullName);

            // Construct a bitmap from the image resource.
            Bitmap bmp1 = new Bitmap(img.Width, img.Height);

            // Save the image as a JPG
            bmp1.Save(fileName, System.Drawing.Imaging.ImageFormat.Jpeg);
        }

        /*------------------------------------------------------------------------*/
        fileName = foo.DirectoryName + "\\" + fileName;
        return fileName;
    }

I'm trying to convert bmp,png,gif,tiff file formats to jpg, but GDI+ as gives:

System.OutOfMemoryException was unhandled
Message=Bellek yetersiz.
Source=System.Drawing
StackTrace:
konum: System.Drawing.Image.FromFile(String filename, Boolean useEmbeddedColorManagement)
konum: System.Drawing.Image.FromFile(String filename)

So how can I avoid this and convert at least PNG and BMP files to JPG?

Here is a picture of the error:

enter image description here


Solution

  • I found the problem! It was caused by PNG alpha channel..

    Thanks to max, link below solved my problem:

    How to load Transparent PNG to Bitmap and ignore alpha channel


    public static void SetAlpha(this Bitmap bmp, byte alpha)
    {
        if(bmp == null) throw new ArgumentNullException("bmp");
    
        var data = bmp.LockBits(
            new Rectangle(0, 0, bmp.Width, bmp.Height),
            System.Drawing.Imaging.ImageLockMode.ReadWrite,
            System.Drawing.Imaging.PixelFormat.Format32bppArgb);
    
        var line = data.Scan0;
        var eof = line + data.Height * data.Stride;
        while(line != eof)
        {
            var pixelAlpha = line + 3;
            var eol = pixelAlpha + data.Width * 4;
            while(pixelAlpha != eol)
            {
                System.Runtime.InteropServices.Marshal.WriteByte(
                    pixelAlpha, alpha);
                pixelAlpha += 4;
            }
            line += data.Stride;
        }
        bmp.UnlockBits(data);
    }
    

    Usage:

    var pngImage = new Bitmap("filename.png");
    pngImage.SetAlpha(255);
    

    after setting alpha it started to work correctly.