如何裁剪一个UIImageView在“纵横配合”模式一个新的UIImage?(How to crop

2019-06-25 02:36发布

我想通过裁剪一个UIImageView内的图像,以创建一个新的UIImage。 例如,在上述知情同意,我想在绿色标示区域的新的UIImage。 我发现代码要做到这一点,通常它看起来是这样的(作为一个UIImage类):

- (UIImage *)croppedImage:(CGRect)bounds {
    CGImageRef imageRef = CGImageCreateWithImageInRect([self CGImage], bounds);
    UIImage *croppedImage = [UIImage imageWithCGImage:imageRef];
    CGImageRelease(imageRef);
    return croppedImage;
}

非常有意义。 然而,我的UIImageView是contentMode“方面配合”。 好像是复杂的CGImageCreateWithImageInRect的计算的CGRect,我一直无法找出正确的解决方案。

我想我需要将相同的转换应用到绿色矩形作为被做的形象呢?

另:我发现这个其他的问题在这里( 如何知道一个UIImageView的应用方面适合的图像后的图像大小 ),这似乎表明越来越大小的蛮力的方式,但我仍然不知道如何融入裁剪的情况。

有任何想法吗?

编辑 :在我的情况下,我字面上具有正方形如上所示在过的UIImageView叠加视图绘制。 所以,当我意识到我正在裁剪的UIImage(在里面的UIImageView),我需要以某种方式改变绿色的CGRect,使得“匹配”在应用“方面适合”做了改造。 例如,如果我离开我的“左上角”模式的UIImageView,然后一切工作正常,因为有一个1:底层的UIImage和UIImageView的1之间的映射。 在“左上”模式的问题是,整个图像并不总是显示,因为它可能会比我的UIImageView大。

Answer 1:

根据我对方的回答给我写了这个方法对于一个UIImageView类类似的问题:

-(CGRect) cropRectForFrame:(CGRect)frame
{
    NSAssert(self.contentMode == UIViewContentModeScaleAspectFit, @"content mode must be aspect fit");

    CGFloat widthScale = self.bounds.size.width / self.image.size.width;
    CGFloat heightScale = self.bounds.size.height / self.image.size.height;

    float x, y, w, h, offset;
    if (widthScale<heightScale) {
        offset = (self.bounds.size.height - (self.image.size.height*widthScale))/2;
        x = frame.origin.x / widthScale;
        y = (frame.origin.y-offset) / widthScale;
        w = frame.size.width / widthScale;
        h = frame.size.height / widthScale;
    } else {
        offset = (self.bounds.size.width - (self.image.size.width*heightScale))/2;
        x = (frame.origin.x-offset) / heightScale;
        y = frame.origin.y / heightScale;
        w = frame.size.width / heightScale;
        h = frame.size.height / heightScale;
    }
    return CGRectMake(x, y, w, h);
}

您可以在绿色矩形的框架传递(假设它是图像视图的子视图),并获得作物矩形回来裁剪的UIImage。 请注意,它仅适用于“方面配合”模式! 我没有,虽然进行了测试。 所以,告诉我,如果它的作品!



Answer 2:

我知道答案已,但我有一些问题得到右上所以,我不会发表我的解决办法了。

问题是进行缩放方面契合的形象,但我们知道的宽度和高度都比例因子。 然后,我们可以计算出正确的裁剪矩形很简单:

-(UIImage*)crop:(CGRect)frame
{
    // Find the scalefactors  UIImageView's widht and height / UIImage width and height
    CGFloat widthScale = self.bounds.size.width / self.image.size.width;
    CGFloat heightScale = self.bounds.size.height / self.image.size.height;

    // Calculate the right crop rectangle 
    frame.origin.x = frame.origin.x * (1 / widthScale);
    frame.origin.y = frame.origin.y * (1 / heightScale);
    frame.size.width = frame.size.width * (1 / widthScale);
    frame.size.height = frame.size.height * (1 / heightScale);

    // Create a new UIImage
    CGImageRef imageRef = CGImageCreateWithImageInRect(self.image.CGImage, frame);
    UIImage *croppedImage = [UIImage imageWithCGImage:imageRef];
    CGImageRelease(imageRef);

    return croppedImage;
}


Answer 3:

我想你不明白你在做什么。 你不能“作物”一个UIImageView - 只UIImages。 所以,你的croppedImage方法应该是在一个UIImage的类别,而不是一个UIImageView类别。 边界RECT传递到农作物的方法必须是相对于图像大小,而不是到ImageView的边界。 这是无关紧要的什么形象看法的contentMode是 - 图像的裁切总是工作一样。 首先从图像查看图像。 然后从它创建一个新的裁剪图像,最后设置裁剪图像的图像视图。 这可以通过一行代码来完成:

imageView.image = [imageView.image croppedImage:rect];

由于您contentMode是“方面适合”新图像将自动延伸到适合在视图帧。 你也可以尝试改变基础上,image.size视图框,以避免的像素化效应。



Answer 4:

我使用下面的方法。

-(UIImage *)getNeedImageFrom:(UIImage*)image cropRect:(CGRect)rect
{
   CGSize cropSize = rect.size;
   CGFloat widthScale =  
   image.size.width/self.imageViewOriginal.bounds.size.width;
   CGFloat heightScale = 
   image.size.height/self.imageViewOriginal.bounds.size.height;
   cropSize = CGSizeMake(rect.size.width*widthScale,  
   rect.size.height*heightScale);
   CGPoint  pointCrop = CGPointMake(rect.origin.x*widthScale, 
   rect.origin.y*heightScale);
   rect = CGRectMake(pointCrop.x, pointCrop.y, cropSize.width, 
   cropSize.height);
   CGImageRef subImage = CGImageCreateWithImageInRect(image.CGImage, rect);
   UIImage *croppedImage = [UIImage imageWithCGImage:subImage];
   CGImageRelease(subImage);
   return croppedImage;

   }


文章来源: How to crop a UIImageView to a new UIImage in 'aspect fit' mode?