【问题标题】:Scaling with cairo causes painted image to appear on a different position使用 cairo 进行缩放会导致绘制的图像出现在不同的位置
【发布时间】:2021-05-15 13:12:20
【问题描述】:

我有一个非常简单的设置: 一切都发生在 GtkDrawingArea 的覆盖“绘制”方法中,该方法放置在滚动窗口的视口内。绘图区域大小为 1000000x1000000。它以绘图区域的中心为中心绘制一个 pixbuf:

cairo_set_source_surface(cr, pixbufSurface, xPos, yPos); // middle center

cairo_pattern_set_filter(cairo_get_source(cr), CAIRO_FILTER_FAST);

cairo_paint_with_alpha(cr, transp);

问题是我必须使用cairo_scale() 来简单地缩放绘制的pixbuf,同时仍将其保持在相同的位置,但它会将其移动得很远。缩放是通过scaleFactor 变量进行的。我怀疑我将不得不移动转换矩阵,并且我强制使用了一些值:

  1. cairo_translate(cr, -500000, -500000); 在 scaleFactor 为 2 时有效
  2. cairo_translate(cr, -1500000, -1500000); 在 scaleFactor 为 4 时有效

但我不知道这些数字是如何相互关联的。

【问题讨论】:

  • 如果你的绘图区域是 1000000x1000000,并且你在中心,这是否意味着你在 500000x500000?如果然后以 2 倍进行缩放,则中间移动到 1000000x1000000 是有意义的。我猜你不是从中间向外扩展,而是从角落向外扩展。
  • 是的,就是中心。你的意思是?我第一次以 2 倍缩放时,如果我转换为 -500000x-500000,它会起作用,但如果我第一次以 4 倍缩放,它会在我转换为 -1500000x-1500000 时起作用 不知道如何制定这个虽然

标签: c gtk scale transformation cairo


【解决方案1】:

如果您首先位于 (x,y) 位置,然后使用 z 进行缩放,然后您将位于 (zx, zy)。

你在中心,所以在 (500000, 500000),所以如果你用 2 缩放,你最终会在 (1000000, 1000000),如果你用 4 缩放,你最终会在 ( 2000000,2000000)

所以你可以用 ((1-z) * 500000, (1-z) * 500000) 转换回来

cairo_scale(cr, scaleFactor, scaleFactor); 
cairo_translate(cr, 500000 * (1-scaleFactor), 500000 * (1-scaleFactor));

您也可以先使用 (-500000, - 500000) 进行转换,然后进行缩放,然后再使用 (500000, 500000) 进行转换,但这仅适用于某些情况。

cairo_translate(cr, -500000, -500000);
cairo_scale(cr, scaleFactor, scaleFactor); 
cairo_translate(cr, 500000, 500000);

只需检查其中任何一个是否有效,或者您是否遇到其他问题。

【讨论】:

  • 那么cairo_translate(cr, 500000 * z, 500000 * z); cairo_scale(cr, z, z); cairo_translate(cr, 500000 * (1-z), 500000 * (1-z));?
  • 好的,用什么方法?哪一个?
  • 两者都没有,pixbuf 只是消失了(它被移动到绘图区域的某处),而且由于它太大,导航和找到它的确切位置并不容易。
  • 但如果 scaleFactor=2 则 cairo_translate(cr, 500000 * (1-scaleFactor), 500000 * (1-scaleFactor)); 与您的 cairo_translate(cr, -500000, -500000); 示例完全相同
  • 如果 translate 函数位于比例之前,它可以工作,但在您的示例中正好相反?
【解决方案2】:

基本上是 Gnoom 所说的,还有一些补充:

  1. 在绘制 pixbuf 之前执行 cairo_scale(cr, z, z)
  2. 对于每个被绘制的 pixbuf,在渲染之前添加 cairo_translate(cr, (xpos*(1-z)/z), (ypos*(1-z)/z));
  3. 渲染后cairo_translate(cr, -(xpos*(1-z)/z), -(ypos*(1-z)/z));

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-06-16
    • 2019-09-17
    • 2011-08-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-10
    • 2012-10-06
    相关资源
    最近更新 更多