保存和恢复 UIImageView 的旋转和大小

发布于 2024-12-17 20:05:29 字数 1804 浏览 0 评论 0原文

我正在开发一个应用程序,除其他外,它需要处理图像视图,即旋转、调整大小、移动它们......将其保存在核心数据模型中,并根据需要恢复它们。

旋转和缩放是通过手势识别器执行的。 我在这里读到,在变换之后,您不能使用图像视图框架来检索真实的矩形,您必须使用边界和中心。

我尝试了几种保存/恢复视图框架、视图层框架、视图边界、视图层边界的组合,但没有成功。这是我最好的方法,但是如果旋转角度不为0,则恢复的图像视图会更大(尽管只是)(角度值越高,恢复的图像尺寸越大)。

我知道存储帧值并在恢复边界时使用它们并不连贯,但我由此得到了“最佳”结果。

这是用于保存图像视图设置的代码:

- (void)updateModelCoords {

    CGFloat angle = atan2f(myImageView.transform.b, myImageView.transform.b);
    CGRect frame = [myImageView.layer frame];
    [myModel setW:[[NSNumber alloc] initWithFloat:frame.size.width]];
    [myModel setH:[[NSNumber alloc] initWithFloat:frame.size.height]];
    [myModel setX:[[NSNumber alloc] initWithFloat:frame.origin.x]];
    [myModel setY:[[NSNumber alloc] initWithFloat:frame.origin.y]];
    [myModel setCenterX:[[NSNumber alloc] initWithFloat:[myImageView center].x]];
    [myModel setCenterY:[[NSNumber alloc] initWithFloat:[myImageView center].y]];
    [myModel setAngle:[[NSNumber alloc] initWithFloat:angle]];

    // db save stuff...
}

这是用于恢复图像视图设置的代码:

- (void) restoreImage {
    float angle = [[myModel angle] floatValue];
    CGAffineTransform transform = CGAffineTransformMakeRotation(angle);
    myImageView.transform = transform;
    CGRect bounds = [myImageView.layer bounds];
    bounds.size.width = [[myModel w] floatValue];
    bounds.size.height = [[myModel h] floatValue];
    bounds.origin.x = [[myModel x] floatValue];
    bounds.origin.y = [[myModel y] floatValue];
    [myImageView.layer setBounds:bounds];
    CGPoint center = CGPointMake([[myModel centerX] floatValue], [[myModel centerY] floatValue]);
    [myImageView setCenter:center];
}

我将蓝色边框应用到图像视图图层作为辅助。方向和位置相同,但恢复后形状是正方形,而保存前是矩形。

提示将非常受欢迎。

让我知道是否需要更多代码来澄清,

非常感谢

I'm developing an app which needs, among other things, handle image views, that is, rotate, resize, move them... save that in a core data model, and restore them on demand.

Rotation and scale is performed via gesture recognizers.
I have read here that after a transform you can't use image view frame in order to retrieve real rect, you have to use bounds and center instead.

I have tried several combinations saving/restoring view frame, view layer frame, view bounds, view layer bounds, with no luck. This is my best approach, but the imageview restored is bigger (though only) if rotation angle is not 0 (the higher angle value, the bigger restored image size is).

I understand storing frame values and use them while restoring bounds is not coherent, but I'm getting my "best" results with this.

This is the code used to save the image view settings:

- (void)updateModelCoords {

    CGFloat angle = atan2f(myImageView.transform.b, myImageView.transform.b);
    CGRect frame = [myImageView.layer frame];
    [myModel setW:[[NSNumber alloc] initWithFloat:frame.size.width]];
    [myModel setH:[[NSNumber alloc] initWithFloat:frame.size.height]];
    [myModel setX:[[NSNumber alloc] initWithFloat:frame.origin.x]];
    [myModel setY:[[NSNumber alloc] initWithFloat:frame.origin.y]];
    [myModel setCenterX:[[NSNumber alloc] initWithFloat:[myImageView center].x]];
    [myModel setCenterY:[[NSNumber alloc] initWithFloat:[myImageView center].y]];
    [myModel setAngle:[[NSNumber alloc] initWithFloat:angle]];

    // db save stuff...
}

This is the code used to restore the image view settings:

- (void) restoreImage {
    float angle = [[myModel angle] floatValue];
    CGAffineTransform transform = CGAffineTransformMakeRotation(angle);
    myImageView.transform = transform;
    CGRect bounds = [myImageView.layer bounds];
    bounds.size.width = [[myModel w] floatValue];
    bounds.size.height = [[myModel h] floatValue];
    bounds.origin.x = [[myModel x] floatValue];
    bounds.origin.y = [[myModel y] floatValue];
    [myImageView.layer setBounds:bounds];
    CGPoint center = CGPointMake([[myModel centerX] floatValue], [[myModel centerY] floatValue]);
    [myImageView setCenter:center];
}

I apply a blue border to the image view layer as a helper. Orientation and position are the same, but the shape is a square after restoring, while it's a rectangle before saving.

Hints will be very wellcome.

Let me know if more code is needed in order to clarify

Thank you so much

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

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

发布评论

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

评论(1

阿楠 2024-12-24 20:05:30

我遇到了同样的问题,在浪费了四个小时后,我想我能够解决这个问题。关键点是不要存储框架、存储边界加载边界。加载时顺序也非常重要。

  1. 边界
  2. 中心
  3. 变换

这就是我所做的:

-(void)writeImageState {
NSMutableDictionary *dict = [[NSMutableDictionary alloc] init];
[dict setObject:NSStringFromCGAffineTransform(self.transform) forKey:@"transform"];
[dict setObject:NSStringFromCGPoint(self.center) forKey:@"center"];
[dict setObject:NSStringFromCGRect(self.bounds) forKey:@"bounds"];

[NSKeyedArchiver archiveRootObject:dict toFile:forUser.imageTransformationPath];
[dict release];
}
-(void)readImageState {
id obj = [NSKeyedUnarchiver unarchiveObjectWithFile:forUser.imageTransformationPath];
if(obj == nil) return;

CGAffineTransform transformed = CGAffineTransformFromString([obj objectForKey:@"transform"]);
CGPoint centered = CGPointFromString([obj objectForKey:@"center"]);
CGRect rect = CGRectFromString([obj objectForKey:@"bounds"]);

self.bounds = rect;
self.center = centered;
self.transform = transformed;
}

让我们知道它是否对您有用。

I was running into same issue and after wasting my four hours, I think I am able to fix the issue. The key point is DO NOT store frame, Store BOUNDS and Load BOUNDS. Also order is VERY VERY important while loading.

  1. Bounds
  2. Center
  3. Transform

Here it is, what I did:

-(void)writeImageState {
NSMutableDictionary *dict = [[NSMutableDictionary alloc] init];
[dict setObject:NSStringFromCGAffineTransform(self.transform) forKey:@"transform"];
[dict setObject:NSStringFromCGPoint(self.center) forKey:@"center"];
[dict setObject:NSStringFromCGRect(self.bounds) forKey:@"bounds"];

[NSKeyedArchiver archiveRootObject:dict toFile:forUser.imageTransformationPath];
[dict release];
}
-(void)readImageState {
id obj = [NSKeyedUnarchiver unarchiveObjectWithFile:forUser.imageTransformationPath];
if(obj == nil) return;

CGAffineTransform transformed = CGAffineTransformFromString([obj objectForKey:@"transform"]);
CGPoint centered = CGPointFromString([obj objectForKey:@"center"]);
CGRect rect = CGRectFromString([obj objectForKey:@"bounds"]);

self.bounds = rect;
self.center = centered;
self.transform = transformed;
}

Let us know it worked for you or not.

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