使用 CGAffineTransform 从 UIImageView 保存 UIImage

发布于 2024-09-06 19:20:18 字数 2111 浏览 5 评论 0 原文

我在 UIScrollView 中有一个 UIImageView,我使用户能够对其执行任意数量的翻转和旋转操作。我已经完成了这一切,允许用户缩放、平移、翻转和旋转。现在我希望能够将最终图像保存为 png 格式。

然而,它正在努力解决这个问题......

我已经看到了很多与此类似的其他帖子,但大多数只需要应用单个转换,例如旋转,例如 从旋转的 UIImageView 创建 UIImage

我想应用用户“创建”的任何转换,这将是一系列翻转和旋转连接在一起

当用户应用各种旋转、翻转等时,我使用 CGAffineTransformConcat 存储连接的变换。例如,当它们旋转时,我会这样做:

CGAffineTransform newTransform = CGAffineTransformMakeRotation(angle);
self.theFullTransform = CGAffineTransformConcat(self.theFullTransform, newTransform);
self.fullPhotoImageView.transform = self.theFullTransform;

以下方法是迄今为止我使用完整变换创建 UIImage 的最佳方法,但是图像总是翻译在错误的位置。例如图像是“偏移”的。我的猜测是与使用 CGAffineTransformTranslate 或 CGContextDrawImage 中设置的错误边界有关。

有人有什么想法吗?这似乎比我想象的要困难得多......

- (UIImage *) translateImageFromImageView: (UIImageView *) imageView withTransform:(CGAffineTransform) aTransform
{
    UIImage *rotatedImage;

    // Get image width, height of the bounding rectangle
    CGRect boundingRect = CGRectApplyAffineTransform(imageView.bounds, aTransform);

    // Create a graphics context the size of the bounding rectangle
    UIGraphicsBeginImageContext(boundingRect.size);
    CGContextRef context = UIGraphicsGetCurrentContext();

    CGAffineTransform transform = CGAffineTransformIdentity;

    //I think this translaton is the problem?

    transform = CGAffineTransformTranslate(transform, boundingRect.size.width/2, boundingRect.size.height/2);
    transform = CGAffineTransformScale(transform, 1.0, -1.0);
    transform = CGAffineTransformConcat(transform, aTransform);

    CGContextConcatCTM(context, transform);

    // Draw the image into the context

    // or the boundingRect is incorrect here?

    CGContextDrawImage(context, boundingRect, imageView.image.CGImage);

    // Get an image from the context
    rotatedImage = [UIImage imageWithCGImage: CGBitmapContextCreateImage(context)];

    // Clean up
    UIGraphicsEndImageContext();
    return rotatedImage;
}

I have a UIImageView within a UIScrollView which I have enabled the user to perform any number of flip and rotation operations on. I have this all working which allows the user to zoom, pan, flip and rotate. Now I want to be able to save the final image out to a png.

however it is doing my head in trying to work this out...

I have seen quite a few other posts similar to this but most only require applying a single transform such as a rotation eg Creating a UIImage from a rotated UIImageView

I would like to apply any transform that the user has "created" which will be a series of flip and rotations concatenated togethers

As the user is applying various rotations, flips etc, I store the concatenated transform using CGAffineTransformConcat. For example when they rotate I do:

CGAffineTransform newTransform = CGAffineTransformMakeRotation(angle);
self.theFullTransform = CGAffineTransformConcat(self.theFullTransform, newTransform);
self.fullPhotoImageView.transform = self.theFullTransform;

The following method is the best I have gotten so far for creating a UIImage with the full transform however the image is always translated in the wrong place. Eg the image is "offset". Which my guess is either related to using the wrong bounds being set in in CGAffineTransformTranslate or CGContextDrawImage.

Does anyone have any ideas? This seems a lot harder that I thought it should be...

- (UIImage *) translateImageFromImageView: (UIImageView *) imageView withTransform:(CGAffineTransform) aTransform
{
    UIImage *rotatedImage;

    // Get image width, height of the bounding rectangle
    CGRect boundingRect = CGRectApplyAffineTransform(imageView.bounds, aTransform);

    // Create a graphics context the size of the bounding rectangle
    UIGraphicsBeginImageContext(boundingRect.size);
    CGContextRef context = UIGraphicsGetCurrentContext();

    CGAffineTransform transform = CGAffineTransformIdentity;

    //I think this translaton is the problem?

    transform = CGAffineTransformTranslate(transform, boundingRect.size.width/2, boundingRect.size.height/2);
    transform = CGAffineTransformScale(transform, 1.0, -1.0);
    transform = CGAffineTransformConcat(transform, aTransform);

    CGContextConcatCTM(context, transform);

    // Draw the image into the context

    // or the boundingRect is incorrect here?

    CGContextDrawImage(context, boundingRect, imageView.image.CGImage);

    // Get an image from the context
    rotatedImage = [UIImage imageWithCGImage: CGBitmapContextCreateImage(context)];

    // Clean up
    UIGraphicsEndImageContext();
    return rotatedImage;
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

二智少女 2024-09-13 19:20:18

偏移量是否可预测,就像图像的一半一样,还是取决于 aTransform?

struct CGAffineTransform {
  CGFloat a, b, c, d;
  CGFloat tx, ty;
};

如果是后者,请在使用之前将 aTransform 中的 tx 和 ty 设置为零。

Is the offset predictable, like always half the image, or does it depend on aTransform?

struct CGAffineTransform {
  CGFloat a, b, c, d;
  CGFloat tx, ty;
};

If the latter, set tx and ty to zero in aTransform before using it.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文