ie: I have one bitmap all yellow. Then I have a second bitmap, the mask is
such that a white area will let all the yellow come through. Then there are
different shades of grey, and that should be combined with the yellow to
make a darker, grayer yellow, and the black area lets no yellow come though.
This would work the same using a blue or orange bitmap. Just darker blue or
orange, etc..
I tried all the options with copymode, starting with either bitmap and
copying the other over it, but have no success.
Is this possible? Any ideas how?
Thanks for any assistance.
Terry.
Take a look at "True Transparent Image with Masking" by Robert Vivrette at
http://www.undu.com/DN970101/00000022.htm
FInd this and other Delphi Graphics Algorithm links at
http://www.efg2.com/lab/library/Delphi/Graphics/Algorithms.htm
efg
_________________________________
efg's Computer Lab: www.efg2.com/lab
Delphi Books: www.efg2.com/lab/TechBooks/Delphi.htm
Earl F. Glynn E-Mail: Earl...@att.net
Overland Park, KS USA
I assume you are using a 16-bit per pixel image or more. In this case
you could use the Scanline property to walk through the pixels of each
bitmap, combine them, and store the result in a third bitmap (or in
one of the source bitmaps).
procedure Clamp(var A : Integer);
begin
if A < 0 then
A := 0;
end;
DestR := SourceR - (WhiteR - MaskR);
Clamp(DestR);
DestG := SourceG - (WhiteG - MaskG);
Clamp(DestG);
DestB := SourceB - (WhiteB - MaskB);
Clamp(DestB);
Of course, depending on the color depth (16,24,32 bpp) of the bitmap
you are using, the way you extract and recombine these RGB values is
different.
If you are using an 8-bit image destination, you need a ramped palette
to make the calculations easy. An 8 bit mask is fine though.
With an 8 bit mask, you could make index 0 be white and 255 be black.
DestR := SourceR - MaskIndex;
Clamp(DestR);
DestG := SourceG - MaskIndex;
Clamp(DestG);
DestB := SourceB - MaskIndex;
Clamp(DestB);
Here is a small example of an 8-bit black mask. The source and
desitination bitmaps are 32 bpp, so the bitshifting deals with this
color depth only. For 24 or 16 bpp images, you will need to modify
the code. Just drop a button on a blank form and assign the event
handler.
function Clamp0(a : Integer) : Integer;
begin
if(a < 0) then
Result := 0
else
Result := a;
end;
procedure TForm1.Button1Click(Sender: TObject);
var
Source, Mask, Dest : TBitmap;
i, j, k : Integer;
MaskPixel : PByte;
SourcePixel, DestPixel : PLongint;
Palette : PLogPalette;
Entry : PPaletteEntry;
begin
Source := TBitmap.Create;
with Source do begin
Height := 100;
Width := 100;
HandleType := bmDIB;
PixelFormat := pf32bit;
end;
Mask := TBitmap.Create;
with Mask do begin
Height := 100;
Width := 100;
HandleType := bmDIB;
PixelFormat := pf8bit;
end;
Dest := TBitmap.Create;
with Dest do begin
Height := 100;
Width := 100;
HandleType := bmDIB;
PixelFormat := pf32bit;
end;
GetMem(Palette, SizeOf(TLogPalette) + SizeOf(TPaletteEntry) *
255);
with Palette^ do begin
palVersion := $300;
palNumEntries := 256;
Entry := @palPalEntry[0];
for i := 0 to 255 do begin
Entry.peRed := 255 - i;
Entry.peBlue := 255 - i;
Entry.peGreen := 255 - i;
Entry.peFlags := 0;
Inc(Entry);
end;
end;
Mask.Palette := CreatePalette(Palette^);
FreeMem(Palette);
Mask.Canvas.Brush.Color := PALETTEINDEX(0);
for i := 0 to 15 do begin
Mask.Canvas.Pen.Color := PALETTEINDEX((15-i) * 15);
Mask.Canvas.Rectangle(i,i,101-i,101-i);
end;
Source.Canvas.Brush.Color := clYellow;
Source.Canvas.Pen.Style := psClear;
Source.Canvas.Rectangle(0,0,101,101);
Canvas.Draw(150,0,Source);
Canvas.Draw(300,0,Mask);
for i := 0 to 99 do begin
MaskPixel := Mask.Scanline[i];
SourcePixel := Source.Scanline[i];
DestPixel := Dest.Scanline[i];
for j := 0 to 99 do begin
DestPixel^ := 0;
for k := 0 to 2 do
DestPixel^ := DestPixel^ Or
(Clamp0(((SourcePixel^ shr (8 * k)) And
$FF)-MaskPixel^) shl (8 * k));
Inc(MaskPixel);
Inc(SourcePixel);
Inc(DestPixel);
end;
end;
Canvas.Draw(0,0,Dest);
Source.Free;
Mask.Free;
Dest.Free;
end;
On Wed, 9 Dec 1998 22:29:49 -0800, "Terry Haan"
<terr...@palsoft.bc.ca> wrote:
>I am trying to "mask" a bitmap
>
>ie: I have one bitmap all yellow. Then I have a second bitmap, the mask is
>such that a white area will let all the yellow come through. Then there are
>different shades of grey, and that should be combined with the yellow to
>make a darker, grayer yellow, and the black area lets no yellow come though.
>This would work the same using a blue or orange bitmap. Just darker blue or
>orange, etc..
>
>I tried all the options with copymode, starting with either bitmap and
>copying the other over it, but have no success.
>
>Is this possible? Any ideas how?
>
>Thanks for any assistance.
>Terry.
>
>
>
Chris Hill
hil...@cs.purdue.edu