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