修复图片方向后,图片乱码
rakuyoMo opened this issue · 1 comments
这个问题和以下两个 issues 类似,目前只在 iOS 12 的设备上复现过,iOS 12 以下的设备没有该问题。
这个问题具体来说,是对 YYImage
对象调用 yy_imageDataRepresentation
方法后,出现图片乱码的问题,如下图所示。
将 _yy_dataRepresentationForSystem
方法中的 修复图片方向的相关代码(2845-2851 行,如下所示)注释后,图片不再乱码。
if (self.imageOrientation != UIImageOrientationUp) {
CGImageRef rotated = YYCGImageCreateCopyWithOrientation(imageRef, self.imageOrientation, bitmapInfo | alphaInfo);
if (rotated) {
CFRelease(imageRef);
imageRef = rotated;
}
}
推测为 YYCGImageCreateCopyWithOrientation
方法内部某些代码与 iOS 12 不兼容?
------------------------ English ------------------------
This issue is similar to the following two issues, which are currently only reproduced on iOS 12 devices, and devices with iOS 12 or lower do not have this issue.
Specifically, this problem occurs when the yy_imageDataRepresentation
method is called on the YYImage
object, and the image is garbled, as shown in the following figure.
After commenting the relevant code (2845-2851 lines, as shown below) in the _yy_dataRepresentationForSystem
method, the image is no longer garbled.
if (self.imageOrientation != UIImageOrientationUp) {
CGImageRef rotated = YYCGImageCreateCopyWithOrientation(imageRef, self.imageOrientation, bitmapInfo | alphaInfo);
if (rotated) {
CFRelease(imageRef);
imageRef = rotated;
}
}
Is it speculated that some code inside the YYCGImageCreateCopyWithOrientation
method is not compatible with iOS 12?
最终我采用 “手动修正图片,之后再转为 NSData 对象” 的方法,解决了这个问题。
相关代码如下:
NSData *imageData = hasAnimatedImageData ? image.animatedImageData : [YYImageEncoder encodeImage:[image mbc_fixOrientation] type:imageType quality:0.9];
修正图片方向的代码如下(来源自互联网):
- (UIImage *)mbc_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;
default:
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;
default:
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;
}