如何在 C# 中合并位图(Alpha 位图和主位图)?
How can I merge bitmap (Alpha Bitmap and Main Bitmap) in C#?
```
if (alpha != null && input != null)
{
Bitmap output = new Bitmap(input.Width, input.Height, PixelFormat.Format32bppArgb);
var rect = new Rectangle(0, 0, input.Width, input.Height);
var bitsAlpha = alpha.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* ptrAlpha = (byte*)bitsAlpha.Scan0 + y * bitsAlpha.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] = ptrAlpha[4 * x]; // alpha
}
}
}
alpha.UnlockBits(bitsAlpha);
input.UnlockBits(bitsInput);
output.UnlockBits(bitsOutput);
return output;
}
```
我将 PixelFormat 更改为 Format8bppIndexed.I 将像素格式设置为 Format8bppIndexed 并得出了这个结论 image 。请帮助我
红色、绿色、蓝色和 Alpha 用于 32 位图像(每个图像都存储为一个字节,8 位,4 x 8 = 32),索引图像不适用于这种方式。
1。如果你的图像是 32 位图像,那么你的循环步骤应该是 4:
for (int x = 0; x < input.Width; x+=4) // x+=3 for 24bit images (without alpha like jpg images)
而不是
for (int x = 0; x < input.Width; x++)
对于 8 位索引图像,它不能那样工作,颜色存储在托盘中 (have a look at this)
据我所知,您正在尝试使用 8 位灰度图像作为另一张图片的 alpha。
这不意味着最终输出将是 8 位。它甚至并不意味着 input
图像是 8 位的。事实上,它的输出应该仍然是 32 位,因为 8 位只支持基于调色板的透明度,这意味着您将 alpha 设置为特定的 colours(影响图像上的所有像素使用那种颜色),而不是图像上的特定像素。
您唯一需要更改的是:
- 由于 alpha 图像显然是 8 位的,因此将其锁定为 8 位。但是可以肯定的是,你应该提前添加一个特定的检查来测试它的像素格式是否确实是
Format8bppIndexed
.
- 由于该图像现在被锁定为 8 位,因此其单个像素不是每 4 个字节分组,而是每 1 个字节分组。因此,在从中检索 alpha 的代码中,删除
* 4
部分。
更改的行:
var bitsAlpha = alpha.LockBits(rect, ImageLockMode.ReadOnly, PixelFormat.Format8bppIndexed);
和
ptrOutput[4 * x + 3] = ptrAlpha[x]; // alpha
除此之外,代码应保持原样。
```
if (alpha != null && input != null)
{
Bitmap output = new Bitmap(input.Width, input.Height, PixelFormat.Format32bppArgb);
var rect = new Rectangle(0, 0, input.Width, input.Height);
var bitsAlpha = alpha.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* ptrAlpha = (byte*)bitsAlpha.Scan0 + y * bitsAlpha.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] = ptrAlpha[4 * x]; // alpha
}
}
}
alpha.UnlockBits(bitsAlpha);
input.UnlockBits(bitsInput);
output.UnlockBits(bitsOutput);
return output;
}
```
我将 PixelFormat 更改为 Format8bppIndexed.I 将像素格式设置为 Format8bppIndexed 并得出了这个结论 image 。请帮助我
红色、绿色、蓝色和 Alpha 用于 32 位图像(每个图像都存储为一个字节,8 位,4 x 8 = 32),索引图像不适用于这种方式。
1。如果你的图像是 32 位图像,那么你的循环步骤应该是 4:
for (int x = 0; x < input.Width; x+=4) // x+=3 for 24bit images (without alpha like jpg images)
而不是
for (int x = 0; x < input.Width; x++)
对于 8 位索引图像,它不能那样工作,颜色存储在托盘中 (have a look at this)
据我所知,您正在尝试使用 8 位灰度图像作为另一张图片的 alpha。
这不意味着最终输出将是 8 位。它甚至并不意味着 input
图像是 8 位的。事实上,它的输出应该仍然是 32 位,因为 8 位只支持基于调色板的透明度,这意味着您将 alpha 设置为特定的 colours(影响图像上的所有像素使用那种颜色),而不是图像上的特定像素。
您唯一需要更改的是:
- 由于 alpha 图像显然是 8 位的,因此将其锁定为 8 位。但是可以肯定的是,你应该提前添加一个特定的检查来测试它的像素格式是否确实是
Format8bppIndexed
. - 由于该图像现在被锁定为 8 位,因此其单个像素不是每 4 个字节分组,而是每 1 个字节分组。因此,在从中检索 alpha 的代码中,删除
* 4
部分。
更改的行:
var bitsAlpha = alpha.LockBits(rect, ImageLockMode.ReadOnly, PixelFormat.Format8bppIndexed);
和
ptrOutput[4 * x + 3] = ptrAlpha[x]; // alpha
除此之外,代码应保持原样。