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

13

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

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 should turn Mask into the right image to be displayed on a form. Does anyone know what kind of method I should use? Stir directly with pixels? Or maybe there's another medium through the canvas ? Anyone who has any idea, send it there.

    
asked by anonymous 09.04.2014 / 19:23

3 answers

5

One 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;
  

It is worthwhile to include a test to make sure that Image is also pf32bit before creating the mask.

    
13.04.2014 / 22:49
10

Sorry for the delay in attending, I've been very busy. It seems that we lacked a bit of 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's a question in SOen on TPNGImage : how-to-get-pngs-to-work-in-d2009

@Guill, you even dealt with the TPNGImage type in your question: # .

At last, 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;

Then the result!

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

    
15.04.2014 / 15:22
-1

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;
  

link

    
13.04.2014 / 22:19