Как правильно отобразить TBitmap с альфа-каналом на TImage?

У меня есть TBitmap, который содержит полупрозрачное изображение с альфа-каналом (в этом примере я получил его из TPngImage).

var
  SourceBitmap: TBitmap;
  PngImage: TPngImage;
begin
  PngImage := TPngImage.Create();
  SourceBitmap := TBitmap.Create();
  try
    PngImage.LoadFromFile('ImgSmallTransparent.png');
    SourceBitmap.Assign(PngImage);
    SourceBitmap.SaveToFile('TestIn.bmp');
    imgSource.Picture.Assign(SourceBitmap);
  finally
    PngImage.Free();
    SourceBitmap.Free();
  end;

Когда я сохраняю этот TBitmap в TestIn.bmp файл и открываю его в любом средстве просмотра изображений, я вижу прозрачность. Но когда я назначаю его TImage, прозрачные пиксели отображаются как черные (TImage имеет Transparent = True).

Как правильно отображать TBitmap с прозрачностью на TImage?


person Andrew    schedule 12.07.2013    source источник
comment
Скопируйте и вставьте части вашего реального кода.   -  person TLama    schedule 12.07.2013
comment
Если ни один из базовых элементов управления wincontrols не имеет Doublebuffered = true и изображение НЕ установлено на прозрачное, все работает для меня так, как ожидалось.   -  person bummi    schedule 12.07.2013


Ответы (1)


Показанный вами код отлично работает в моей системе, если я использую Transparent = false для imgSource.
Я могу воспроизвести поведение с черными пикселями, если загружу растровое изображение из файла.

Различные настройки влияют на отображение введите описание изображения здесь введите описание изображения здесь  введите описание изображения здесь  введите описание изображения здесь

procedure TForm3.SetAlphaFormatClick(Sender: TObject);
begin
  if SetAlphaFormat.Checked then
    ToggleImage.Picture.Bitmap.alphaformat := afDefined
  else
    ToggleImage.Picture.Bitmap.alphaformat := afIgnored;
end;

procedure TForm3.SetImageTransparentClick(Sender: TObject);
begin
  ToggleImage.Transparent := SetImageTransparent.Checked;
  Image1.Transparent := SetImageTransparent.Checked;
end;

procedure TForm3.LoadPngTransform2BitmapClick(Sender: TObject);
Const
  C_ThePNG = 'C:\temp\test1.png';
  C_TheBitMap = 'C:\temp\TestIn.bmp';
var
  SourceBitmap, TestBitmap: TBitmap;
  pngImage: TPngImage;
begin

  Image1.Transparent := SetImageTransparent.Checked;
  pngImage := TPngImage.Create;
  SourceBitmap := TBitmap.Create;
  TestBitmap := TBitmap.Create;
  try
    pngImage.LoadFromFile(C_ThePNG);
    SourceBitmap.Assign(pngImage);

    {v1 with this version without the marked* part, I get the behavoir you described
      SourceBitmap.SaveToFile(C_TheBitMap);
      TestBitmap.LoadFromFile(C_TheBitMap);
      TestBitmap.PixelFormat := pf32Bit;
      TestBitmap.HandleType := bmDIB;
      TestBitmap.alphaformat := afDefined;  //*
      Image1.Picture.Assign(TestBitmap);
    }
    //> v2
    SourceBitmap.SaveToFile(C_TheBitMap);
    SourceBitmap.PixelFormat := pf32Bit;
    SourceBitmap.HandleType :=  bmDIB;
    SourceBitmap.alphaformat := afDefined;
    Image1.Picture.Assign(SourceBitmap);
    //< v2
  finally
    pngImage.Free;
    SourceBitmap.Free;
    TestBitmap.Free;
  end;
end;
person bummi    schedule 12.07.2013