Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix the issue when EXIF orientation does not keep during the libwebp encoding #96

Merged
merged 1 commit into from
Feb 4, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 32 additions & 1 deletion SDWebImageWebPCoder/Classes/SDImageWebPCoder.m
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

#import "SDImageWebPCoder.h"
#import "SDWebImageWebPCoderDefine.h"
#import "SDInternalMacros.h"
#import <Accelerate/Accelerate.h>
#import <os/lock.h>
#import <libkern/OSAtomic.h>
Expand Down Expand Up @@ -784,7 +785,14 @@ - (NSData *)encodedDataWithFrames:(NSArray<SDImageFrame *> *)frames loopCount:(N
BOOL encodeFirstFrame = [options[SDImageCoderEncodeFirstFrameOnly] boolValue];
if (encodeFirstFrame || frames.count <= 1) {
// for static single webp image
// Keep EXIF orientation
#if SD_UIKIT || SD_WATCH
CGImagePropertyOrientation orientation = [SDImageCoderHelper exifOrientationFromImageOrientation:image.imageOrientation];
#else
CGImagePropertyOrientation orientation = kCGImagePropertyOrientationUp;
#endif
data = [self sd_encodedWebpDataWithImage:imageRef
orientation:orientation
quality:compressionQuality
maxPixelSize:maxPixelSize
maxFileSize:maxFileSize
Expand All @@ -797,7 +805,15 @@ - (NSData *)encodedDataWithFrames:(NSArray<SDImageFrame *> *)frames loopCount:(N
}
for (size_t i = 0; i < frames.count; i++) {
SDImageFrame *currentFrame = frames[i];
NSData *webpData = [self sd_encodedWebpDataWithImage:currentFrame.image.CGImage
UIImage *currentImage = currentFrame.image;
// Keep EXIF orientation
#if SD_UIKIT || SD_WATCH
CGImagePropertyOrientation orientation = [SDImageCoderHelper exifOrientationFromImageOrientation:currentImage.imageOrientation];
#else
CGImagePropertyOrientation orientation = kCGImagePropertyOrientationUp;
#endif
NSData *webpData = [self sd_encodedWebpDataWithImage:currentImage.CGImage
orientation:orientation
quality:compressionQuality
maxPixelSize:maxPixelSize
maxFileSize:maxFileSize
Expand Down Expand Up @@ -838,6 +854,7 @@ - (NSData *)encodedDataWithFrames:(NSArray<SDImageFrame *> *)frames loopCount:(N
}

- (nullable NSData *)sd_encodedWebpDataWithImage:(nullable CGImageRef)imageRef
orientation:(CGImagePropertyOrientation)orientation
quality:(double)quality
maxPixelSize:(CGSize)maxPixelSize
maxFileSize:(NSUInteger)maxFileSize
Expand All @@ -847,6 +864,20 @@ - (nullable NSData *)sd_encodedWebpDataWithImage:(nullable CGImageRef)imageRef
if (!imageRef) {
return nil;
}
// Seems libwebp has no convenient EXIF orientation API ?
// Use transform to apply ourselves. Need to release before return
// TODO: Use `WebPMuxSetChunk` API to write/read EXIF data, see: https://developers.google.com/speed/webp/docs/riff_container#extended_file_format
__block CGImageRef rotatedCGImage = NULL;
@onExit {
if (rotatedCGImage) {
CGImageRelease(rotatedCGImage);
}
};
if (orientation != kCGImagePropertyOrientationUp) {
rotatedCGImage = [SDImageCoderHelper CGImageCreateDecoded:imageRef orientation:orientation];
NSCParameterAssert(rotatedCGImage);
imageRef = rotatedCGImage;
}

size_t width = CGImageGetWidth(imageRef);
size_t height = CGImageGetHeight(imageRef);
Expand Down
Loading