Конференция "Media" » GDI+. Получить ARGB изображение из буфера обмена [D7]
 
  • neversleep (31.03.12 16:13) [0]
    САБЖ. С обычными RGB изображениями проблем нет:

    // С помощью GetClipboardData(CF_BITMAP) получаю HBITMAP.

    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;


    Но у изображений с альфа-каналом вместо прозрачности чёрный цвет. Как это исправить?
  • ~AQUARIUS~ (31.03.12 21:57) [1]
    BITMAP не поддерживает альфа-канал. Ну т.е. для 32-битного дополнительный байт есть, но его использование не регламентировано - любое приложение вольно делать с ним, что желает нужным. Если у вас какое-то другое приложение копирует часть изображения с альфа-каналом, то вероятно оно кладет в буффер HBITMAP, но без альфаканала, и еще данные в каком-то своем формате. Поищите программу InsideClipboard и посмотрите, что на самом деле находится в буффере обмена
  • neversleep (31.03.12 23:07) [2]
    Копирование может производиться из любого приложения. Задача отследить копирование изображения и сохранить его таким какое оно есть, конечно используя только стандартные форматы буфера обмена.

    Любопытно, что GIMP каким-то образом распознаёт прозрачность, с учётом того что в буфере лежит только CF_BITMAP/CF_DIB, при вставке прозрачная часть изображения остаётся неизменной.
  • ~AQUARIUS~ (31.03.12 23:18) [3]
    Попробуйте доставать из буффера CF_DIB вместо CF_BITMAP - возможно, альфа-канал портится системными функциями при создании HBITMAP; создавайте GPBitmap напрямую на массив пикселей
  • Cobalt © (01.04.12 00:13) [4]
    Насколько я в курсе, GIMP - приложение с открытыми исходными кодами, так что можно их посмотреть.
  • neversleep (01.04.12 09:36) [5]

    > Попробуйте доставать из буффера 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 - приложение с открытыми исходными
    > кодами, так что можно их посмотреть.

    Знаю, но пока оставлю этот вариант :)
  • neversleep (01.04.12 11:02) [6]
    Нашёл... Bitmap.RotateFlip(RotateNoneFlipY);
  • None (09.04.12 08:54) [7]

    >>  BI := GlobalLock(DIB);
    >>  Bits := Pointer(Integer(BI) + SizeOf(BI^));


    Что-то у меня получается что должно быть +SizeOf(tagBITMAPINFOHEADER)
    Странно...
  • neversleep (12.04.12 06:40) [8]

    > Что-то у меня получается что должно быть +SizeOf(tagBITMAPINFOHEADER)
    > Странно...

    Вы абсолютно правы, позже заметил ошибку, просто тут не отписался.
 
Конференция "Media" » GDI+. Получить ARGB изображение из буфера обмена [D7]
Есть новые Нет новых   [134428   +39][b:0][p:0.002]