Cocoa touch 当用户挤压屏幕时,如何放大/缩小UIImage对象?

Cocoa touch 当用户挤压屏幕时,如何放大/缩小UIImage对象?,cocoa-touch,uiimage,uiimagejpegrepresentation,Cocoa Touch,Uiimage,Uiimagejpegrepresentation,我想在用户对我的应用程序执行标准收缩操作时放大/缩小UIImage对象。我目前正在使用UIImageView来显示我的图像,如果细节有任何帮助的话 我正在想办法,但到目前为止还没有这样的运气 有什么线索吗?最简单的方法是,如果你只想缩小缩小,就把你的图像放在UIWebView中(写少量html包装代码,引用你的图像,你基本上就完成了)。更复杂的方法是使用触摸开始、触摸移动和触摸结束来跟踪用户的手指,并适当调整视图的变换属性。请记住,您永远不会放大UIImage。永远 相反,您在显示UIImage

我想在用户对我的应用程序执行标准收缩操作时放大/缩小UIImage对象。我目前正在使用UIImageView来显示我的图像,如果细节有任何帮助的话

我正在想办法,但到目前为止还没有这样的运气


有什么线索吗?

最简单的方法是,如果你只想缩小缩小,就把你的图像放在
UIWebView
中(写少量html包装代码,引用你的图像,你基本上就完成了)。更复杂的方法是使用
触摸开始
触摸移动
触摸结束
来跟踪用户的手指,并适当调整视图的变换属性。

请记住,您永远不会放大
UIImage
。永远

相反,您在显示
UIImage
视图上放大和缩小

在这种特殊情况下,您可以选择创建一个带有自定义图形的自定义
UIView
来显示图像,一个为您显示图像的
UIImageView
,或者一个需要一些额外HTML来备份图像的
UIWebView


在所有情况下,您都需要实现
touchsbegind
touchsmoved
,等等,以确定用户正在尝试做什么(缩放、平移等)。

我以前使用过一个解决方案,它不需要您使用UIWebView

- (UIImage *)scaleAndRotateImage(UIImage *)image
{
    int kMaxResolution = 320; // Or whatever

    CGImageRef imgRef = image.CGImage;

    CGFloat width = CGImageGetWidth(imgRef);
    CGFloat height = CGImageGetHeight(imgRef);


    CGAffineTransform transform = CGAffineTransformIdentity;
    CGRect bounds = CGRectMake(0, 0, width, height);
    if (width > kMaxResolution || height > kMaxResolution) {
        CGFloat ratio = width/height;
        if (ratio > 1) {
            bounds.size.width = kMaxResolution;
            bounds.size.height = bounds.size.width / ratio;
        }
        else {
            bounds.size.height = kMaxResolution;
            bounds.size.width = bounds.size.height * ratio;
        }
    }

    CGFloat scaleRatio = bounds.size.width / width;
    CGSize imageSize = CGSizeMake(CGImageGetWidth(imgRef), CGImageGetHeight(imgRef));
    CGFloat boundHeight;
    UIImageOrientation orient = image.imageOrientation;
    switch(orient) {

        case UIImageOrientationUp: //EXIF = 1
            transform = CGAffineTransformIdentity;
            break;

        case UIImageOrientationUpMirrored: //EXIF = 2
            transform = CGAffineTransformMakeTranslation(imageSize.width, 0.0);
            transform = CGAffineTransformScale(transform, -1.0, 1.0);
            break;

        case UIImageOrientationDown: //EXIF = 3
            transform = CGAffineTransformMakeTranslation(imageSize.width, imageSize.height);
            transform = CGAffineTransformRotate(transform, M_PI);
            break;

        case UIImageOrientationDownMirrored: //EXIF = 4
            transform = CGAffineTransformMakeTranslation(0.0, imageSize.height);
            transform = CGAffineTransformScale(transform, 1.0, -1.0);
            break;

        case UIImageOrientationLeftMirrored: //EXIF = 5
            boundHeight = bounds.size.height;
            bounds.size.height = bounds.size.width;
            bounds.size.width = boundHeight;
            transform = CGAffineTransformMakeTranslation(imageSize.height, imageSize.width);
            transform = CGAffineTransformScale(transform, -1.0, 1.0);
            transform = CGAffineTransformRotate(transform, 3.0 * M_PI / 2.0);
            break;

        case UIImageOrientationLeft: //EXIF = 6
            boundHeight = bounds.size.height;
            bounds.size.height = bounds.size.width;
            bounds.size.width = boundHeight;
            transform = CGAffineTransformMakeTranslation(0.0, imageSize.width);
            transform = CGAffineTransformRotate(transform, 3.0 * M_PI / 2.0);
            break;

        case UIImageOrientationRightMirrored: //EXIF = 7
            boundHeight = bounds.size.height;
            bounds.size.height = bounds.size.width;
            bounds.size.width = boundHeight;
            transform = CGAffineTransformMakeScale(-1.0, 1.0);
            transform = CGAffineTransformRotate(transform, M_PI / 2.0);
            break;

        case UIImageOrientationRight: //EXIF = 8
            boundHeight = bounds.size.height;
            bounds.size.height = bounds.size.width;
            bounds.size.width = boundHeight;
            transform = CGAffineTransformMakeTranslation(imageSize.height, 0.0);
            transform = CGAffineTransformRotate(transform, M_PI / 2.0);
            break;

        default:
            [NSException raise:NSInternalInconsistencyException format:@"Invalid image orientation"];

    }

    UIGraphicsBeginImageContext(bounds.size);

    CGContextRef context = UIGraphicsGetCurrentContext();

    if (orient == UIImageOrientationRight || orient == UIImageOrientationLeft) {
        CGContextScaleCTM(context, -scaleRatio, scaleRatio);
        CGContextTranslateCTM(context, -height, 0);
    }
    else {
        CGContextScaleCTM(context, scaleRatio, -scaleRatio);
        CGContextTranslateCTM(context, 0, -height);
    }

    CGContextConcatCTM(context, transform);

    CGContextDrawImage(UIGraphicsGetCurrentContext(), CGRectMake(0, 0, width, height), imgRef);
    UIImage *imageCopy = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    return imageCopy;
}
该文章可在Apple Support上找到,网址为:

另一种简单的方法是将
UIImageView
放在
UIScrollView
中,您需要将滚动视图的contentSize设置为与
UIImageView的大小相同。将控制器实例设置为滚动视图的代理,并实现用于缩放的
视图CrollView:
滚动视图DiEndZooming:withView:atScale:
方法,以允许收缩缩放和图像平移。这就是Ben的解决方案所做的,只是以稍微轻量级的方式,因为您没有完整web视图的开销


您可能遇到的一个问题是,滚动视图中的缩放以应用于图像的变换形式出现。这可能会导致在高缩放因子下出现模糊。对于可以重新绘制的内容,您可以按照我的建议,在完成捏手势后提供更清晰的显示。hniels的解决方案可用于重新缩放图像。

下面的代码有助于在不使用UIScrollView的情况下缩放UIImageView:

-(void)HandlePinch:(UIPinchGestureRecognizer*)recognizer{
    if ([recognizer state] == UIGestureRecognizerStateEnded) {
        NSLog(@"======== Scale Applied ===========");
        if ([recognizer scale]<1.0f) {
            [recognizer setScale:1.0f];
        }
        CGAffineTransform transform = CGAffineTransformMakeScale([recognizer scale],  [recognizer scale]);
        imgView.transform = transform;
    }
}
-(void)HandlePinch:(UIPinchGestureRecognitor*)识别器{
if([Recognitor state]==UIgestureRecognitzerStateEnded){
NSLog(@“=============应用的比例==============”);

如果([recognizer scale]Shefali针对UIImageView的解决方案非常有效,但需要稍加修改:

- (void)pinch:(UIPinchGestureRecognizer *)gesture {
    if (gesture.state == UIGestureRecognizerStateEnded
        || gesture.state == UIGestureRecognizerStateChanged) {
        NSLog(@"gesture.scale = %f", gesture.scale);

        CGFloat currentScale = self.frame.size.width / self.bounds.size.width;
        CGFloat newScale = currentScale * gesture.scale;

        if (newScale < MINIMUM_SCALE) {
            newScale = MINIMUM_SCALE;
        }
        if (newScale > MAXIMUM_SCALE) {
            newScale = MAXIMUM_SCALE;
        }

        CGAffineTransform transform = CGAffineTransformMakeScale(newScale, newScale);
        self.transform = transform;
        gesture.scale = 1;
    }
}
-(void)pinch:(UIPinchGestureRecognizer*)手势{
如果(手势.state==UIGestureRecognitizerStateEnded
||手势.state==UIGestureRecognitzerStateChanged){
NSLog(@“sipple.scale=%f”,sipple.scale);
CGFloat currentScale=self.frame.size.width/self.bounds.size.width;
CGFloat newScale=currentScale*signature.scale;
if(新闻比例<最小比例){
新闻尺度=最小尺度;
}
如果(新闻比例>最大比例){
新闻尺度=最大尺度;
}
CGAffineTransform transform=CGAffineTransformMakeScale(newScale,newScale);
自我转换=转换;
1.scale=1;
}
}

(Shefali的解决方案有一个缺点,即挤压时不能连续缩放。此外,在开始新挤压时,当前图像缩放被重置。)

如其他人所述,最简单的解决方案是将UIImageView放入UIScrollView。我在Interface Builder.xib文件中这样做

在viewDidLoad中,设置以下变量。将控制器设置为UIScrollViewDelegate

- (void)viewDidLoad {
    [super viewDidLoad];
    self.scrollView.minimumZoomScale = 0.5;
    self.scrollView.maximumZoomScale = 6.0;
    self.scrollView.contentSize = self.imageView.frame.size;
    self.scrollView.delegate = self;
}
需要实现以下方法才能返回要缩放的imageView

- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView
{
    return self.imageView;
}
在iOS9之前的版本中,您可能还需要添加此空委托方法:

- (void)scrollViewDidEndZooming:(UIScrollView *)scrollView withView:(UIView *)view atScale:(CGFloat)scale
{
}

这篇文章很好地描述了如何做到这一点:

Shafali和JRV的答案扩展到包括平移和收缩缩放:

#define MINIMUM_SCALE 0.5
#define MAXIMUM_SCALE 6.0
@property CGPoint translation;


- (void)pan:(UIPanGestureRecognizer *)gesture {
    static CGPoint currentTranslation;
    static CGFloat currentScale = 0;
    if (gesture.state == UIGestureRecognizerStateBegan) {
        currentTranslation = _translation;
        currentScale = self.view.frame.size.width / self.view.bounds.size.width;
    }
    if (gesture.state == UIGestureRecognizerStateEnded || gesture.state == UIGestureRecognizerStateChanged) {

        CGPoint translation = [gesture translationInView:self.view];

        _translation.x = translation.x + currentTranslation.x;
        _translation.y = translation.y + currentTranslation.y;
        CGAffineTransform transform1 = CGAffineTransformMakeTranslation(_translation.x , _translation.y);
        CGAffineTransform transform2 = CGAffineTransformMakeScale(currentScale, currentScale);
        CGAffineTransform transform = CGAffineTransformConcat(transform1, transform2);
        self.view.transform = transform;
    }
}


- (void)pinch:(UIPinchGestureRecognizer *)gesture {
    if (gesture.state == UIGestureRecognizerStateEnded || gesture.state == UIGestureRecognizerStateChanged) {
//        NSLog(@"gesture.scale = %f", gesture.scale);

        CGFloat currentScale = self.view.frame.size.width / self.view.bounds.size.width;
        CGFloat newScale = currentScale * gesture.scale;

        if (newScale < MINIMUM_SCALE) {
            newScale = MINIMUM_SCALE;
        }
        if (newScale > MAXIMUM_SCALE) {
            newScale = MAXIMUM_SCALE;
        }

        CGAffineTransform transform1 = CGAffineTransformMakeTranslation(_translation.x, _translation.y);
        CGAffineTransform transform2 = CGAffineTransformMakeScale(newScale, newScale);
        CGAffineTransform transform = CGAffineTransformConcat(transform1, transform2);
        self.view.transform = transform;
        gesture.scale = 1;
    }
}
#定义最小刻度0.5
#定义最大_刻度6.0
@属性点转换;
-(无效)平移:(UIPangestureRecognitor*)手势{
静态转换;
静态CGFloat电流标度=0;
if(signature.state==UIGestureRecognitizerStateStart){
当前翻译=_翻译;
currentScale=self.view.frame.size.width/self.view.bounds.size.width;
}
如果(手势.state==UIGestureRecognizerStateEnded | |手势.state==UIGestureRecognizerStateChanged){
CGPoint translation=[手势翻译视图:self.view];
_translation.x=translation.x+currentTranslation.x;
_translation.y=translation.y+currentTranslation.y;
CGAffineTransform transform1=CGAffineTransformMakeTransform(_translation.x,_translation.y);
CGAffineTransform transform2=CGAffineTransformMakeScale(currentScale,currentScale);
CGAffineTransform transform=CGAffineTransformConcat(transform1,transform2);
self.view.transform=转换;
}
}
-(无效)按压:(UIPinchGestureRecognitor*)手势{
如果(手势.state==UIGestureRecognizerStateEnded | |手势.state==UIGestureRecognizerStateChanged){
//NSLog(@“sipple.scale=%f”,sipple.scale);
CGFloat currentScale=self.view.frame.size.width/self.view.bounds.size.width;
CGFloat newScale=currentScale*signature.scale;
if(新闻比例<最小比例){
新闻尺度=最小尺度;
}
如果(新闻比例>最大比例){
新闻尺度=最大尺度;
}
CG仿射四反式
@IBAction func scaleImage(sender: UIPinchGestureRecognizer) {
        self.view.transform = CGAffineTransformScale(self.view.transform, sender.scale, sender.scale)
        sender.scale = 1
    }
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
        view.backgroundColor = UIColor.blackColor()
    }