Delphi 2006: назначение PNG для TImage во время выполнения теряет альфа-прозрачность - PullRequest
5 голосов
/ 21 марта 2011

Delphi 2006 TImage не совсем поддерживает PNG.Чтобы на моих формах были изображения с альфа-прозрачностью, я должен загружать их во время выполнения.Я могу загрузить их во время разработки, но они не выживают, я думаю, потому что PNG не сохраняются в файле DFM.Я уверен, что в последней версии Delphi это все просто, но я не могу обновить прямо сейчас.

В любом случае, я загружал их во время выполнения с помощью:

Image1.Picture.Assign (PngImageCollection1.Items [0].PNGImage) ;

Компонент PNGImageCollection содержит все мои PNG разных размеров (они создаются и загружаются во время разработки), и я назначаю их соответствующим TImages в событии FormCreate.

Это работало нормально, пока ябыла проблема, когда я пытался повторно использовать одно из этих изображений где-то еще после того, как оно было использовано в форме.Я обнаружил, что в результате присвоения TPicture было установлено пустое изображение.Это происходило в подпрограмме TPicture.ForceType, в которой AFAICT проверяет тип FGraphic, и, если это не нужный тип, он освобождает FGraphic и создает новый экземпляр запрошенного типа.

ОК.Поэтому, немного почесавшись, я вижу, что, возможно, мне действительно следовало бы сделать следующее:

Image1.Picture.Bitmap.Assign (PngImageCollection1.Items [0].PNGImage) ; 

Это добилось цели, так как Assign не засорял изображение, но изображение теперь отображается сполупрозрачные биты как непрозрачные, то есть:

TImage when assigned with Image1.Picture.Bitmap.Assign

вместо:

TImage when assigned with Image1.Picture.Assign

Как можно получить это изображение для отображенияальфа-прозрачные биты правильно?(и дополнительный вопрос: является ли Image1.Picture.Bitmap.Assign верным способом сделать это?).

Вот код более подробно:

В коде, где у меня былопроблема «повторного использования» TImage, последовательность была:
При создании формы:

LogoImage.Picture.Assign (PngImageCollection1.Items [0].PNGImage) ; 

(PNGIMage - это логотип компании, LogoImage1 - на главной форме).

На печатизаголовок отчета:

procedure PrintLogo (Report : TBaseReport) ;

var
    X1, Y1, LogoHeightMM    : Double ;

begin
with Report do
    begin
    LogoHeightMM  := CalcGraphicHeight (LogoWidthMM, MainForm.LogoImage.Picture.Graphic) ;
    X1            := PageWidth - MarginRight - LogoWidthMM ;
    Y1            := SectionBottom - LogoHeightMM ;
    PrintBitmapRect (X1, Y1, X1 + LogoWidthMM, Y1 + LogoHeightMM, MainForm.LogoImage.Picture.Bitmap) ;
    end ;
end ;

При первом вызове подпрограммы для печати логотипа она выполняется без ошибок, но LogoImage .Picture остается очищенным после вызова PrintBitmapRect.При следующем вызове процедуры заголовка печати произойдет сбой вызова CalcGraphicHeight, поскольку ширина и высота изображения равны нулю.

Изменение Picture.Assign на Picture.Bitmap.Assign фиксирует RTE в заголовкерутина печати, но когда я перенес такое же «исправление» на другие статические изображения, назначенные из PNG (как шестерни выше), я потерял канал aplha.

1 Ответ

5 голосов
/ 21 марта 2011

Вы не показываете действительно релевантную часть вашего кода: как вы повторно используете изображение, которое заставило бы его иметь определенный тип.

Когда вы назначаете TImage объект TPngObject, изображение на изображении содержит объект png. Только когда вы запрашиваете конкретное растровое изображение, оно заставляет графическое изображение иметь растровое изображение. Например, это,

  Bmp.Assign(Image1.Picture.Bitmap);

заставит Image1 иметь растровое изображение, если его изображение было объектом png, оно будет освобождено. Пока это,

  Bmp.Assign(Image1.Picture.Graphic);

не заставит Image1 иметь растровое изображение, объект png выполнит назначение и останется там.

Растровые изображения Delphi (по крайней мере, до последних версий) не поддерживают альфа-каналы, поэтому не следует использовать Image1.Picture.Bitmap.Assign(.. для частично прозрачных изображений.


Кстати, вместо того, чтобы повторно использовать изображение на изображении, вы, вероятно, можете использовать изображение из вашей коллекции изображений PNG в качестве источника.

...