W := SourceBitmap.Width;
H := SourceBitmap.Height;
MonoScanLineSize := SourceSize.X div 8;
if SourceSize.X mod 8 <> 0 then
Inc (MonoScanLineSize);
if MonoScanLineSize mod 4 <> 0 then { Compensate for scan line boundary }
MonoScanLineSize := (MonoScanLineSize and not 3) + 4;
MonoPixels := AllocMem(MonoScanLineSize * SourceSize.Y); { AllocMem is used because it initializes to zero }
try
GetMem (Pixels, W * H * 4);
try
FillChar (Info, SizeOf(Info), 0);
with Info do begin
with Header do begin
biSize := SizeOf(TBitmapInfoHeader);
biWidth := W;
biHeight := -H; { negative number makes it a top-down DIB }
biPlanes := 1;
biBitCount := 32;
{biCompression := BI_RGB;} { implied due to the FillChar zeroing }
end;
{Colors[0] := clBlack;} { implied due to the FillChar zeroing }
Colors[1] := clWhite;
end;
DC := CreateCompatibleDC(0);
GetDIBits (DC, SourceBitmap.Handle, 0, H, Pixels, PBitmapInfo(@Info)^,
DIB_RGB_COLORS);
DeleteDC (DC);
for I := 0 to High(TransColors) do
if TransColors = -1 then
TransColors := Pixels[W * (H-1)] and $FFFFFF;
{ ^ 'and' operation is necessary because the high byte is undefined }
MonoPixel := MonoPixels;
for Y := SourceOffset.Y to SourceOffset.Y+SourceSize.Y-1 do begin
StartMonoPixel := MonoPixel;
CurBit := 7;
Pixel := @Pixels[(Y * W) + SourceOffset.X];
for X := 0 to SourceSize.X-1 do begin
for I := 0 to High(TransColors) do
if Pixel^ and $FFFFFF = Cardinal(TransColors) then begin
{ ^ 'and' operation is necessary because the high byte is undefined }
MonoPixel^ := MonoPixel^ or (1 shl CurBit);
Break;
end;
Dec (CurBit);
if CurBit < 0 then begin
Inc (Integer(MonoPixel));
CurBit := 7;
end;
Inc (Integer(Pixel), SizeOf(Longint)); { proceed to the next pixel }
end;
Integer(MonoPixel) := Integer(StartMonoPixel) + MonoScanLineSize;
end;
finally
FreeMem (Pixels);
end;
{ Write new bits into a new HBITMAP, and assign this handle to MaskBitmap }
MaskBmp := CreateBitmap(SourceSize.X, SourceSize.Y, 1, 1, nil);
with Info.Header do begin
biWidth := SourceSize.X;
biHeight := -SourceSize.Y; { negative number makes it a top-down DIB }
biPlanes := 1;
biBitCount := 1;
end;
DC := CreateCompatibleDC(0);
SetDIBits (DC, MaskBmp, 0, SourceSize.Y, MonoPixels, PBitmapInfo(@Info)^,
DIB_RGB_COLORS);
DeleteDC (DC);
finally
FreeMem (MonoPixels);
end;
MaskBitmap.Handle := MaskBmp;
end;