The following code provides a routine for combining an image and a mask image into
an image with Alpha information.
The routine uses the GDI+ bitmap's Lockbits method to provide fast access to the
image data.
This routine is available in the GDIPExtensions unit which is part of GDI+ Controls.
function CombineImageMask(Bitmap: TGPBitmap; Mask: TGPBitmap; var AlphaRGBImage: TGPBitmap): boolean; var w, h: cardinal; x, y: cardinal; obmd: TBitmapData; bbmd: TBitmapData; mbmd: TBitmapData; r: TGPRect; oImageStart: PByteArray; opixelpos: integer; oPixel: pARGB; bImageStart : PByteArray; bpixelpos: integer; bPixel: pARGB; mImageStart: PByteArray; mpixelpos : integer; mPixel: pARGB; alphalevel: cardinal; begin AlphaRGBImage := nil; if not assigned(Bitmap) then raise EImageProcessError.create('No Bitmap assigned'); if not assigned(Mask) then raise EImageProcessError.create('No Mask assigned'); if (Bitmap.GetWidth = 0) or (Bitmap.GetHeight = 0) then raise EImageProcessError.create('Height and width of image must be greater than zero'); if (Bitmap.GetWidth <> Mask.GetWidth) or (Bitmap.GetHeight <> Mask.GetWidth) then raise EImageProcessError.create('The hieght and width of both the image and mask should be the same'); w := Bitmap.GetWidth; h := Bitmap.GetHeight; AlphaRGBImage := TGPBitmap.Create(w, h, PixelFormat32bppARGB); r := MakeRect(0, 0, integer(w), integer(h)); bitmap.LockBits(r, ImageLockModeRead, PixelFormat32bppRGB, bbmd); mask.LockBits(r, ImageLockModeRead, PixelFormat32bppRGB, mbmd); AlphaRGBImage.LockBits(r, ImageLockModeWrite, PixelFormat32bppARGB, obmd); bImageStart := bbmd.Scan0; mImageStart := mbmd.Scan0; oImageStart := obmd.Scan0; for y := 0 to obmd.Height - 1 do begin for x := 0 to obmd.Width - 1 do begin opixelpos := (y * cardinal(obmd.Stride)) + (x * 4); oPixel := @oImageStart[oPixelPos]; bpixelpos := (y * cardinal(bbmd.Stride)) + (x * 4); bPixel := @bImageStart[bPixelPos]; mpixelpos := (y * cardinal(mbmd.Stride)) + (x * 4); mPixel := @mImageStart[mPixelPos]; oPixel^ := bPixel^ and not ALPHA_MASK; // copy rgb across alphalevel := (((mpixel^ and $FF0000) shr 16) + ((mpixel^ and $00FF00) shr 8) + (mpixel^ and $0000FF)) div 3; oPixel^ := ((alphalevel and $FF) shl ALPHA_SHIFT) or oPixel^; end; end; AlphaRGBImage.UnlockBits(obmd); bitmap.UnlockBits(bbmd); mask.UnlockBits(mbmd); result := true; end;