How to create a solid mask from a semi-transparent Bitmap?

I want to create the image on the right, from the one on the left.

insert the description of the image hereinsert the description of the image here

And I have the following structure:

var
  Image, Mask : TBitmap;
begin
  Mask := TBitmap.Create;
  Image := TBitmap.Create;
  Image.LoadFromFile('Yoshi.png');

// Criação da máscara aqui

end; 

The result I'm looking for must turn Mask into the image on the right to be shown in a form. Does anyone know what kind of method I should use? Mess with pixels directly? Or who knows there is another means through the canvas? Whoever has any idea, send it in.

Author: Guill, 2014-04-09

3 answers

A possible solution:

var
  Image, Mask : TBitmap;
  i,j,Color   : LongWord;
  rowI, rowM  : pRGBQuadArray;

begin
   Color := $FF0000;

   Image := TBitmap.Create;
   Image.LoadFromFile('Yoshi.png');

   Mask := TBitmap.Create;
   Mask.PixelFormat := pf32bit;
   Mask.Width  := Image.Width;
   Mask.Height := Image.Height;
   FOR j := 0 TO Mask.Height-1 DO
   begin
      rowM := Mask.Scanline[j];
      rowI := Mask.Scanline[j];
      FOR i := 0 TO Mask.Width-1 DO
      begin       
         rowM[i] := ( rowI[i] and $FF000000 ) + Color;
      end;
   end;
   // ...use a máscara...
end;

Compensates for including a test to make sure that Image is also pf32bit before creating the mask.

 5
Author: Bacco, 2014-04-13 22:05:49

Sorry for the delay in showing up, I've been very busy. It seems that we lacked a little research.

If the ideal is to work with PNG because of transparency, then working with Bitmap is not correct.

In fact, from Delphi 2009 with the introduction of Unicode it became possible to work with several other types of images, including PNG.

Here is a question in SOen about TPNGImage: how-do-I-get-pngs-to-work-in-d2009

@ Guill, did you handle the TPNGImage type yourself in this question:How to load semi-transparent PNG through a memory stream?.

Anyway, my humble method to treat this image:

procedure TMainForm.btnCriarMascaraClick(Sender: TObject);
var
  png: TPNGImage;
  x,y: TColor;
begin
  png := TPNGImage.Create;
  try
    png.Assign(imgOrig.Picture);

    for x := 0 to pred(png.Width) do
      for y := 0 to pred(png.Height) do
      begin
        if png.Pixels[x,y] <> png.TransparentColor then
        begin
          png.Pixels[x,y] := clLime;
        end;
      end;

    ImgDest.Picture.Assign(png);
  finally
    png.Free;
  end;
end;

Next, the result!

Treated image

It is necessary to have the unit pngimage. In XE3 it is in Vcl.Imaging.pngimage. However, if you load the image at desing time, the IDE itself Delphi already adds a reference to it.

 10
Author: Comunidade, 2017-05-23 12:37:35

Try using the canvas and FillRect property.

Something like:

procedure CreateBitmapSolidColor(Width,Height:Word;Color:TColor;const FileName : TFileName);
var
 bmp : TBitmap;
begin
 bmp:=TBitmap.Create;
 try
   bmp.PixelFormat:=pf24bit;
   bmp.Width:=Width;
   bmp.Height:=Height;
   bmp.Canvas.Brush.Color := Color;
   bmp.Canvas.FillRect(Rect(0,0,Height, Width));
   bmp.SaveToFile(FileName);
 finally
   bmp.Free;
 end;
end;

Https://stackoverflow.com/questions/5414929/how-i-create-bmp-files-bitmaps-of-a-single-color-using-delphi

 -1
Author: Marcelo de Andrade, 2017-05-23 12:37:31