[英]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.