From 96b0a2e0316111e0967ebe557fbb2e513f44cf45 Mon Sep 17 00:00:00 2001 From: DreamPiggy Date: Thu, 30 Jan 2020 15:11:42 +0800 Subject: [PATCH] Added the default ImageIO coder with PDF support, use the screen size if user does not provide any explict pixel size --- SDWebImage/Core/SDImageIOAnimatedCoder.m | 50 ++++++++++++++++++------ 1 file changed, 39 insertions(+), 11 deletions(-) diff --git a/SDWebImage/Core/SDImageIOAnimatedCoder.m b/SDWebImage/Core/SDImageIOAnimatedCoder.m index b72dc4e0..1db7a495 100644 --- a/SDWebImage/Core/SDImageIOAnimatedCoder.m +++ b/SDWebImage/Core/SDImageIOAnimatedCoder.m @@ -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; }