我正在尝试实现一个自定义画家,该画家可以在画布上绘制图像(缩小版本),并且可以旋转和缩放绘制的图像。
我知道要缩放图像,我必须使用scale方法缩放画布。
现在的问题是如何在其中心(或任何其他点)旋转缩放后的图像。画布的旋转方法仅允许在左上角旋转。
答案 0 :(得分:3)
这可以通过移动坐标空间来实现,如图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,角度都以弧度表示。
这是demo app
的仓库答案 1 :(得分: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();
}
答案 2 :(得分:1)
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);
}