0
        ```
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

Zahir
  • 13
  • 1
  • It is not so hard to create a 8bit image but your code doesn't even try. And 8bit doesn't really work with real alpha.. – TaW Jan 01 '21 at 22:35
  • @TaW When I asked the question, I didn't fully understand but now I understand. Thanks for the reply. :) – Zahir Jan 05 '21 at 09:03

2 Answers2

0

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)

Ashkan Mobayen Khiabani
  • 33,575
  • 33
  • 102
  • 171
  • He only claims to use 8bit images; in the code all is 32bit. Question is unclear.. – TaW Jan 01 '21 at 22:34
  • Yes i know, thats why i described these – Ashkan Mobayen Khiabani Jan 02 '21 at 00:54
  • @AshkanMobayenKhiabani Thank you for your reply. What do I spell instead of [https://stackoverflow.com/questions/2593212/editing-8bpp-indexed-bitmaps/39211938#39211938] "dataB" – Zahir Jan 02 '21 at 15:11
  • @TaW I asked the question because I couldn't do it myself. I wrote 32 bits, couldn't write 8 bits – Zahir Jan 02 '21 at 15:15
  • OK, then here is how you do it: You first(!) create the Palette of thr 256 most important colors in you image, then you set the pixels according to the palette. Still, there is no alpha expet for a dedicated tranpareny color.. [This](https://stackoverflow.com/questions/24211886/convert-pixel-color-array-to-byte-array-for-bitmap/24213166#24213166) may or may not help.. – TaW Jan 02 '21 at 18:54
  • @TaW simplest way to do this even with all 8-bit input is still to make a 32-bit end result though. And in that case, it's enough to lock just the `alpha` image as 8-bit, and remove the `* 4` on the `ptrAlpha` addressing. – Nyerguds Jan 04 '21 at 07:40
  • @AshkanMobayenKhiabani The current code fixes that issue by using `4 * x` in the actual loop though. And if this code is meant to combine addressing on a 32-bit and on an 8-bit image in the same loop, this is in fact a fairly decent way to do this. Your 32-bit code is wrong since it loops over the *width*, but skips per 4, which means it skips per four *pixels*, not *bytes*. – Nyerguds Jan 04 '21 at 07:46
  • @AshkanMobayenKhiabani `x+=3 for 32bit images` is also wrong; that would be *24* bit. But that whole part is wrong in general since you loop over the width instead of the actual data length of the line, which would be the stride, or, more accurately, `(input.Width * bpp + 7) / 8`. – Nyerguds Jan 06 '21 at 10:35
0

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.

Nyerguds
  • 5,360
  • 1
  • 31
  • 63
  • When I asked the question, I didn't fully understand but now I understand. Thanks for the reply. :) – Zahir Jan 05 '21 at 09:02
  • If an answer helped you, please upvote. If it solved your problem, accept it as solution. See *[SO Help: Someone Answers](https://stackoverflow.com/help/someone-answers)* – Nyerguds Jan 06 '21 at 10:29