【问题标题】:CGContext - scale and then crop image at pointCGContext - 在点缩放然后裁剪图像
【发布时间】:2015-02-15 08:33:14
【问题描述】:

与 Instagram 类似,我有一个方形裁剪视图 (UIScrollView),其中有一个 UIImageView。因此,用户可以在方形矩形内拖动纵向或横向图像(等于屏幕宽度),然后应在滚动偏移处裁剪图像。 UIImageView 设置为宽高比合适。 UIScrollView 内容大小设置为横向或纵向的比例因子,以便它以宽高比正确呈现。

当用户完成拖动后,我想根据给定的大小放大图像,比如说 1000x1000px 正方形,然后在滚动偏移处裁剪它(使用 [UIImage drawAtPoint:CGPoint]。

问题是我无法正确计算得到正确的偏移点。如果我在 6+ 上接近它,那么在 4S 上就会很远。

这是我的缩放和裁剪代码:

(UIImage *)squareImageFromImage:(UIImage *)image scaledToSize:(CGFloat)newSize {
CGAffineTransform scaleTransform;
CGPoint origin;

if (image.size.width > image.size.height) {
    //landscape
    CGFloat scaleRatio = newSize / image.size.height;
    scaleTransform = CGAffineTransformMakeScale(scaleRatio, scaleRatio);
    origin = CGPointMake((int)(-self.scrollView.contentOffset.x*scaleRatio),0);
} else if (image.size.width < image.size.height) {
    //portrait
    CGFloat scaleRatio = newSize / image.size.width;
    scaleTransform = CGAffineTransformMakeScale(scaleRatio, scaleRatio);
    origin = CGPointMake(0, (int)(-self.scrollView.contentOffset.y*scaleRatio));
} else {
    //square
    CGFloat scaleRatio = newSize / image.size.width;
    scaleTransform = CGAffineTransformMakeScale(scaleRatio, scaleRatio);
    origin = CGPointMake(0, 0);
}

UIGraphicsBeginImageContextWithOptions(size, YES, 0);
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextConcatCTM(context, scaleTransform);
[image drawAtPoint:origin];
image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();

return image;
}

例如,对于横向,如果我向左拖动滚动条,使图像一直向右裁剪,我的偏移量将接近 6+,但在 4S 上它将关闭约 150-200就CGPoint而言。

这是我设置滚动视图和图像视图的代码:

CGRect cropRect = CGRectMake(0.0f,0.0,SCREEN_WIDTH,SCREEN_WIDTH);
CGFloat ratio = (int)self.image.size.height/self.image.size.width;
CGRect r = CGRectMake(0.0,0.0,SCREEN_WIDTH,SCREEN_WIDTH);

if (ratio>1.00) {
    //portrait
    r = CGRectMake(0.0,0.0,SCREEN_WIDTH,(int)(SCREEN_WIDTH*ratio));
} else if (ratio<1.00) {
    //landscape
    CGFloat size = (int)self.image.size.width/self.image.size.height;
    cropOffset = (SCREEN_WIDTH*size)-SCREEN_WIDTH;
    r = CGRectMake(0.0,0.0,(int)(SCREEN_WIDTH*size),SCREEN_WIDTH);
}

NSLog(@"r.size.height == %.4f",r.size.height);
self.scrollView.frame = cropRect;
self.scrollView.contentSize = r.size;

self.imageView = [[UIImageView alloc] initWithFrame:r];
self.imageView.backgroundColor = [UIColor clearColor];
self.imageView.contentMode = UIViewContentModeScaleAspectFit;
self.imageView.image = self.image;

[self.scrollView addSubview:self.imageView];

【问题讨论】:

    标签: ios objective-c uiscrollview uiimageview crop


    【解决方案1】:

    裁剪数学可能很棘手。自从我不得不处理这个问题以来已经有一段时间了,所以希望我能指出你正确的方向。这是来自 Pixology 的一段代码,它从 UIScrollView 中获取缩放的可见矩形。我认为这里缺少的成分可能是zoomScale

    CGRect visibleRect;
    visibleRect.origin = _scrollView.contentOffset;
    visibleRect.size = _scrollView.bounds.size;
    // figure in the scale
    float theScale = 1.0 / _scrollView.zoomScale;
    visibleRect.origin.x *= theScale;
    visibleRect.origin.y *= theScale;
    visibleRect.size.width *= theScale;
    visibleRect.size.height *= theScale;
    

    您可能还需要计算设备屏幕比例:

    CGFloat screenScale = [[UIScreen mainScreen] scale];
    

    看看你能从这些信息中走多远,然后告诉我。

    【讨论】:

    • 滚动没有缩放,所以这不是一个因素。它只是向右/向左或向上/向下滚动。所以它总是1.0。 CGContextConcatCTM 正在放大图像,因此滚动偏移量必须有一个乘数。乘数是我想不出来的。
    猜你喜欢
    • 1970-01-01
    • 2019-11-17
    • 1970-01-01
    • 2016-08-29
    • 2017-06-18
    • 1970-01-01
    • 1970-01-01
    • 2012-07-21
    • 2013-02-15
    相关资源
    最近更新 更多