C# GDI+合成透明位图
我想用Graphics.DrawImage重写这个方法。无论bitmapToDrawOn的PixelFormat和BitmapDrawen值是什么,我都尝试了所有组合,它们通常应该是PixelFormat.Format32bppRgb和PixelFormat.Format32bppArgb或PixelFormat.Format32bppPArgb,我无法获得此结果 这个合成操作对我来说似乎很明显,所以看起来我遗漏了什么C# GDI+合成透明位图,c#,gdi+,alpha-transparency,C#,Gdi+,Alpha Transparency,我想用Graphics.DrawImage重写这个方法。无论bitmapToDrawOn的PixelFormat和BitmapDrawen值是什么,我都尝试了所有组合,它们通常应该是PixelFormat.Format32bppRgb和PixelFormat.Format32bppArgb或PixelFormat.Format32bppPArgb,我无法获得此结果 这个合成操作对我来说似乎很明显,所以看起来我遗漏了什么 private static void ComposeBitmapWithT
private static void ComposeBitmapWithTransparency(Bitmap bitmapToDrawOn, Bitmap bitmapDrawn) {
Debug.Assert(bitmapToDrawOn != null);
Debug.Assert(bitmapToDrawOn.PixelFormat == PixelFormat.Format32bppRgb);
Debug.Assert(bitmapDrawn != null);
Debug.Assert(bitmapDrawn.PixelFormat == PixelFormat.Format32bppArgb);
var width = bitmapToDrawOn.Width;
Debug.Assert(bitmapDrawn.Width == width);
var height = bitmapToDrawOn.Height;
Debug.Assert(bitmapDrawn.Height == height);
var rect = new Rectangle(0, 0, width, height);
var bitmapToDrawOnData = bitmapToDrawOn.LockBits(
rect,
ImageLockMode.ReadWrite,
bitmapToDrawOn.PixelFormat);
var bitmapDrawnData = bitmapDrawn.LockBits(
rect,
ImageLockMode.ReadOnly,
bitmapDrawn.PixelFormat);
unsafe {
var pBitmapToDrawOn = (StructPixel*)bitmapToDrawOnData.Scan0;
var pBitmapDrawn = (StructPixel*)bitmapDrawnData.Scan0;
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
byte r = pBitmapToDrawOn->R;
byte g = pBitmapToDrawOn->G;
byte b = pBitmapToDrawOn->B;
byte rX = pBitmapDrawn->R;
byte gX = pBitmapDrawn->G;
byte bX = pBitmapDrawn->B;
// Only the transparency of bitmapDrawn is taken account.
byte alphaX = pBitmapDrawn->Alpha;
byte alphaXComplement = (byte)(255 - alphaX);
pBitmapToDrawOn->R = (byte)((r * alphaXComplement + rX * alphaX) >> 8);
pBitmapToDrawOn->G = (byte)((g * alphaXComplement + gX * alphaX) >> 8);
pBitmapToDrawOn->B = (byte)((b * alphaXComplement + bX * alphaX) >> 8);
pBitmapToDrawOn++;
pBitmapDrawn++;
}
}
}
bitmapDrawn.UnlockBits(bitmapDrawnData);
bitmapToDrawOn.UnlockBits(bitmapToDrawOnData);
}
你能发布StructPixel的代码吗?StructPixel的代码发布了。这里的实际问题是什么?是否要使用Graphics.DrawBitmap绘制?这个方法不存在。我指的是DrawImage,而不是DrawBitmap。很抱歉混淆了。问题是我找不到一种方法来使用DrawImage来获得用这种方法编码的具有透明效果的明显合成。我已经读了你的答案,但是我得到的构图效果与明显的不同,我不知道为什么。合成算法似乎在每个RGB通道上使用[255]模,因此在阿尔法为50%的情况下,合成两个通道值100和200时,DrawBitmap的值不是150,而是100+200=300[255]=45
[StructLayout(LayoutKind.Explicit)]
public struct StructPixel {
[FieldOffset(0)]
public byte B;
[FieldOffset(1)]
public byte G;
[FieldOffset(2)]
public byte R;
[FieldOffset(3)]
public byte Alpha;
}