问题
I want to a draw a translucent image on a Delphi form, but for some reason it is not working.
Here is the original PNG (border is semi transparent):
I load the image in a TImage
object:
Image1.Transparent := True;
Form1.Color := clWhite;
Form1.TransparentColor := True;
Form1.TransparentColorValue := clWhite;
The application:
The image isn't translucent. I am working with a BMP image that contains the alpha channel. Am I missing something?
回答1:
I found a solution that will let you draw a BMP image with an alpha channel onto a form using only the Windows API:
const
AC_SRC_OVER = 0;
AC_SRC_ALPHA = 1;
type
BLENDFUNCTION = packed record
BlendOp,
BlendFlags,
SourceConstantAlpha,
AlphaFormat: byte;
end;
function WinAlphaBlend(hdcDest: HDC; xoriginDest, yoriginDest, wDest, hDest: integer;
hdcSrc: HDC; xoriginSrc, yoriginSrc, wSrc, hSrc: integer; ftn: BLENDFUNCTION): LongBool;
stdcall; external 'Msimg32.dll' name 'AlphaBlend';
procedure TForm4.FormClick(Sender: TObject);
var
hbm: HBITMAP;
bm: BITMAP;
bf: BLENDFUNCTION;
dc: HDC;
begin
hbm := LoadImage(0,
'C:\Users\Andreas Rejbrand\Skrivbord\RatingCtrl.bmp',
IMAGE_BITMAP,
0,
0,
LR_LOADFROMFILE);
if hbm = 0 then
RaiseLastOSError;
try
if GetObject(hbm, sizeof(bm), @bm) = 0 then RaiseLastOSError;
dc := CreateCompatibleDC(0);
if dc = 0 then RaiseLastOSError;
try
if SelectObject(dc, hbm) = 0 then RaiseLastOSError;
bf.BlendOp := AC_SRC_OVER;
bf.BlendFlags := 0;
bf.SourceConstantAlpha := 255;
bf.AlphaFormat := AC_SRC_ALPHA;
if not WinAlphaBlend(Canvas.Handle,
10,
10,
bm.bmWidth,
bm.bmHeight,
dc,
0,
0,
bm.bmWidth,
bm.bmHeight,
bf) then RaiseLastOSError;
finally
DeleteDC(dc);
end;
finally
DeleteObject(hbm);
end;
end;
Using The GIMP, I converted the PNG image
found here to a 32-bit RGBA bitmap, found here, and the result is very good:
回答2:
Why not try do draw your png onto new image with regular bmp. Draw what you want onto image 2 and redraw /or assign/ all to your image 1 when finish. Must works...
回答3:
The TransparentColorValue
approach cannot possibly work, because this only works with images in which a single colour represents full transparency. [In addition, you are toying with the form's transparent colour instead of image's transparent colour!] The above PNG image is supposed to have an alpha channel, so it's not like every pixel is either shown or transparent -- instead, each pixel has an opacity between 0 and 1 (0.37, for instance). That is, in addition to the R, G, and B components of each pixel, there is an 'alpha' component A.
The above image appears to be corrupt, however. A 'correct' PNG is shown below:
You can try to blend the above one onto different backgrounds, and you will find that the shadow blends nicely.
So, if one has a 'correct' PNG, how to draw it onto a form? Well, that is going to be very difficult in your case, since Delphi 7 does not support PNG images. It only supports BMP images, and these normally do not have alpha channels.
来源:https://stackoverflow.com/questions/5964701/how-to-draw-a-translucent-image-on-a-form