Как нарисовать полупрозрачное изображение на форме? - PullRequest
5 голосов
/ 11 мая 2011

Я хочу нарисовать полупрозрачное изображение на форме Delphi, но по какой-то причине оно не работает.

Вот исходный PNG (граница полупрозрачная):Transparent border

Я загружаю изображение в TImage объект:

Image1.Transparent := True;
Form1.Color := clWhite;
Form1.TransparentColor := True;
Form1.TransparentColorValue := clWhite;

TImage

Приложение:
Application


Изображение не является полупрозрачным.Я работаю с изображением BMP, которое содержит альфа-канал.Я что-то упустил?

Ответы [ 3 ]

11 голосов
/ 11 мая 2011

Я нашел решение, которое позволит вам рисовать изображение BMP с альфа-каналом на форме, используя только 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;

Используя GIMP, я преобразовал изображение PNG

http://privat.rejbrand.se/RatingCtrl.png

найдено здесь для 32-битной карты RGBA, найдено здесь , и результат очень хороший:

http://privat.rejbrand.se/gdiblend1.png http://privat.rejbrand.se/gdiblend2.png http://privat.rejbrand.se/gdiblend3.png

1 голос
/ 16 ноября 2012

Почему бы не попробовать нарисовать свой png на новом изображении с обычным bmp. Нарисуйте то, что вы хотите, на изображении 2 и перерисовайте / или назначьте / все вашему изображению 1, когда закончите. Должно работать ...

1 голос
/ 11 мая 2011

Подход TransparentColorValue не может работать, потому что он работает только с изображениями, в которых один цвет представляет полную прозрачность. [Кроме того, вы играете с формы прозрачного цвета вместо изображения прозрачного цвета!] Предполагается, что вышеприведенное изображение PNG имеет альфа-канал , поэтому это не значит, что каждый пиксель либо показан, либо прозрачен - вместо этого каждый пиксель имеет непрозрачность от 0 до 1 (например, 0,37). То есть, в дополнение к компонентам R, G и B каждого пикселя, есть альфа-компонент A.

Однако приведенное выше изображение выглядит поврежденным. «Правильный» PNG показан ниже:

http://privat.rejbrand.se/RatingCtrl.png

Вы можете попытаться смешать вышеперечисленное на разных фонах, и вы обнаружите, что тень прекрасно сочетается.

Итак, если у вас есть «правильный» PNG, как нарисовать его на форме? Что ж, это будет очень сложно в вашем случае, поскольку Delphi 7 не поддерживает изображения PNG. Он поддерживает только изображения BMP, и обычно они не имеют альфа-каналов.

...