简体   繁体   中英

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

I changed the PixelFormat to Format8bppIndexed.I set the pixel format to Format8bppIndexed and came to this conclusion image . Please help me

Red, Green, Blue and Alpha is for 32bit images (each of these is stored as a byte which 8 bits, 4 x 8 = 32), indexed images doesn't work this way.

1. if your image is a 32bit image, then your loop steps should be 4:

for (int x = 0; x < input.Width; x+=4) // x+=3 for 24bit images (without alpha like jpg images) 

instead of

for (int x = 0; x < input.Width; x++)

for 8bit indexed images it does not work that way and the colors are stored in a pallet ( have a look at this )

From what I can see, you're trying to use an 8-bit grayscale image as alpha for another picture.

This does not mean the final output will be 8-bit. It doesn't even mean the input image is 8-bit. In fact, the output of this should still be 32-bit, since 8-bit only supports palette-based transparency, meaning you set alpha to specific colours (affecting all pixels on the image that use that colour), rather than to specific pixels on the image.

The only things you need to change are these:

  • Since the alpha image is apparently 8-bit, lock that one as 8-bit. But to be sure, you should add a specific check in advance to test if its pixel format is indeed Format8bppIndexed .
  • Since that image is now locked as 8-bit, its single pixels are not grouped per 4 bytes but per 1 byte. So in the code that retrieves the alpha from it, remove the * 4 part.

The changed lines:

var bitsAlpha = alpha.LockBits(rect, ImageLockMode.ReadOnly, PixelFormat.Format8bppIndexed);

and

ptrOutput[4 * x + 3] = ptrAlpha[x];        // alpha

Besides this, the code should be kept as it is.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM