c# - c# System.Drawing 中的 Alpha 掩蔽?

标签 c# alpha masking

我正在尝试使用 System.Drawing.Graphics 使用源 Bitmap 和 alpha 掩码 Bitmap 绘制图像目的。 目前我循环 X 和 Y 并使用 GetPixelSetPixel 将源颜色和 mask alpha 写入第三个 Bitmap,然后渲染那。 然而,这是非常低效的,我想知道是否有更快的方法来实现这一点?

我想要的效果是这样的:

Effect I’m after

网格图案代表透明度;你可能知道这一点。

最佳答案

是的,更快的方法是使用 Bitmap.LockBits 并使用指针算法来检索值,而不是 GetPixelSetPixel。当然,缺点是您必须使用不安全的代码;如果你犯了一个错误,你可能会在你的程序中导致一些非常严重的崩溃。但如果你保持简单和独立,应该没问题(嘿,如果我能做到,你也能做到)。

例如,您可以这样做(未经测试,使用风险自负):

Bitmap mask = ...;
Bitmap input = ...;

Bitmap output = new Bitmap(input.Width, input.Height, PixelFormat.Format32bppArgb);
var rect = new Rectangle(0, 0, input.Width, input.Height);
var bitsMask = mask.LockBits(rect, ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);
var bitsInput = input.LockBits(rect, ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);
var bitsOutput = output.LockBits(rect, ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb);
unsafe
{
    for (int y = 0; y < input.Height; y++)
    {
        byte* ptrMask = (byte*) bitsMask.Scan0 + y * bitsMask.Stride;
        byte* ptrInput = (byte*) bitsInput.Scan0 + y * bitsInput.Stride;
        byte* ptrOutput = (byte*) bitsOutput.Scan0 + y * bitsOutput.Stride;
        for (int x = 0; x < input.Width; x++)
        {
            ptrOutput[4 * x] = ptrInput[4 * x];           // blue
            ptrOutput[4 * x + 1] = ptrInput[4 * x + 1];   // green
            ptrOutput[4 * x + 2] = ptrInput[4 * x + 2];   // red
            ptrOutput[4 * x + 3] = ptrMask[4 * x];        // alpha
        }
    }
}
mask.UnlockBits(bitsMask);
input.UnlockBits(bitsInput);
output.UnlockBits(bitsOutput);

output.Save(...);

此示例从掩码图像中的 blue channel 导出输出中的 alpha channel 。如果需要,我相信您可以将其更改为使用 mask 的红色或 alpha channel 。

关于c# - c# System.Drawing 中的 Alpha 掩蔽?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3654220/

相关文章:

javascript - 光标在输入标签中不起作用

c# - 有没有办法在 SQL Server CE 中一次搜索所有表的字段?

android - 了解android中的动画功能

java - 如何检测RGB是否完全透明?

android - 以编程方式在android中获取ARGB背景颜色中的A值

html - 如何创建带旋转的 CSS3 溢出隐藏隐藏聚光灯效果?

c# - 如果条件为真,代码不返回

c# - Entity Framework 多个多对多查询

c# - 从 C# 中的 XML 填充下拉列表

objective-c - SKCropNode 屏蔽边缘抗锯齿