[英]Image captured from custom camera gets rotated after cropping iOS
裁剪图像后,我面临图像旋转的问题。 我已经逐步使用了下面我目前使用的方法。
这是我遵循以获得结果的过程:
步骤:1通过自定义相机拍照
- (void)captureImageWithCompletionHander:(void (^)(id))completionHandler{
[_cameraOverlayView hideHightLightOverlay];
if (_isCapturing) return;
__weak typeof(self) weakSelf = self;
[weakSelf hideGLKView:YES completion:^{
[weakSelf hideGLKView:NO completion:^{
[weakSelf hideGLKView:YES completion:nil];
}];
}];
_isCapturing = YES;
AVCaptureConnection *videoConnection = nil;
for (AVCaptureConnection *connection in self.stillImageOutput.connections){
for (AVCaptureInputPort *port in [connection inputPorts]){
if ([[port mediaType] isEqual:AVMediaTypeVideo] ){
videoConnection = connection;
break;
}
}
if (videoConnection) break;
}
[self.stillImageOutput captureStillImageAsynchronouslyFromConnection:videoConnection completionHandler: ^(CMSampleBufferRef imageSampleBuffer, NSError *error){
if(!CMSampleBufferIsValid(imageSampleBuffer)){
return;
}
NSData *imageData = [AVCaptureStillImageOutput jpegStillImageNSDataRepresentation:imageSampleBuffer];
UIImage * capturedImage = [[UIImage alloc]initWithData:imageData scale:1];
NSLog(@"%lu",(unsigned long)UIImageJPEGRepresentation(capturedImage, 1.0).length);
if (_myDevice == [AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo][0]) {
capturedImage = capturedImage;
}else if (_myDevice == [AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo][1]) {
}
[weakSelf hideGLKView:NO completion:nil];
completionHandler(capturedImage);
_isCapturing = NO;
}];
}
步骤:2固定方向
-(id)initWithImage:(UIImage*) image{
self = [super init];
if (self){
self.originalImage = [image fixOrientation];
}
return self;
}
//Method for fix orientation
@implementation UIImage (fixOrientation)
- (UIImage *)fixOrientation {
// No-op if the orientation is already correct
if (self.imageOrientation == UIImageOrientationUp) return self;
// We need to calculate the proper transformation to make the image upright.
// We do it in 2 steps: Rotate if Left/Right/Down, and then flip if Mirrored.
CGAffineTransform transform = CGAffineTransformIdentity;
switch (self.imageOrientation) {
case UIImageOrientationDown:
case UIImageOrientationDownMirrored:
transform = CGAffineTransformTranslate(transform, self.size.width, self.size.height);
transform = CGAffineTransformRotate(transform, M_PI);
break;
case UIImageOrientationLeft:
case UIImageOrientationLeftMirrored:
transform = CGAffineTransformTranslate(transform, self.size.width, 0);
transform = CGAffineTransformRotate(transform, M_PI_2);
break;
case UIImageOrientationRight:
case UIImageOrientationRightMirrored:
transform = CGAffineTransformTranslate(transform, 0, self.size.height);
transform = CGAffineTransformRotate(transform, -M_PI_2);
break;
case UIImageOrientationUp:
case UIImageOrientationUpMirrored:
break;
}
switch (self.imageOrientation) {
case UIImageOrientationUpMirrored:
case UIImageOrientationDownMirrored:
transform = CGAffineTransformTranslate(transform, self.size.width, 0);
transform = CGAffineTransformScale(transform, -1, 1);
break;
case UIImageOrientationLeftMirrored:
case UIImageOrientationRightMirrored:
transform = CGAffineTransformTranslate(transform, self.size.height, 0);
transform = CGAffineTransformScale(transform, -1, 1);
break;
case UIImageOrientationUp:
case UIImageOrientationDown:
case UIImageOrientationLeft:
case UIImageOrientationRight:
break;
}
// Now we draw the underlying CGImage into a new context, applying the transform
// calculated above.
CGContextRef ctx = CGBitmapContextCreate(NULL, self.size.width, self.size.height,
CGImageGetBitsPerComponent(self.CGImage), 0,
CGImageGetColorSpace(self.CGImage),
CGImageGetBitmapInfo(self.CGImage));
CGContextConcatCTM(ctx, transform);
switch (self.imageOrientation) {
case UIImageOrientationLeft:
case UIImageOrientationLeftMirrored:
case UIImageOrientationRight:
case UIImageOrientationRightMirrored:
// Grr...
CGContextDrawImage(ctx, CGRectMake(0,0,self.size.height,self.size.width), self.CGImage);
break;
default:
CGContextDrawImage(ctx, CGRectMake(0,0,self.size.width,self.size.height), self.CGImage);
break;
}
// And now we just create a new UIImage from the drawing context
CGImageRef cgimg = CGBitmapContextCreateImage(ctx);
UIImage *img = [UIImage imageWithCGImage:cgimg];
CGContextRelease(ctx);
CGImageRelease(cgimg);
return img;
}
@end
步骤:3裁剪图像
-(UIImage *)cropImage:(UIImage *)image{
CGFloat overlayHeight = self.frame.size.height;
UIImageOrientation originalOrientation = image.imageOrientation;
CGFloat originalScale = image.scale;
CIImage *rawImage = [CIImage imageWithCGImage:image.CGImage];
NSMutableDictionary *rectangleCoordinates = [NSMutableDictionary new];
rectangleCoordinates[@"inputTopLeft"] = [CIVector vectorWithCGPoint:CGPointMake(topLeftPath.x * _absoluteWidth, (overlayHeight - topLeftPath.y) * _absoluteHeight)];
rectangleCoordinates[@"inputTopRight"] = [CIVector vectorWithCGPoint:CGPointMake(topRightPath.x * _absoluteWidth, (overlayHeight - topRightPath.y) * _absoluteHeight)];
rectangleCoordinates[@"inputBottomLeft"] = [CIVector vectorWithCGPoint:CGPointMake(bottomLeftPath.x * _absoluteWidth, (overlayHeight - bottomLeftPath.y) * _absoluteHeight)];
rectangleCoordinates[@"inputBottomRight"] = [CIVector vectorWithCGPoint:CGPointMake(bottomRightPath.x * _absoluteWidth, (overlayHeight - bottomRightPath.y) * _absoluteHeight)];
rawImage = [rawImage imageByApplyingFilter:@"CIPerspectiveCorrection" withInputParameters:rectangleCoordinates];
CIContext *context = [CIContext contextWithOptions:nil];
CGImageRef cgImage = [context createCGImage:rawImage fromRect:[rawImage extent]];
UIImage *RImage = [UIImage imageWithCGImage:cgImage scale:originalScale orientation:originalOrientation];
return RImage;
}
结果:
我已经尝试过但不起作用的一些参考:
iOS UIImagePickerController上载后结果图像方向
iOS-UIImageView-如何处理UIImage图像方向
将UIImage转换为CIImage以裁剪为CGRect。 AVFoundation
如果有人指导解决此问题,那就太好了。
提前致谢。
只需在“ cropImage”方法的以下行中将方向替换为UIImageOrientationUp。
UIImage *RImage = [UIImage imageWithCGImage:cgImage scale:originalScale orientation:UIImageOrientationUp];
经过如此多的实验并尝试了许多解决方案,最后我通过移至UIBeizerPath
解决了它。
我注意到定向问题仅是由于CIImage
,而它从未得到解决。 即使是原始图像也能正确获取,由于CIImage
它在裁剪后也会旋转。
所以尝试了UIBeizerPath
&这是我所做的:
UIBezierPath *path = [_overlayView getPath];
CGRect rect = CGRectZero;
rect.size = _detectedImage.frame.size;
CAShapeLayer *shapeLayer = [CAShapeLayer layer];
shapeLayer.frame = CGRectMake(0, 0, _detectedImage.frame.size.width, _detectedImage.frame.size.height);
shapeLayer.path = path.CGPath;
shapeLayer.fillColor = [[UIColor whiteColor] CGColor];
shapeLayer.backgroundColor = [[UIColor clearColor] CGColor];
[_detectedImage.layer setMask:shapeLayer];
UIGraphicsBeginImageContextWithOptions(_detectedImage.layer.frame.size, NO, 0);
[_detectedImage.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *outputImage = UIGraphicsGetImageFromCurrentImageContext();
UIImage *cpImage = [outputImage imageByTrimmingTransparentPixelsRequiringFullOpacity:YES];
UIGraphicsEndImageContext();
希望它会帮助某人。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.