Split PNG into RGB and Alpha Channels

时间秒杀一切 提交于 2019-12-19 04:16:04

问题


I'm trying to do some automated processing of PNG files that takes in an RGBa .png file and outputs two jpeg files: 1 that is just the RGB channels and the other that is just the alpha channel, as a greyscale image.

Is there any way to do this in C# natively? If a third party library is required, that is fine as long as it's free/open source, but I would prefer to just do it directly with GDI or something.


回答1:


Here is my working code:

    /// <summary>
    /// Split PNG file into two JPGs (RGB and alpha)
    /// </summary>
    private void SplitPngFileIntoRGBandAplha(string imagePath)
    {
        try
        {
            // Open original bitmap
            var bitmap = new Bitmap(imagePath);

            // Rectangle 
            var rect = new Rectangle(0, 0, bitmap.Width, bitmap.Height);

            // Get RGB bitmap
            var bitmapInRgbFormat = bitmap.Clone(rect, PixelFormat.Format32bppRgb);

            // Read bitmap data
            BitmapData bmData = bitmap.LockBits(rect, ImageLockMode.ReadOnly, bitmap.PixelFormat);

            // Prepare alpha bitmap
            var alphaBitmap = new Bitmap(bmData.Width, bmData.Height, PixelFormat.Format32bppRgb);

            for (int y = 0; y <= bmData.Height -1; y++)
            {
                for (int x = 0; x <= bmData.Width -1; x++)
                {
                    Color PixelColor = Color.FromArgb(Marshal.ReadInt32(bmData.Scan0, (bmData.Stride * y) + (4 * x)));
                    if (PixelColor.A > 0 & PixelColor.A <= 255)
                    {
                        alphaBitmap.SetPixel(x, y, Color.FromArgb(PixelColor.A, PixelColor.A, PixelColor.A, PixelColor.A));
                    }
                    else
                    {
                        alphaBitmap.SetPixel(x, y, Color.FromArgb(0, 0, 0, 0));
                    }
                }
            }

            bitmap.UnlockBits(bmData);

            // Prepare JPG format
            ImageCodecInfo jgpEncoder = GetEncoder(ImageFormat.Jpeg);
            var encoder =  Encoder.Quality;
            var encoderParameters = new EncoderParameters(1);
            var encoderParameter = new EncoderParameter(encoder, 100L);
            encoderParameters.Param[0] = encoderParameter;

            // Save RGB bitmap
            bitmapInRgbFormat.Save(imagePath.Replace("png", "jpg"), jgpEncoder, encoderParameters);

            // Save Alpha bitmpa
            alphaBitmap.Save(imagePath.Replace(".png", "_alpha.jpg"), jgpEncoder, encoderParameters);

            bitmap.Dispose();
            bitmapInRgbFormat.Dispose();
            bitmap.Dispose();

            // Delete bitmap
            System.IO.File.Delete(imagePath);
        }
        catch(Exception e)
        {
             // Handle exception
        }

    }



回答2:


Option - load to Bitmap, clone to get RGB only, than manually grab bits with LockBits and extract alpha channel to create new greyscale bitmap from it.

// get RGB copy
var bitmapInRgbFormat = loadedBitmap.Clone(
        new Rectangle(0, 0, loadedBitmap.Width, loadedBitmap.Height),
        PixelFormat.Format32bppRgb)


来源:https://stackoverflow.com/questions/15207815/split-png-into-rgb-and-alpha-channels

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!