【问题标题】:How can I merge bitmap (Alpha Bitmap and Main Bitmap) in C#?如何在 C# 中合并位图(Alpha 位图和主位图)?
【发布时间】:2021-04-08 12:57:00
【问题描述】:
        ```
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。我将像素格式设置为 Format8bppIndexed 并得出此结论 image 。请帮帮我

【问题讨论】:

  • 创建 8 位图像并不难,但您的代码甚至没有尝试。而且 8bit 并不真正适用于真正的 alpha ..
  • @TaW 当我问这个问题时,我并不完全明白,但现在我明白了。谢谢回复。 :)

标签: c# image merge bitmap


【解决方案1】:

据我所知,您正在尝试使用 8 位灰度图像作为另一张图片的 Alpha。

不是意味着最终输出将是 8 位。这甚至不意味着input 图像是 8 位的。实际上,它的输出应该仍然是 32 位,因为 8 位只支持基于调色板的透明度,这意味着您将 alpha 设置为特定的 colors(影响图像上使用该颜色的所有像素),而不是图像上的特定像素

你需要改变的只有这些:

  • 由于 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

除此之外,代码应保持原样。

【讨论】:

  • 当我问这个问题时,我并没有完全理解,但现在我明白了。谢谢回复。 :)
  • 如果回答对您有帮助,请点赞。如果它解决了您的问题,请接受它作为解决方案。见SO Help: Someone Answers
【解决方案2】:

Red、Green、Blue 和 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)

【讨论】:

  • 他只声称使用8bit图像;在代码中都是 32 位的。问题不清楚..
  • 是的,我知道,这就是我描述这些的原因
  • @AshkanMobayenKhiabani 感谢您的回复。我拼写什么而不是 [stackoverflow.com/questions/2593212/…"dataB"
  • @TaW 我问了这个问题,因为我自己做不到。我写了 32 位,不能写 8 位
  • 好的,那么你就是这样做的:你首先(!)在你的图像中创建 thr 256 种最重要的颜色的调色板,然后根据调色板设置像素。尽管如此,没有专门的透明颜色的 alpha expet..This 可能有帮助,也可能没有帮助..
猜你喜欢
  • 2014-04-06
  • 1970-01-01
  • 1970-01-01
  • 2010-09-23
  • 2012-12-25
  • 1970-01-01
  • 1970-01-01
  • 2013-07-07
  • 1970-01-01
相关资源
最近更新 更多