Advertisement
pushrbx

Premute Image Alpha

Apr 21st, 2013
146
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.39 KB | None | 0 0
  1. void ImagePreMultAlpha(Image *pImage)
  2. {
  3.     // The per pixel alpha blending API for layered windows deals with
  4.     // pre-multiplied alpha values in the RGB channels. For further details see
  5.     // the MSDN documentation for the BLENDFUNCTION structure. It basically
  6.     // means we have to multiply each red, green, and blue channel in our image
  7.     // with the alpha value divided by 255.
  8.     //
  9.     // Notes:
  10.     // 1. ImagePreMultAlpha() needs to be called before every call to
  11.     //    UpdateLayeredWindow() (in the RedrawLayeredWindow() function).
  12.     //
  13.     // 2. Must divide by 255.0 instead of 255 to prevent alpha values in range
  14.     //    [1, 254] from causing the pixel to become black. This will cause a
  15.     //    conversion from 'float' to 'BYTE' possible loss of data warning which
  16.     //    can be safely ignored.
  17.  
  18.     if (!pImage)
  19.         return;
  20.  
  21.     BYTE *pPixel = NULL;
  22.  
  23.     if (pImage->width * 4 == pImage->pitch)
  24.     {
  25.         // This is a special case. When the image width is already a multiple
  26.         // of 4 the image does not require any padding bytes at the end of each
  27.         // scan line. Consequently we do not need to address each scan line
  28.         // separately. This is much faster than the below case where the image
  29.         // width is not a multiple of 4.
  30.        
  31.         int totalBytes = pImage->width * pImage->height * 4;
  32.  
  33.         for (int i = 0; i < totalBytes; i += 4)
  34.         {
  35.             pPixel = &pImage->pPixels[i];
  36.             pPixel[0] = (BYTE)(pPixel[0] * (float)pPixel[3] / 255.0f);
  37.             pPixel[1] = (BYTE)(pPixel[1] * (float)pPixel[3] / 255.0f);
  38.             pPixel[2] = (BYTE)(pPixel[2] * (float)pPixel[3] / 255.0f);
  39.         }
  40.     }
  41.     else
  42.     {
  43.         // Width of the image is not a multiple of 4. So padding bytes have
  44.         // been included in the DIB's pixel data. Need to address each scan
  45.         // line separately. This is much slower than the above case where the
  46.         // width of the image is already a multiple of 4.
  47.  
  48.         for (int y = 0; y < pImage->height; ++y)
  49.         {
  50.             for (int x = 0; x < pImage->width; ++x)
  51.             {
  52.                 pPixel = &pImage->pPixels[(y * pImage->pitch) + (x * 4)];
  53.                 pPixel[0] = (BYTE)(pPixel[0] * (float)pPixel[3] / 255.0f);
  54.                 pPixel[1] = (BYTE)(pPixel[1] * (float)pPixel[3] / 255.0f);
  55.                 pPixel[2] = (BYTE)(pPixel[2] * (float)pPixel[3] / 255.0f);
  56.             }
  57.         }
  58.     }
  59. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement