2

我正在尝试对接受 RGBa .png 文件并输出两个 jpeg 文件的 PNG 文件进行一些自动处理:1 个只是 RGB 通道,另一个只是 alpha 通道,作为灰度图像。

有什么办法可以在 C# 中原生地做到这一点吗?如果需要第三方库,只要它是免费/开源的就可以了,但我更愿意直接使用 GDI 或其他东西来做。

4

2 回答 2

3

这是我的工作代码:

    /// <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
        }

    }
于 2013-05-28T07:03:30.917 回答
1

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)
于 2013-03-04T18:03:44.757 回答