【问题标题】:Flutter - How to rotate an image around the center with canvasFlutter - 如何使用画布围绕中心旋转图像
【发布时间】:2018-07-13 10:37:30
【问题描述】:

我正在尝试实现一个自定义画家,可以在画布上绘制图像(缩小版),并且绘制的图像可以旋转和缩放。

我知道要缩放图像,我必须使用 scale 方法缩放画布。

现在的问题是如何在其中心(或任何其他点)旋转缩放的图像。 canvas的rotate方法只允许在左上角旋转。

Here is my implementation that can be extended

【问题讨论】:

  • 看看这个example
  • @RaoufRahiche 我需要用画布绘制旋转
  • 你能解决这个问题吗? @NatwarSingh
  • 还没有尝试过,但我能够用Transform.rotateTransform.translate 小部件解决我的问题。

标签: dart flutter


【解决方案1】:

这可以通过移动坐标空间来实现,如图 1 所示。 平移是 C1 和 C2 之间的坐标差,与图 2 中的 A 和 B 之间的坐标完全相同。 通过一些几何公式,我们可以计算出所需的平移并生成旋转图像,如下所示

ui.Image rotatedImage({ui.Image image, double angle}) {
  var pictureRecorder = ui.PictureRecorder();
  Canvas canvas = Canvas(pictureRecorder);

  final double r = sqrt(image.width * image.width + image.height * image.height) / 2;
  final alpha = atan(image.height / image.width);
  final beta = alpha + angle;
  final shiftY = r * sin(beta);
  final shiftX = r * cos(beta);
  final translateX = image.width / 2 - shiftX;
  final translateY = image.height / 2 - shiftY;
  canvas.translate(translateX, translateY);
  canvas.rotate(angle);
  canvas.drawImage(image, Offset.zero, Paint());

  return pictureRecorder.endRecording().toImage(image.width, image.height);
}

alpha, beta, angle 都是弧度。

这里是demo app的repo

【讨论】:

    【解决方案2】:

    Had the same problem, 解决方案就是在三行中制作自己的旋转方法

    void rotate(Canvas canvas, double cx, double cy, double angle) {
      canvas.translate(cx, cy);
      canvas.rotate(angle);
      canvas.translate(-cx, -cy);
    }
    

    因此,我们首先将画布移向您要绕其旋转的点。然后我们沿着左上角(Flutter 的默认值)旋转,它在坐标空间中是您想要的枢轴,然后将画布放回所需的位置,并应用旋转。方法非常高效,平移只需要4次加法,旋转成本和原来的一样。

    【讨论】:

    • 这是最干净的方法!如果添加一些数学细节来解释代码会更好。
    • 谢谢!这对我来说很好!对于那些想知道的人,我试图使用 Transform 来旋转元素。我最终应用的转换是:Matrix4.identity()..translate(Constants.elementCardHalfSize)..rotateY(initialRotateX)..translate(-Constants.elementCardHalfSize)
    • 什么是 cx 和 cy?
    • @Scorb 你可以叫他们xy如果你愿意,我叫他们cxcy,因为我希望我的支点在中心,因此中心x和中心是的
    • 我建议不要翻译回之前的位置,而是在翻译之前推荐save(),完成后推荐restore()
    【解决方案3】:

    如果您不想围绕图像中心旋转图像,您可以使用这种方式。您不必关心画布相对于图像旋转的偏移量,因为在绘制图像后画布会移回其原始位置。

    void rotate(Canvas c, Image image, Offset focalPoint, Size screenSize, double angle) {
      c.save();
      c.translate(screenSize.width/2, screenSize.height/2);
      c.rotate(angle);
      // To rotate around the center of the image, focal point is the
      // image width and height divided by 2
      c.drawImage(image, focalPoint*-1, Paint());
      c.translate(-screenSize.width/2, -screenSize.height/2);
      c.restore();
    }
    

    【讨论】:

      猜你喜欢
      • 2020-08-31
      • 1970-01-01
      • 1970-01-01
      • 2020-06-06
      • 1970-01-01
      • 2014-10-10
      • 2013-08-04
      • 2011-05-10
      • 2013-12-08
      相关资源
      最近更新 更多