Added the default ImageIO coder with PDF support, use the screen size if user does not provide any explict pixel size

This commit is contained in:
DreamPiggy 2020-01-30 15:11:42 +08:00
parent 08aab785db
commit 96b0a2e031
1 changed files with 39 additions and 11 deletions

View File

@ -14,6 +14,9 @@
#import "SDAnimatedImageRep.h"
#import "UIImage+ForceDecode.h"
// Specify DPI for vector format in CGImageSource, like PDF
static NSString * kSDCGImageSourceRasterizationDPI = @"kCGImageSourceRasterizationDPI";
@interface SDImageIOCoderFrame : NSObject
@property (nonatomic, assign) NSUInteger index; // Frame index (zero based)
@ -158,9 +161,33 @@
exifOrientation = kCGImagePropertyOrientationUp;
}
CFStringRef uttype = CGImageSourceGetType(source);
// Check vector format
BOOL isVector = NO;
if ([NSData sd_imageFormatFromUTType:uttype] == SDImageFormatPDF) {
isVector = YES;
}
CGImageRef imageRef;
if (thumbnailSize.width == 0 || thumbnailSize.height == 0 || (pixelWidth <= thumbnailSize.width && pixelHeight <= thumbnailSize.height)) {
imageRef = CGImageSourceCreateImageAtIndex(source, index, NULL);
if (thumbnailSize.width == 0 || thumbnailSize.height == 0 || pixelWidth == 0 || pixelHeight == 0 || (pixelWidth <= thumbnailSize.width && pixelHeight <= thumbnailSize.height)) {
NSDictionary *options;
if (isVector) {
if (thumbnailSize.width == 0 || thumbnailSize.height == 0) {
// Provide the default pixel count for vector images, simply just use the screen size
#if SD_WATCH
thumbnailSize = WKInterfaceDevice.currentDevice.screenBounds.size;
#elif SD_UIKIT
thumbnailSize = UIScreen.mainScreen.bounds.size;
#elif SD_MAC
thumbnailSize = NSScreen.mainScreen.frame.size;
#endif
}
CGFloat maxPixelSize = MAX(thumbnailSize.width, thumbnailSize.height);
NSUInteger DPIPerPixel = 2;
NSUInteger rasterizationDPI = maxPixelSize * DPIPerPixel;
options = @{kSDCGImageSourceRasterizationDPI : @(rasterizationDPI)};
}
imageRef = CGImageSourceCreateImageAtIndex(source, index, (__bridge CFDictionaryRef)options);
} else {
NSMutableDictionary *thumbnailOptions = [NSMutableDictionary dictionary];
thumbnailOptions[(__bridge NSString *)kCGImageSourceCreateThumbnailWithTransform] = @(preserveAspectRatio);
@ -179,21 +206,22 @@
thumbnailOptions[(__bridge NSString *)kCGImageSourceThumbnailMaxPixelSize] = @(maxPixelSize);
thumbnailOptions[(__bridge NSString *)kCGImageSourceCreateThumbnailFromImageIfAbsent] = @(YES);
imageRef = CGImageSourceCreateThumbnailAtIndex(source, index, (__bridge CFDictionaryRef)thumbnailOptions);
}
if (!imageRef) {
return nil;
}
if (thumbnailSize.width > 0 && thumbnailSize.height > 0) {
if (preserveAspectRatio) {
// kCGImageSourceCreateThumbnailWithTransform will apply EXIF transform as well, we should not apply twice
exifOrientation = kCGImagePropertyOrientationUp;
} else {
// `CGImageSourceCreateThumbnailAtIndex` take only pixel dimension, if not `preserveAspectRatio`, we should manual scale to the target size
if (imageRef) {
CGImageRef scaledImageRef = [SDImageCoderHelper CGImageCreateScaled:imageRef size:thumbnailSize];
CGImageRelease(imageRef);
imageRef = scaledImageRef;
}
CGImageRef scaledImageRef = [SDImageCoderHelper CGImageCreateScaled:imageRef size:thumbnailSize];
CGImageRelease(imageRef);
imageRef = scaledImageRef;
}
}
if (!imageRef) {
return nil;
}
#if SD_UIKIT || SD_WATCH
UIImageOrientation imageOrientation = [SDImageCoderHelper imageOrientationFromEXIFOrientation:exifOrientation];
@ -363,7 +391,7 @@
if (scaleFactor != nil) {
scale = MAX([scaleFactor doubleValue], 1);
}
image = [SDImageIOAnimatedCoder createFrameAtIndex:0 source:_imageSource scale:scale preserveAspectRatio:_preserveAspectRatio thumbnailSize:_thumbnailSize];
image = [self.class createFrameAtIndex:0 source:_imageSource scale:scale preserveAspectRatio:_preserveAspectRatio thumbnailSize:_thumbnailSize];
if (image) {
image.sd_imageFormat = self.class.imageFormat;
}