如何拉伸一个具有任意不透明度的cairo gdk pixbuf模式区域?

时间:2012-08-24 06:23:08

标签: cairo freepascal lazarus gdk

如何使用用户定义的不透明度拉伸gdk pixbuf的区域到cairo表面?

我正在尝试编写一个用于处理位图的跨平台界面,并希望将alpha混合添加到我的cairo stretch绘制方法中。我现在所做的工作得很好,但是我无法想出将alpha混合模拟成一系列cairo / gdk apis的方法,它有点像微软的AlphaBlend函数。

到目前为止我所拥有的是:

procedure TGtkBitmap.Draw(const Source: TRect; Canvas: TCanvas;
  const Dest: TRect; Alpha: Byte = $FF);
var
  D: PGdkDrawable;
  C: Pcairo_t;
  M: cairo_matrix_t;
begin
  if FBuffer = nil then
    Exit;
  if (WidthOf(Source) < 1) or (WidthOf(Dest) < 1) then
    Exit;
  if (HeightOf(Source) < 1) or (HeightOf(Dest) < 1) then
    Exit;
  D := TGtk2DeviceContext(Canvas.Handle).Drawable;
  C := gdk_cairo_create(D);
  gdk_cairo_set_source_pixbuf(C, FBuffer, 0, 0);
  cairo_matrix_init_identity(@M);
  cairo_matrix_translate(@M, Source.Left, Source.Top);
  cairo_matrix_scale(@M, WidthOf(Source) / WidthOf(Dest),
    HeightOf(Source) / HeightOf(Dest));
  cairo_matrix_translate(@M, -Dest.Left, -Dest.Top);
  cairo_pattern_set_matrix(cairo_get_source(C), @M);
  cairo_rectangle(C, Dest.Left, Dest.Top, WidthOf(Dest), HeightOf(Dest));
  // what cairo functions can I combine here to vary
  // the opacity of the pattern fill using Alpha argument?
  cairo_fill(C);
  cairo_destroy(C);
end;

一切正常,但我不确定如何使用pix buff模式进行alpha混合。我可以想象一种方法,包括创建第二个cairo表面,用用户定义的不透明度绘制整个pixbuf,然后使用新表面为第一个表面创建图案,这些都有点混乱,可能比某些东西慢得多我很高兴。

这是我目前工作的video recording。我想从熟悉cairo的人那里知道,我可以在上面的例程中插入什么来设置pixbuf源模式的alpha级别?

1 个答案:

答案 0 :(得分:1)

来自cairo邮件列表的Chris Wilson提供了这种完美运行的解决方案。

替换:

cairo_fill(C);

使用:

cairo_clip(C);
cairo_paint_with_alpha(C, Alpha / $FF);

感谢来自cairo邮件列表的Chris Wilson!