仅使用 CPU 将 ARGB 位图合成在一起

问题描述 投票:0回答:1

这是我面临的一个问题。当尝试将多个位图合成在一起时,我得到了一个奇怪的结果。

Desired result (but this was done manually)

Current result with the weird oddities

这是代码片段。这里我尝试使用两个字节数组,每个数组都包含 ARGB 值。

public static void Composite(this byte[] input, byte[] layer, int x, int y, int width, int height)
{
    int w = width;
    if (w > RewBatch.width)
    {
        w = RewBatch.width;
    }
    Parallel.For(0, height, j =>
    {
        for (int i = 0; i < w; i += 4)
        {
            int whoAmI = (y + j) * w + (x + i);
            if (whoAmI < 0 || whoAmI > input.Length)
            {
                continue;
            }
            Pixel _one = Pixel.Extract32bit(input, whoAmI);
            Pixel _two = Pixel.Extract32bit(layer, j * width + i);
            if (_two.A < 255)
            {
                Color blend = _two.color.Blend(_one.color, 0.15d);
                input[whoAmI] = blend.B;
                input[whoAmI + 1] = blend.G;
                input[whoAmI + 2] = blend.R;
                input[whoAmI + 3] = blend.A;
            }
            else
            {
                input[whoAmI] = 255;
                input[whoAmI + 1] = _two.color.R;
                input[whoAmI + 2] = _two.color.G;
                input[whoAmI + 3] = _two.color.B;
            }
        }
    });
}
c# arrays real-time alphablending compositing
1个回答
0
投票
public virtual void CompositeImage(byte[] buffer, int bufferWidth, int bufferHeight, byte[] image, int imageWidth, int imageHeight, int x, int y)
{
    for (int i = 0; i < imageHeight; i++)
    {
        for (int j = 0; j < imageWidth; j++)
        {
            if (j > bufferWidth)
            {
                continue;
            }
            if (i > bufferHeight)
            {
                continue;
            }

            int index = Math.Min((i * imageWidth + j) * 4, image.Length - 4);
            int bufferIndex = ((y + i) * bufferWidth + (x + j)) * 4;

            if (bufferIndex < 0 || bufferIndex >= buffer.Length - 4)
                return;
            Pixel back = new Pixel(
                buffer[bufferIndex + 3],
                buffer[bufferIndex + 2],
                buffer[bufferIndex + 1],
                buffer[bufferIndex]
            );
            Pixel fore = new Pixel(
                image[index],
                image[index + 1],
                image[index + 2],
                image[index + 3]
            );

            if (fore.A < 255)
            {
                Color blend = fore.color.Blend(back.color, 0.15d);
                buffer[bufferIndex] = blend.B;
                buffer[bufferIndex + 1] = blend.G;
                buffer[bufferIndex + 2] = blend.R;

                if (back.A == 255) buffer[bufferIndex + 3] = 255;
                else buffer[bufferIndex + 3] = blend.A;
            }
            else
            {
                buffer[bufferIndex] = fore.color.B;
                buffer[bufferIndex + 1] = fore.color.G;
                buffer[bufferIndex + 2] = fore.color.R;
                buffer[bufferIndex + 3] = 255;
            }

            //back = back.Composite(fore);
        }
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.