C# GDI+合成透明位图

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

我想用Graphics.DrawImage重写这个方法。无论bitmapToDrawOn的PixelFormat和BitmapDrawen值是什么,我都尝试了所有组合,它们通常应该是PixelFormat.Format32bppRgb和PixelFormat.Format32bppArgb或PixelFormat.Format32bppPArgb,我无法获得此结果

这个合成操作对我来说似乎很明显,所以看起来我遗漏了什么

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;
   }