Sorry for the delay to attend, I’ve been very busy. It seems that we have lacked a little research.
If the ideal is to work with PNG
for the sake of transparency, then work with Bitmap
is not correct.
In fact, from the Delphi 2009
with the introduction of Unicode
it has become possible to work with several other types of images, including the PNG
.
Here’s a question on Soen about the TPNGImage
: how-do-i-get-pngs-to-work-in-d2009
@Guill, you yourself dealt with the Tpngimage type in your question:How to load semi-transparent PNG via a memory stream?.
Anyway, my humble method of treating that 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 up, the result!
It is necessary to have the unit
pngimage
. In XE3 is in Vcl.Imaging.pngimage
.
However, if you load the image at desing time, the Delphi IDE itself already adds a reference to it.
I know very little about it, but semi-transparent images are images without background? I don’t know how Delphi recognizes that kind of pixel, and I haven’t even tested it here. But any pixel color other than the value recognized as background color (in the case of the transparent pixel) you substitute by the color you want the mask. Wouldn’t that be the way.. ?
– user3628
I think if it is to manipulate at the pixel level, it would be there. But I also never dealt directly with pixels in Delphi. I expect some direction with this question. And if by chance someone has a less "coded" way of doing. I would like to know.
– Guill
I tested here and soon the first pixel (0,0) was already recognized as white (#ffffff), so it would not be a perfect formula to try to change the color of everything other than
clWhite
.– user3628
You would need to get the Alpha value of each pixel. And preserve it if it is 0. But I don’t know how to access this value.
– Guill
Well, it’s really not my thing. See if you can find something in this link. Good luck!
– user3628
Hi. It’s been (a long time since I programmed in Delphi, so I won’t even try to prepare an answer. But @Tiago’s suggestion is the easiest way to do it. It’s called Limiarisation (Thresholding), because in practice you set a threshold value and turn the original image into binary making each pixel 0 if the original pixel is below the threshold and 255 if it is above. Here are some ways to access (
bmp.Canvas.Pixels[x,y]
seems the easiest): http://ksymeon.blogspot.com.br/2010/02/getdibits-vs-scanline-vs-pixels-in.html– Luiz Vieira
I hope the links will help you, but if you can solve your question please don’t forget to add an answer yourself to serve as a future reference to those who need it most. :)
– Luiz Vieira
@Guill whatever the path used, try not to use 0 and 1 if possible, but the full alpha, otherwise the edges will be serrated.
– Bacco
@Guill, will the mask be used to make custom window format? Then you will probably have to convert into regions.
– Bacco
@Bacco No. The mask will simply be displayed.
– Guill