C# Растровое размытие с прозрачным фоном - PullRequest
1 голос
/ 10 марта 2020

Я бы хотел добавить эффект размытия на мой текст. Для этого я использую этот метод:

public static Bitmap ConvolutionFilter(Bitmap sourceBitmap, double[,] filterMatrix, double factor = 1, int bias = 0)
    {
        BitmapData sourceData = sourceBitmap.LockBits(new Rectangle(0, 0,
                                 sourceBitmap.Width, sourceBitmap.Height),
                                                   ImageLockMode.ReadOnly,
                                             System.Drawing.Imaging.PixelFormat.Format32bppArgb);


        byte[] pixelBuffer = new byte[sourceData.Stride * sourceData.Height];
        byte[] resultBuffer = new byte[sourceData.Stride * sourceData.Height];


        Marshal.Copy(sourceData.Scan0, pixelBuffer, 0, pixelBuffer.Length);
        sourceBitmap.UnlockBits(sourceData);

        double blue = 0.0;
        double green = 0.0;
        double red = 0.0;

        int filterWidth = filterMatrix.GetLength(1);
        int filterHeight = filterMatrix.GetLength(0);

        int filterOffset = (filterWidth - 1) / 2;
        int calcOffset = 0;

        int byteOffset = 0;

        for (int offsetY = filterOffset; offsetY < sourceBitmap.Height - filterOffset; offsetY++)
        {
            for (int offsetX = filterOffset; offsetX < sourceBitmap.Width - filterOffset; offsetX++)
            {
                blue = 0;
                green = 0;
                red = 0;

                byteOffset = offsetY * sourceData.Stride + offsetX * 4;

                for (int filterY = -filterOffset; filterY <= filterOffset; filterY++)
                {
                    for (int filterX = -filterOffset; filterX <= filterOffset; filterX++)
                    {
                        calcOffset = byteOffset +
                                     (filterX * 4) +
                                     (filterY * sourceData.Stride);

                        blue += (double)(pixelBuffer[calcOffset]) *
                                filterMatrix[filterY + filterOffset,
                                                    filterX + filterOffset];

                        green += (double)(pixelBuffer[calcOffset + 1]) *
                                 filterMatrix[filterY + filterOffset,
                                                    filterX + filterOffset];

                        red += (double)(pixelBuffer[calcOffset + 2]) *
                               filterMatrix[filterY + filterOffset,
                                                  filterX + filterOffset];
                    }
                }

                blue = factor * blue + bias;
                green = factor * green + bias;
                red = factor * red + bias;

                blue = (blue > 255 ? 255 : (blue < 0 ? 0 :  blue));

                green = (green > 255 ? 255 : (green < 0 ? 0 : green));

                red = (red > 255 ? 255 : (red < 0 ? 0 : red));

                resultBuffer[byteOffset] = (byte)(blue);
                resultBuffer[byteOffset + 1] = (byte)(green);
                resultBuffer[byteOffset + 2] = (byte)(red);

                resultBuffer[byteOffset + 3] = 255;
            }
        }

        Bitmap resultBitmap = new Bitmap(sourceBitmap.Width, sourceBitmap.Height);

        BitmapData resultData = resultBitmap.LockBits(new Rectangle(0, 0, resultBitmap.Width, resultBitmap.Height), ImageLockMode.WriteOnly,
                                             System.Drawing.Imaging.PixelFormat.Format32bppArgb);

        Marshal.Copy(resultBuffer, 0, resultData.Scan0, resultBuffer.Length);
        resultBitmap.UnlockBits(resultData);

        return resultBitmap;
    }

Код из: https://softwarebydefault.com/2013/06/09/image-blur-filters/

Этот метод размывает мой текст, но он становится прозрачным фон на черном фоне.

До: enter image description here

После: enter image description here

Текст представляет собой растровое изображение с помощью метода Graphics.DrawText (...). Я хотел бы получить размытый текст, но на прозрачном фоне. Как мне этого добиться?

1 Ответ

2 голосов
/ 10 марта 2020

Вы устанавливаете альфа-значение на 255 (не прозрачное) в фильтре.

resultBuffer[byteOffset + 3] = 255; // Fully opaque - not transparent at all

Если вы рассматриваете альфа-компонент так же, как цветовые компоненты (красный / зеленый / синий), я думаю, вы получу то, что вы после.

...