-
САБЖ. С обычными RGB изображениями проблем нет:
function SaveAsPNG(const FileName: WideString; Bitmap: HBITMAP): Boolean;
var
GPBitmap: TGPBitmap;
Quality: DWORD;
EncoderParams: EncoderParameters;
begin
Result := False;
GPBitmap := TGPBitmap.Create(Bitmap, 0);
try
Quality := 100;
EncoderParams.Count := 1;
with EncoderParams.Parameter[0] do
begin
Guid := EncoderQuality;
NumberOfValues := 1;
Type_ := EncoderParameterValueTypeLong;
Value := @Quality;
end;
Result := GPBitmap.Save(FileName, GIUD_Encoder_PNG, @EncoderParams) = Ok;
finally
GPBitmap.Free;
end;
end;
Но у изображений с альфа-каналом вместо прозрачности чёрный цвет. Как это исправить?
-
BITMAP не поддерживает альфа-канал. Ну т.е. для 32-битного дополнительный байт есть, но его использование не регламентировано - любое приложение вольно делать с ним, что желает нужным. Если у вас какое-то другое приложение копирует часть изображения с альфа-каналом, то вероятно оно кладет в буффер HBITMAP, но без альфаканала, и еще данные в каком-то своем формате. Поищите программу InsideClipboard и посмотрите, что на самом деле находится в буффере обмена
-
Копирование может производиться из любого приложения. Задача отследить копирование изображения и сохранить его таким какое оно есть, конечно используя только стандартные форматы буфера обмена.
Любопытно, что GIMP каким-то образом распознаёт прозрачность, с учётом того что в буфере лежит только CF_BITMAP/CF_DIB, при вставке прозрачная часть изображения остаётся неизменной.
-
Попробуйте доставать из буффера CF_DIB вместо CF_BITMAP - возможно, альфа-канал портится системными функциями при создании HBITMAP; создавайте GPBitmap напрямую на массив пикселей
-
Насколько я в курсе, GIMP - приложение с открытыми исходными кодами, так что можно их посмотреть.
-
> Попробуйте доставать из буффера CF_DIB вместо CF_BITMAP > - возможно, альфа-канал портится системными функциями при > создании HBITMAP; создавайте GPBitmap напрямую на массив > пикселей
Сделал, проблема с прозрачностью решилась, но возникла другая - изображение получается отраженным по вертикали: http://i31.fastpic.ru/big/2012/0401/21/d1d7b037f90a9a7d7d90f0623862ef21.png
procedure TForm1.FormPaint(Sender: TObject);
var
DIB: THandle;
BI: PBitmapInfo;
Bits: Pointer;
Bitmap: TGPBitmap;
Graphics: TGPGraphics;
begin
if (not IsClipboardFormatAvailable(CF_DIB)) then
Exit;
DIB := 0;
if (OpenClipboard(0)) then
begin
DIB := GetClipboardData(CF_DIB);
CloseClipboard;
end;
if (DIB = 0) then
Exit;
BI := GlobalLock(DIB);
Bits := Pointer(Integer(BI) + SizeOf(BI^));
Graphics := TGPGraphics.Create(Canvas.Handle);
Bitmap := TGPBitmap.Create(BI^.bmiHeader.biWidth, BI^.bmiHeader.biHeight, BI^.bmiHeader.biWidth * 4, PixelFormat32bppARGB, Bits);
try
Graphics.DrawImage(Bitmap, 0, 0);
finally
Graphics.Free;
Bitmap.Free;
end;
GlobalUnlock(DIB);
end;
> Насколько я в курсе, GIMP - приложение с открытыми исходными > кодами, так что можно их посмотреть.
Знаю, но пока оставлю этот вариант :)
-
Нашёл... Bitmap.RotateFlip(RotateNoneFlipY);
-
>> BI := GlobalLock(DIB); >> Bits := Pointer(Integer(BI) + SizeOf(BI^));
Что-то у меня получается что должно быть +SizeOf(tagBITMAPINFOHEADER) Странно...
-
> Что-то у меня получается что должно быть +SizeOf(tagBITMAPINFOHEADER) > Странно...
Вы абсолютно правы, позже заметил ошибку, просто тут не отписался.
|