Objective-C:从 UIScrollView 获取缩放的裁剪图像

Posted

技术标签:

【中文标题】Objective-C:从 UIScrollView 获取缩放的裁剪图像【英文标题】:Objective-C: Get Scaled Cropped Image from UIScrollView 【发布时间】:2015-10-22 19:59:36 【问题描述】:

场景

我正在开发一个照片共享应用程序。该应用程序需要允许用户在将图像发送到服务器之前裁剪图像。我正在使用 UIScrollViewUIImageView 子视图,其中包含我希望用户裁剪的图像。

我的尝试

我曾尝试通过 *** 上的一些解决方案来做到这一点,但它们涉及在用户缩放后截取 UIScrollView 帧的屏幕截图。这不起作用的原因是,当用户在 iPhone 5(320x320,屏幕宽度的完美正方形)上截屏时,当该照片上传并显示在 iPhone 6 Plus(更大的屏幕尺寸)上时,图像将被像素化。

问题

如何在UIScrollView 内获得可能缩放为 3000x3000 的图像并提取与UIScrollView 框架 (320x320) 尺寸相同的图像 缩放为 640x640 不会丢失图像分辨率?

插图

【问题讨论】:

【参考方案1】:

首先,你可以继承UIScrollView,里面包含一个UIImageView,初始化这个UIScrollView和UIImageView,分配一个图像实例给UIImageView,这样它就可以显示了。

- (instancetype)initWithFrame:(CGRect)frame
    self = [super initWithFrame:frame];
    if (self) 
        self.delegate = self;
        self.maximumZoomScale = 4.0f;
        self.showsHorizontalScrollIndicator = NO;
        self.showsVerticalScrollIndicator = NO;
        [self loadImageView:frame];
    
    return self;


- (void) loadImageView:(CGRect) frame 
    if (!_imageView) 
        _imageView = [[UIImageView alloc] initWithFrame:CGRectMake(0,(frame.size.height-frame.size.width)/2, frame.size.width, frame.size.width)];
        _imageView.contentMode = UIViewContentModeScaleAspectFit;
        _imageView.center = self.center;
        [self addSubview:_imageView];
    


//call this menthod to assginment image to imageView
- (void)showImage:(UIImage*)image
    self.imageView.image = image;
    [self handleImageType];

其次,可以在viewForZoomingInScrollView和scrollViewDidZoom中处理,代码如下:

- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView 

    return _imageView;//your imageView inside UIScrollView
  


- (void)scrollViewDidZoom:(UIScrollView *)scrollView

    CGSize boundSize = self.bounds.size;//scrollView bounds
    CGFloat boundWidth = boundSize.width;
    CGFloat boundHeight = boundSize.height;

    CGSize imageSize = self.imageView.image.size;
    CGFloat imageWidth = imageSize.width;
    CGFloat imageHeight = imageSize.height;

    CGFloat zoomScale = scrollView.zoomScale;
    DLog(@"zoomScale === %f",zoomScale);

    [self normalScaleViewDidZoom:boundWidth boundHeight:boundHeight imageWidth:imageWidth imageHeight:imageHeight scrollView:scrollView];
  

- (void)handleImageType

    CGSize imageSize = self.imageView.image.size;//imageView's image size
    CGFloat imageWidth = imageSize.width;
    CGFloat imageHeight = imageSize.height;
    if (imageWidth > imageHeight) 
      type = 1;
     else if (imageWidth < imageHeight)
      type = 2;
     else if (imageWidth == imageHeight) 
      type = 3;
    

- (void)normalScaleViewDidZoom:(CGFloat)boundWidth boundHeight:(CGFloat)boundHeight imageWidth:(CGFloat)imageWidth imageHeight:(CGFloat)imageHeight scrollView:(UIScrollView*)scrollView

    CGFloat zoomScale = scrollView.zoomScale;
    if (type == 1) 

        self.contentSize = CGSizeMake(boundWidth/imageHeight*imageWidth*zoomScale,boundWidth*zoomScale + (boundHeight-boundWidth));
     else if (type == 2)

        self.contentSize = CGSizeMake(boundWidth*zoomScale,boundWidth/imageWidth*imageHeight*zoomScale + (boundHeight-boundWidth) );
     else if (type == 3) 

        self.contentSize = CGSizeMake(boundWidth*zoomScale,boundHeight-boundWidth+boundWidth*zoomScale);
    
    [self zoomCenter:scrollView];



- (void)zoomCenter:(UIScrollView*)scrollView
    CGFloat offsetX = (scrollView.bounds.size.width > scrollView.contentSize.width)?(scrollView.bounds.size.width - scrollView.contentSize.width)/2 : 0.0;
    CGFloat offsetY = (scrollView.bounds.size.height > scrollView.contentSize.height)?(scrollView.bounds.size.height - scrollView.contentSize.height)/2 : 0.0;
    self.imageView.center = CGPointMake(scrollView.contentSize.width/2 + offsetX,scrollView.contentSize.height/2 + offsetY);


以上所有代码都是我在我的项目中应用的,希望你可以使用:)

【讨论】:

以上是关于Objective-C:从 UIScrollView 获取缩放的裁剪图像的主要内容,如果未能解决你的问题,请参考以下文章

Objective-C:从本地通知打开 URL

从 Objective-C 访问 Swift 扩展

从 Objective-C 里的 Alloc 和 AllocWithZone 谈起

从 Objective-C 调用 Python 代码

Objective-C:如何从 POST 方法返回响应?

从objective-c++调用swift函数