Как нарисовать полупрозрачное изображение на форме?

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

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

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

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

TImage

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


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


person Little Helper    schedule 11.05.2011    source источник
comment
Я не понимаю, как можно использовать изображение PNG в элементе управления Delphi 7 TImage. Delphi 7 не поддерживает PNG ...   -  person Andreas Rejbrand    schedule 11.05.2011
comment
хммммм. Он загружается как PNGObject.   -  person Little Helper    schedule 11.05.2011
comment
D7 не поддерживает png. Вы установили сторонний компонент. Почему вы против сторонних компонентов?   -  person David Heffernan    schedule 11.05.2011
comment
Ладно, с комплектующими для третьей стороны! ооооо. Извините, я использую элементы управления TNT Unicode. TTntImage.   -  person Little Helper    schedule 11.05.2011
comment
@Robrok: Ваш английский не проблема, но немного сбивает с толку, когда вы говорите, что используете TImage, а на самом деле используете TntImage!   -  person Andreas Rejbrand    schedule 11.05.2011
comment
Спасибо!! Но давай с проблемой!   -  person Little Helper    schedule 11.05.2011
comment
@Robrok: На самом деле, я работаю над этим, пока мы говорим!   -  person Andreas Rejbrand    schedule 11.05.2011
comment
Я ищу в Интернете, но безрезультатно.   -  person Little Helper    schedule 11.05.2011
comment
@Robrok: Я нашел решение.   -  person Andreas Rejbrand    schedule 11.05.2011
comment
@Robrok Используете ли вы TNT, это означает, что вы отказались от написания собственного элемента управления кнопками Unicode? Если так, это был хороший ход!   -  person David Heffernan    schedule 11.05.2011
comment
Я создал свою собственную кнопку с именем TSuperButton. : D С 3 состояниями кнопок. Ну наконец то!!!   -  person Little Helper    schedule 11.05.2011


Ответы (3)


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

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

person Andreas Rejbrand    schedule 11.05.2011
comment
Да, это работает. Но если я хочу обвести форму рамкой? - person Little Helper; 11.05.2011
comment
Я хочу создать форму со скином. - person Little Helper; 11.05.2011
comment
Хороший! Кстати, ваш код работает с обычным объявлением функции gdi, то есть windows.AlphaBlend(), не нужно объявлять константы, запись и функцию .. - person Sertac Akyuz; 12.05.2011
comment
@Sertac: Мне это хорошо известно, но я не уверен, что AlphaBlend объявлен в Windows.pas, который поставляется со старой Delphi 7, версией OP для Delphi. Вдобавок объявление AlphaBlend в Windows.pas в Delphi 2009 (моя версия Delphi) очень "некрасиво": function AlphaBlend(DC: HDC; p2, p3, p4, p5: Integer; DC6: HDC; p7, p8, p9, p10: Integer; p11: TBlendFunction): BOOL; stdcall; Но я думаю, мне следовало написать об этом сноску. - person Andreas Rejbrand; 12.05.2011
comment
И почему в мире каждый пост, который я делаю на ТАК, получает отрицательные голоса?!?! - person Andreas Rejbrand; 12.05.2011

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

person ivo    schedule 16.11.2012

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

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


(источник: rejbrand.se )

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

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

person Andreas Rejbrand    schedule 11.05.2011
comment
растровые изображения Windows часто имеют альфа-каналы - person David Heffernan; 11.05.2011
comment
@David: Да, но я не уверен, сможет ли Delphi 7 TImage справиться с этим. Может это? - person Andreas Rejbrand; 11.05.2011
comment
что вы подразумеваете под часто Дэвидом? Очень немногие инструменты поддерживают файлы .BMP с альфа-каналами, так как часто, как вы полагаете, в сохраненных окнах .BMP они есть? Я бы сказал, что они есть примерно у 0,0001% из них. Кроме, может быть, на вашем компьютере. - person Warren P; 11.05.2011
comment
@andreas нет, я очень в этом сомневаюсь. TBitmap Delphi очень запоздала с альфа-поддержкой. - person David Heffernan; 11.05.2011
comment
Я могу сохранить это изображение в формате BMP, но оно будет черным. :( - person Little Helper; 11.05.2011
comment
@warren, кто что сказал о файлах? Как вы думаете, как на вашем компьютере представлены значки 32bpp xp? - person David Heffernan; 11.05.2011
comment
@Robrok: Тот, что был назван «Form4» выше? Тогда вы, вероятно, используете очень плохой конвертер форматов файлов изображений. Попробуйте Paint. Но все же BMP и альфа-каналы не очень хорошо сочетаются друг с другом, поэтому я бы, вероятно, не использовал BMP на вашем месте. - person Andreas Rejbrand; 11.05.2011
comment
BMP или PNG, что угодно. Я учусь и хочу нарисовать прозрачное изображение на форме. - person Little Helper; 11.05.2011
comment
Мне нравятся альфа-скины, но они не бесплатные. И старые версии плохие. - person Little Helper; 11.05.2011
comment
@David: OP что-то сказал о файлах. Это сайт, на котором мы отвечаем на вопросы пользователей. Или мы пытаемся. - person Warren P; 11.05.2011