@@ -556,12 +556,17 @@ - (instancetype)init
556556 return ;
557557 }
558558
559- // 新たな画像アセットとしてカメラロールに保存
560- CFDictionaryRef attachments = CMCopyDictionaryOfAttachments (kCFAllocatorDefault ,
561- imageDataSampleBuffer,
562- kCMAttachmentMode_ShouldPropagate );
563- [[weakSelf library ] writeImageDataToSavedPhotosAlbum: jpegData metadata: (__bridge id )attachments
564- completionBlock:
559+ // EXIF情報を水平に統一する。ブラウザによってはEXIF情報により画像の向きが変わるため。
560+ CGImageSourceRef source = CGImageSourceCreateWithData ((__bridge CFDataRef)jpegData, NULL );
561+ NSDictionary *metadata = (__bridge NSDictionary *) CGImageSourceCopyPropertiesAtIndex (source, 0 , NULL );
562+ NSMutableDictionary *meta = [NSMutableDictionary dictionaryWithDictionary: metadata];
563+ NSMutableDictionary *tiff = meta[(NSString *) kCGImagePropertyTIFFDictionary ];
564+ tiff[(NSString *) kCGImagePropertyTIFFOrientation ] = @(kCGImagePropertyOrientationUp );
565+ meta[(NSString *) kCGImagePropertyTIFFDictionary ] = tiff;
566+ meta[(NSString *) kCGImagePropertyOrientation ] = @(kCGImagePropertyOrientationUp );
567+ UIImage *jpeg = [[UIImage alloc ] initWithData: jpegData];
568+ UIImage *fixJpeg = [weakSelf fixOrientationWithImage: jpeg position: recorder.videoDevice.position];
569+ [[weakSelf library ] writeImageToSavedPhotosAlbum: fixJpeg.CGImage metadata: meta completionBlock:
565570 ^(NSURL *assetURL, NSError *error) {
566571 if (!assetURL || error) {
567572 [response setErrorToUnknownWithMessage: @" Failed to save a photo to camera roll." ];
@@ -1691,7 +1696,87 @@ AVCaptureVideoOrientation videoOrientationFromDeviceOrientation(UIDeviceOrientat
16911696 }
16921697 return orientation;
16931698}
1699+ - (UIImage *)fixOrientationWithImage : (UIImage *)image position : (AVCaptureDevicePosition) position {
1700+
1701+ if (image.imageOrientation == UIImageOrientationUp && position != AVCaptureDevicePositionFront) return image;
16941702
1703+ CGAffineTransform transform = CGAffineTransformIdentity;
1704+
1705+ switch (image.imageOrientation ) {
1706+ case UIImageOrientationDown:
1707+ case UIImageOrientationDownMirrored:
1708+ transform = CGAffineTransformTranslate (transform, image.size .width , image.size .height );
1709+ transform = CGAffineTransformRotate (transform, M_PI);
1710+ break ;
1711+
1712+ case UIImageOrientationLeft:
1713+ case UIImageOrientationLeftMirrored:
1714+ transform = CGAffineTransformTranslate (transform, image.size .width , 0 );
1715+ transform = CGAffineTransformRotate (transform, M_PI_2);
1716+ break ;
1717+
1718+ case UIImageOrientationRight:
1719+ case UIImageOrientationRightMirrored:
1720+ transform = CGAffineTransformTranslate (transform, 0 , image.size .height );
1721+ transform = CGAffineTransformRotate (transform, -M_PI_2);
1722+ break ;
1723+ case UIImageOrientationUp:
1724+ case UIImageOrientationUpMirrored:
1725+ break ;
1726+ }
1727+
1728+ switch (position) {
1729+ case AVCaptureDevicePositionFront:
1730+ switch (image.imageOrientation ) {
1731+
1732+ case UIImageOrientationLeft:
1733+ case UIImageOrientationLeftMirrored:
1734+ case UIImageOrientationRight:
1735+ case UIImageOrientationRightMirrored:
1736+ transform = CGAffineTransformTranslate (transform, 0 , image.size .width );
1737+ transform = CGAffineTransformScale (transform, 1 , -1 );
1738+ break ;
1739+ case UIImageOrientationDown:
1740+ case UIImageOrientationDownMirrored:
1741+ case UIImageOrientationUp:
1742+ case UIImageOrientationUpMirrored:
1743+ default :
1744+ transform = CGAffineTransformTranslate (transform, image.size .width , 0 );
1745+ transform = CGAffineTransformScale (transform, -1 , 1 );
1746+ break ;
1747+ }
1748+
1749+ break ;
1750+ case AVCaptureDevicePositionUnspecified:
1751+ case AVCaptureDevicePositionBack:
1752+ default :
1753+ break ;
1754+ }
1755+
1756+ CGContextRef ctx = CGBitmapContextCreate (NULL , image.size .width , image.size .height ,
1757+ CGImageGetBitsPerComponent (image.CGImage ), 0 ,
1758+ CGImageGetColorSpace (image.CGImage ),
1759+ CGImageGetBitmapInfo (image.CGImage ));
1760+ CGContextConcatCTM (ctx, transform);
1761+ switch (image.imageOrientation ) {
1762+ case UIImageOrientationLeft:
1763+ case UIImageOrientationLeftMirrored:
1764+ case UIImageOrientationRight:
1765+ case UIImageOrientationRightMirrored:
1766+
1767+ CGContextDrawImage (ctx, CGRectMake (0 ,0 ,image.size .height ,image.size .width ), image.CGImage );
1768+ break ;
1769+
1770+ default :
1771+ CGContextDrawImage (ctx, CGRectMake (0 ,0 ,image.size .width ,image.size .height ), image.CGImage );
1772+ break ;
1773+ }
1774+ CGImageRef cgimg = CGBitmapContextCreateImage (ctx);
1775+ UIImage *img = [UIImage imageWithCGImage: cgimg];
1776+ CGContextRelease (ctx);
1777+ CGImageRelease (cgimg);
1778+ return img;
1779+ }
16951780#pragma mark - AVCapture{Audio,Video}DataOutputSampleBufferDelegate
16961781
16971782- (void )captureOutput : (AVCaptureOutput *)captureOutput
0 commit comments