Ios 从较大的UIImage裁剪UIImage的一部分,并包括非映像部分
我想我可能有一个奇怪的要求,但希望有人能帮助我。我正在使用众所周知的Ios 从较大的UIImage裁剪UIImage的一部分,并包括非映像部分,ios,uiscrollview,uiimage,ios7,crop,Ios,Uiscrollview,Uiimage,Ios7,Crop,我想我可能有一个奇怪的要求,但希望有人能帮助我。我正在使用众所周知的uicrollview+UIImageView放大和缩小图像,以及平移。这工作得很好,但我们当前的项目需要能够裁剪图像,但如果图像小于裁剪矩形,还需要在侧面包含黑色条。请参见下面的图片 我们希望捕获蓝色框中的所有内容,包括白色(白色为黑色,因为不透明设置为YES)。 这对于完全缩小的图像非常有用(白色只是UIImageView的额外空间)。 然而,当我们试图放大图像,并仅捕获该部分加上空白时,问题就出现了。 这将产生下图
uicrollview
+UIImageView
放大和缩小图像,以及平移。这工作得很好,但我们当前的项目需要能够裁剪图像,但如果图像小于裁剪矩形,还需要在侧面包含黑色条。请参见下面的图片
我们希望捕获蓝色框中的所有内容,包括白色(白色为黑色,因为不透明设置为YES
)。
这对于完全缩小的图像非常有用(白色只是UIImageView的额外空间)。
然而,当我们试图放大图像,并仅捕获该部分加上空白时,问题就出现了。
这将产生下图
我们看到的问题是,我们需要能够创建一个与裁剪矩形中的图像完全相同的图像,而不管该图像是否有一部分。另一个问题是,我们希望能够动态更改输出分辨率。纵横比为16:9,在本例中,kMaxWidth=1136
和kMaxHeight=639
,但在未来,我们可能需要更大或更小的16:9分辨率
以下是我迄今为止的功能:
- (UIImage *)createCroppedImageFromImage:(UIImage *)image {
CGSize newRect = CGSizeMake(kMaxWidth, kMaxHeight);
UIGraphicsBeginImageContextWithOptions(newRect, YES, 0.0);
// 0 is the edge of the screen, to help with zooming
CGFloat xDisplacement = ((abs(0 - imageView.frame.origin.x) * kMaxWidth) / (self.cropSize.width / self.scrollView.zoomScale) / self.scrollView.zoomScale);
CGFloat yDisplacement = ((abs(self.cropImageView.frame.origin.y - imageView.frame.origin.y) * kMaxHeight) / (self.cropSize.height / self.scrollView.zoomScale) / self.scrollView.zoomScale);
CGFloat newImageWidth = (self.image.size.width * kMaxWidth) / (self.cropSize.width / self.scrollView.zoomScale);
CGFloat newImageHeight = (self.image.size.height * kMaxHeight) / (self.cropSize.height / self.scrollView.zoomScale);
[image drawInRect:CGRectMake(xDisplacement, 0, newImageWidth, newImageHeight)];
UIImage *croppedImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return croppedImage;
}
任何帮助都将不胜感激。我认为图像视图的已翻译rect计算不正确。由于UIImageView是UIScrollView中的子视图,您应该能够通过调用
[scrollView convertRect:scrollView.bounds to View:imageView]来计算可见的rect代码>。这将是图像视图的可见矩形。你现在需要做的就是修剪它
-(UIImage*)cropImage:(UIImage*)img inRect:(CGRect)rect{
CGImageRef cropped = CGImageCreateWithImageInRect(img.CGImage, rect);
UIImage *image = [UIImage imageWithCGImage:cropped];
CGImageRelease(cropped);
return image;
}
编辑:是的。。。我忘了提到裁剪应该在(0,1)坐标空间中进行。我已经为您修改了裁剪函数,因此它会根据您提供的所有参数、UIScrollView中的UIImageView和图像裁剪图像
-(UIImage*)cropImage:(UIImage*)image inImageView:(UIImageView*)imageView scrollView:(UIScrollView*)scrollView{
// get visible rect from image scrollview
CGRect visibleRect = [scrollView convertRect:scrollView.bounds toView:imageView];
UIImage* rCroppedImage;
CALayer* maskLayer= [[CALayer alloc] init];
maskLayer.contents= (id)image.CGImage;
maskLayer.frame= CGRectMake(0, 0, visibleRect.size.width, visibleRect.size.height);
CGRect rect= CGRectMake(visibleRect.origin.x / image.size.width,
visibleRect.origin.y / image.size.height,
visibleRect.size.width / image.size.width,
visibleRect.size.height / image.size.height);
maskLayer.contentsRect= rect;
UIGraphicsBeginImageContext(visibleRect.size);
CGContextRef context= UIGraphicsGetCurrentContext();
[maskLayer renderInContext:context];
rCroppedImage= UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return rCroppedImage;
}
最后我只是截图,然后剪下来。它似乎工作得很好
- (UIImage *)cropImage {
CGRect cropRect = self.cropOverlay.cropRect;
UIGraphicsBeginImageContext(self.view.frame.size);
[self.view.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *fullScreenshot = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
CGImageRef croppedImage = CGImageCreateWithImageInRect(fullScreenshot.CGImage, cropRect);
UIImage *crop = [[UIImage imageWithCGImage:croppedImage] resizedImage:self.outputSize interpolationQuality:kCGInterpolationHigh];
CGImageRelease(croppedImage);
return crop;
}
如果使用iOS 7,您将使用drawViewHierarchyInRect:AfterScreenUpdate:
,而不是RenderContext:
我使用了类似于[self cropImage:self.image inRect:[self.scrollView convertRect:self.scrollView.bounds to View:imageView]]的函数
但是它根本不起作用。你能告诉我你得到的rect值是多少吗?有几件事。1.这需要使用UIGraphicsBeginImageContextWithOptions
,将“不透明”设置为“是”,以显示左右两侧的黑条(这是必需的)。2.将此选项与不透明=是一起使用会导致手机崩溃,而不仅仅是应用程序崩溃。3.没有使用kMaxWidth
和kMaxHeight
来指定输出图像的大小。使用UIGraphicsBeginImageContextWithOptions(visibleRect.size,是,scrollView.zoomScale)
有助于使ui图像
不会导致崩溃,但是图像不是我要找的。这是屏幕的大小,在这里我只寻找裁剪矩形,它也是整个图像。