Рисование прозрачного TMetaFile на TCanvas в Delphi - PullRequest
2 голосов
/ 22 октября 2010

Я хотел бы нарисовать прозрачный TMetaFile на холсте, используемом для печати водяного знака.

Проблема в том, что функция AlphaBlend не распознает TMetaFile.Handle в качестве источника, поскольку она ожидает дескриптор холста.

Я создал 32-битное растровое изображение с прозрачностью, но рисование на нем заставит белый фон, поэтому на Canvas вы можете видеть прямоугольник с альфа-смешиванием.Как нарисовать прозрачный TMetaFile на экране / принтере Canvas?

TMetaFile, безусловно, прозрачный, я тестировал его на простой веб-странице с использованием IE с нестандартным цветом фона.Исходный код:

procedure TPainter.DrawAlpha(ACanvas: TCanvas; ARect: TRect; AGraphic: TMetafile; AAlpha: Byte);
var
  bmp: TBitmap;
  bf: BLENDFUNCTION;
begin
  bmp := TBitmap.Create;
  try
    bmp.PixelFormat := pf32bit;
    bmp.SetSize(ARect.Right - ARect.Left, ARect.Bottom - ARect.Top);
    bmp.Transparent := True;
    bmp.Canvas.Brush.Color := clNone;
    bmp.Canvas.Brush.Style := bsClear;
    bmp.Canvas.FillRect(Rect(0, 0, ARect.Right - ARect.Left, ARect.Bottom - ARect.Top));
    bmp.Canvas.StretchDraw(Rect(0, 0, ARect.Right - ARect.Left, ARect.Bottom - ARect.Top), AGraphic);

    bf.BlendOp := AC_SRC_OVER;
    bf.BlendFlags := 0;
    bf.SourceConstantAlpha := 230;
    bf.AlphaFormat := 0;

    AlphaBlend(
      ACanvas.Handle,
      ARect.Left,
      ARect.Top,
      ARect.Right - ARect.Left,
      ARect.Bottom - ARect.Top,
      bmp.Canvas.Handle,
      0,
      0,
      ARect.Right - ARect.Left,
      ARect.Bottom - ARect.Top,
      bf
    );
  finally
    bmp.Free;
  end;
end;

1 Ответ

4 голосов
/ 22 октября 2010

Если вы проверите официальную документацию MSDN, вы получите следующее заявление: http://msdn.microsoft.com/en-us/library/dd183351(VS.85).aspx

Произошла ошибка (и функция возвращает FALSE), если контекст устройства источника идентифицирует расширенный контекст устройства метафайла.

Моим первым предположением было то, что, даже если MSDN говорит только о контексте исходного устройства, ваш код никогда не будет работать с AlphaBlend, который предназначен для работы между двумя растровыми изображениями.

Но после второго исследования в типах перечисления метафайла есть выделенный тип записи TEMRAlphaBlend. Так что должно работать как положено.

Что вы используете для отображения метафайла? Нам понадобится код, который вы используете для отображения метафайла здесь.

Мой совет - сохранить ваш метафайл в файл emf, а затем использовать emfexplorer для проверки его контекста.

Мы разработали модуль с открытым исходным кодом, названный SynGdiPlus, для рисования метафайла с использованием GDI +, следовательно, с сглаживанием, в чистом Delphi. Но мы еще не реализовали тип записи TEMRAlphaBlend. Если вам было бы интересно иметь в своем приложении рисование сглаживания, я мог бы взглянуть на его реализацию.

...