Skip to content

Commit 76423a1

Browse files
authoredFeb 4, 2024
Merge pull request #96 from SDWebImage/bugfix_exif_orientation_encode
Fix the issue when EXIF orientation does not keep during the libwebp encoding
2 parents acfb824 + ee4f321 commit 76423a1

File tree

1 file changed

+32
-1
lines changed

1 file changed

+32
-1
lines changed
 

‎SDWebImageWebPCoder/Classes/SDImageWebPCoder.m

+32-1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88

99
#import "SDImageWebPCoder.h"
1010
#import "SDWebImageWebPCoderDefine.h"
11+
#import "SDInternalMacros.h"
1112
#import <Accelerate/Accelerate.h>
1213
#import <os/lock.h>
1314
#import <libkern/OSAtomic.h>
@@ -784,7 +785,14 @@ - (NSData *)encodedDataWithFrames:(NSArray<SDImageFrame *> *)frames loopCount:(N
784785
BOOL encodeFirstFrame = [options[SDImageCoderEncodeFirstFrameOnly] boolValue];
785786
if (encodeFirstFrame || frames.count <= 1) {
786787
// for static single webp image
788+
// Keep EXIF orientation
789+
#if SD_UIKIT || SD_WATCH
790+
CGImagePropertyOrientation orientation = [SDImageCoderHelper exifOrientationFromImageOrientation:image.imageOrientation];
791+
#else
792+
CGImagePropertyOrientation orientation = kCGImagePropertyOrientationUp;
793+
#endif
787794
data = [self sd_encodedWebpDataWithImage:imageRef
795+
orientation:orientation
788796
quality:compressionQuality
789797
maxPixelSize:maxPixelSize
790798
maxFileSize:maxFileSize
@@ -797,7 +805,15 @@ - (NSData *)encodedDataWithFrames:(NSArray<SDImageFrame *> *)frames loopCount:(N
797805
}
798806
for (size_t i = 0; i < frames.count; i++) {
799807
SDImageFrame *currentFrame = frames[i];
800-
NSData *webpData = [self sd_encodedWebpDataWithImage:currentFrame.image.CGImage
808+
UIImage *currentImage = currentFrame.image;
809+
// Keep EXIF orientation
810+
#if SD_UIKIT || SD_WATCH
811+
CGImagePropertyOrientation orientation = [SDImageCoderHelper exifOrientationFromImageOrientation:currentImage.imageOrientation];
812+
#else
813+
CGImagePropertyOrientation orientation = kCGImagePropertyOrientationUp;
814+
#endif
815+
NSData *webpData = [self sd_encodedWebpDataWithImage:currentImage.CGImage
816+
orientation:orientation
801817
quality:compressionQuality
802818
maxPixelSize:maxPixelSize
803819
maxFileSize:maxFileSize
@@ -838,6 +854,7 @@ - (NSData *)encodedDataWithFrames:(NSArray<SDImageFrame *> *)frames loopCount:(N
838854
}
839855

840856
- (nullable NSData *)sd_encodedWebpDataWithImage:(nullable CGImageRef)imageRef
857+
orientation:(CGImagePropertyOrientation)orientation
841858
quality:(double)quality
842859
maxPixelSize:(CGSize)maxPixelSize
843860
maxFileSize:(NSUInteger)maxFileSize
@@ -847,6 +864,20 @@ - (nullable NSData *)sd_encodedWebpDataWithImage:(nullable CGImageRef)imageRef
847864
if (!imageRef) {
848865
return nil;
849866
}
867+
// Seems libwebp has no convenient EXIF orientation API ?
868+
// Use transform to apply ourselves. Need to release before return
869+
// TODO: Use `WebPMuxSetChunk` API to write/read EXIF data, see: https://developers.google.com/speed/webp/docs/riff_container#extended_file_format
870+
__block CGImageRef rotatedCGImage = NULL;
871+
@onExit {
872+
if (rotatedCGImage) {
873+
CGImageRelease(rotatedCGImage);
874+
}
875+
};
876+
if (orientation != kCGImagePropertyOrientationUp) {
877+
rotatedCGImage = [SDImageCoderHelper CGImageCreateDecoded:imageRef orientation:orientation];
878+
NSCParameterAssert(rotatedCGImage);
879+
imageRef = rotatedCGImage;
880+
}
850881

851882
size_t width = CGImageGetWidth(imageRef);
852883
size_t height = CGImageGetHeight(imageRef);

0 commit comments

Comments
 (0)
Please sign in to comment.