diff --git a/Cartfile b/Cartfile index 9a360e8..cb68a79 100644 --- a/Cartfile +++ b/Cartfile @@ -1 +1 @@ -github "SDWebImage/SDWebImage" ~> 5.0 \ No newline at end of file +github "SDWebImage/SDWebImage" ~> 5.5 \ No newline at end of file diff --git a/Cartfile.resolved b/Cartfile.resolved index 7b485c4..0e510c6 100644 --- a/Cartfile.resolved +++ b/Cartfile.resolved @@ -1 +1 @@ -github "SDWebImage/SDWebImage" "5.0.2" +github "SDWebImage/SDWebImage" "5.5.2" diff --git a/Example/SDWebImagePDFCoder/SDViewController.m b/Example/SDWebImagePDFCoder/SDViewController.m index 1a2887c..63d8dc4 100644 --- a/Example/SDWebImagePDFCoder/SDViewController.m +++ b/Example/SDWebImagePDFCoder/SDViewController.m @@ -25,6 +25,7 @@ - (void)viewDidLoad [[SDImageCodersManager sharedManager] addCoder:PDFCoder]; NSURL *pdfURL = [NSURL URLWithString:@"https://raw.githubusercontent.com/icons8/flat-color-icons/master/pdf/about.pdf"]; NSURL *pdfURL2 = [NSURL URLWithString:@"https://raw.githubusercontent.com/icons8/flat-color-icons/master/pdf/webcam.pdf"]; + NSURL *pdfURL3 = [NSURL URLWithString:@"https://raw.githubusercontent.com/icons8/flat-color-icons/master/pdf/like.pdf"]; CGSize screenSize = self.view.bounds.size; @@ -36,8 +37,13 @@ - (void)viewDidLoad imageView2.contentMode = UIViewContentModeScaleAspectFit; imageView2.clipsToBounds = YES; + UIImageView *imageView3 = [[UIImageView alloc] init]; + imageView3.frame = CGRectMake(screenSize.width - 100, screenSize.height - 100, 100, 100); + imageView3.contentMode = UIViewContentModeScaleToFill; + [self.view addSubview:imageView1]; [self.view addSubview:imageView2]; + [self.view addSubview:imageView3]; [imageView1 sd_setImageWithURL:pdfURL placeholderImage:nil options:SDWebImageRetryFailed completed:^(UIImage * _Nullable image, NSError * _Nullable error, SDImageCacheType cacheType, NSURL * _Nullable imageURL) { if (image) { @@ -46,7 +52,7 @@ - (void)viewDidLoad NSAssert(pdfData.length > 0, @"PDF Data export failed"); } }]; - [imageView2 sd_setImageWithURL:pdfURL2 placeholderImage:nil options:SDWebImageRetryFailed context:@{SDWebImageContextPDFImageSize : @(imageView2.bounds.size)} progress:nil completed:^(UIImage * _Nullable image, NSError * _Nullable error, SDImageCacheType cacheType, NSURL * _Nullable imageURL) { + [imageView2 sd_setImageWithURL:pdfURL2 placeholderImage:nil options:SDWebImageRetryFailed completed:^(UIImage * _Nullable image, NSError * _Nullable error, SDImageCacheType cacheType, NSURL * _Nullable imageURL) { if (image) { NSLog(@"PDF load animation success"); [UIView animateWithDuration:2 animations:^{ @@ -58,6 +64,13 @@ - (void)viewDidLoad }]; } }]; + [imageView3 sd_setImageWithURL:pdfURL3 placeholderImage:nil options:SDWebImageRetryFailed context:@{SDWebImageContextImageThumbnailPixelSize: @(CGSizeMake(100, 100))} progress:nil completed:^(UIImage * _Nullable image, NSError * _Nullable error, SDImageCacheType cacheType, NSURL * _Nullable imageURL) { + if (image) { + NSLog(@"PDF bitmap load success."); + NSData *svgData = [image sd_imageDataAsFormat:SDImageFormatPDF]; + NSAssert(!svgData, @"SVG Data should not exist"); + } + }]; } - (void)didReceiveMemoryWarning diff --git a/Package.swift b/Package.swift index b3e4367..d92cd22 100644 --- a/Package.swift +++ b/Package.swift @@ -17,7 +17,7 @@ let package = Package( dependencies: [ // Dependencies declare other packages that this package depends on. // .package(url: /* package url */, from: "1.0.0"), - .package(url: "https://github.com/SDWebImage/SDWebImage.git", from: "5.1.0") + .package(url: "https://github.com/SDWebImage/SDWebImage.git", from: "5.5.0") ], targets: [ // Targets are the basic building blocks of a package. A target can define a module or a test suite. diff --git a/README.md b/README.md index eeb0806..812201e 100644 --- a/README.md +++ b/README.md @@ -49,7 +49,7 @@ SDWebImagePDFCoder is available through [Swift Package Manager](https://swift.or ```swift let package = Package( dependencies: [ - .package(url: "https://github.com/SDWebImage/SDWebImagePDFCoder.git", from: "0.4") + .package(url: "https://github.com/SDWebImage/SDWebImagePDFCoder.git", from: "0.6") ] ) ``` @@ -86,9 +86,9 @@ imageView.sd_setImage(with: url) For firmware which is below iOS/tvOS 11+, `UIImage` && `UIImageView` does not support vector image rendering. Even you can add PDF image in Xcode Asset Catalog, it was encoded to bitmap PNG format when compiled but not support runtime scale. -For `UIImageView`, we will only parse PDF with a fixed image size (from the PDF cropBox information). But we also support you to specify a desired size during image loading using `.pdfImageSize` context option. And you can specify whether or not to keep aspect ratio during scale using `.pdfImagePreserveAspectRatio` context option. +For `UIImageView`, we will only parse PDF with a fixed image size (from the PDF mediaBox information). But we also support you to specify a desired size during image loading using `.imageThumbnailPixelSize` context option. And you can specify whether or not to keep aspect ratio during scale using `.imagePreserveAspectRatio` context option. -Note: Even you're on iOS/tvOS 11+, you can also use the `.pdfPrefersBitmap` context option to force us to generate the bitmap form of PDF, instead of the vector format. This can be used for some general image processing code. +Note: Once you pass the pixel size, we will always generate the bitmap representation even on iOS/tvOS 11+. If you want the vector format, do not pass them, let `UIImageView` to dynamically stretch the PDF. + Objective-C @@ -96,8 +96,8 @@ Note: Even you're on iOS/tvOS 11+, you can also use the `.pdfPrefersBitmap` cont SDImagePDFCoder *PDFCoder = [SDImagePDFCoder sharedCoder]; [[SDImageCodersManager sharedManager] addCoder:PDFCoder]; UIImageView *imageView; -CGSize PDFImageSize = CGSizeMake(500, 500); -[imageView sd_setImageWithURL:url placeholderImage:nil options:0 context:@{SDWebImageContextPDFPrefersBitmap : @YES, SDWebImageContextPDFImageSize : @(PDFImageSize)]; +CGSize bitmapSize = CGSizeMake(500, 500); +[imageView sd_setImageWithURL:url placeholderImage:nil options:0 context:@{SDWebImageContextImageThumbnailPixelSize : @(bitmapSize)]; ``` + Swift @@ -106,8 +106,8 @@ CGSize PDFImageSize = CGSizeMake(500, 500); let PDFCoder = SDImagePDFCoder.shared SDImageCodersManager.shared.addCoder(PDFCoder) let imageView: UIImageView -let PDFImageSize = CGSize(width: 500, height: 500) -imageView.sd_setImage(with: url, placeholderImage: nil, options: [], context: [.pdfPrefersBitmap : true, .pdfImageSize : PDFImageSize]) +let bitmapSize = CGSize(width: 500, height: 500) +imageView.sd_setImage(with: url, placeholderImage: nil, options: [], context: [.imageThumbnailPixelSize : bitmapSize]) ``` ## Export PDF data @@ -119,15 +119,19 @@ Note: For firmware which is below iOS/tvOS 11+, UIImage does not support PDF vec + Objective-C ```objectivec -UIImage *image; // UIImage with vector image, or NSImage contains `NSPDFImageRep` -NSData *imageData = [image sd_imageDataAsFormat:SDImageFormatPDF]; +UIImage *pdfImage; // UIImage with vector image, or NSImage contains `NSPDFImageRep` +if (pdfImage.sd_isVector) { // This API available in SDWebImage 5.6.0 + NSData *pdfData = [pdfImage sd_imageDataAsFormat:SDImageFormatPDF]; +} ``` + Swift ```swift -let image; // UIImage with vector image, or NSImage contains `NSPDFImageRep` -let imageData = image.sd_imageData(as: .PDF) +let pdfImage: UIImage // UIImage with vector image, or NSImage contains `NSPDFImageRep` +if pdfImage.sd_isVector { // This API available in SDWebImage 5.6.0 + let pdfData = pdfImage.sd_imageData(as: .PDF) +} ``` ## Screenshot diff --git a/SDWebImagePDFCoder.podspec b/SDWebImagePDFCoder.podspec index 56d13e2..701106f 100644 --- a/SDWebImagePDFCoder.podspec +++ b/SDWebImagePDFCoder.podspec @@ -39,5 +39,5 @@ SDWebImageSVGCoder is a SVG coder plugin for SDWebImage framework, which provide 'DERIVE_MACCATALYST_PRODUCT_BUNDLE_IDENTIFIER' => 'NO' } - s.dependency 'SDWebImage', '~> 5.0' + s.dependency 'SDWebImage', '~> 5.5' end diff --git a/SDWebImagePDFCoder/Classes/SDImagePDFCoder.h b/SDWebImagePDFCoder/Classes/SDImagePDFCoder.h index 44c831c..a0949b4 100644 --- a/SDWebImagePDFCoder/Classes/SDImagePDFCoder.h +++ b/SDWebImagePDFCoder/Classes/SDImagePDFCoder.h @@ -13,16 +13,16 @@ NS_ASSUME_NONNULL_BEGIN +static const SDImageFormat SDImageFormatPDF = 13; + /*** SDImagePDFCoder is a PDF image coder, which use the built-in UIKit/AppKit method to decode PDF images. And it will use the Core Graphics to draw PDF images when needed (For example, current firmware does not support built-in rendering). This class does not use PDFKit framwork because we focus on PDF vector images but not document pages rendering. - @note: For iOS/tvOS, from iOS/tvOS 11+, Apple support built-in vector scale for PDF image in `UIImage`. Which means you can just get set a image to the `UIImaegView`, then changing image view's bounds, contentMode to adjust the PDF image without losing any detail. However, when running on lower firmware, we don't support vector scaling and parse PDF image as a bitmap image. You can use `SDWebImageContextPDFImageSize` and `SDWebImageContextPDFImagePreserveAspectRatio` during image loading to specify a desired size (such as larger size for view rendering). - @note: For macOS, Apple support built-in vector scale for PDF image in `NSImage`. However, `NSImage` is mutable, you can change the size after image was loaded. - @note: By default we parse the first page (pageNumber = 1) of PDF image, for custom page number, check `SDWebImageContextPDFPageNumber` context option. + @note For iOS/tvOS, from iOS/tvOS 11+, Apple support built-in vector scale for PDF image in `UIImage`. Which means you can just get set a image to the `UIImaegView`, then changing image view's bounds, contentMode to adjust the PDF image without losing any detail. However, when running on lower firmware, we don't support vector scaling and parse PDF image as a bitmap image. You can use `SDImageCoderDecodeThumnailPixelSize` and `SDWebImageContextImagePreserveAspectRatio` during image loading to specify a desired size (such as larger size for view rendering). + @note For macOS, Apple support built-in vector scale for PDF image in `NSImage`. However, `NSImage` is mutable, you can change the size after image was loaded. + @note By default we parse the first page (pageNumber = 1) of PDF image, for custom page number, check `SDWebImageContextPDFPageNumber` context option. + @note If you call the coder directly, use the coder option (See `SDWebImagePDFCoderDefine.h`) instead of the context option. */ - -static const SDImageFormat SDImageFormatPDF = 13; - @interface SDImagePDFCoder : NSObject @property (nonatomic, class, readonly) SDImagePDFCoder *sharedCoder; diff --git a/SDWebImagePDFCoder/Classes/SDImagePDFCoder.m b/SDWebImagePDFCoder/Classes/SDImagePDFCoder.m index a4231cc..388d38a 100644 --- a/SDWebImagePDFCoder/Classes/SDImagePDFCoder.m +++ b/SDWebImagePDFCoder/Classes/SDImagePDFCoder.m @@ -55,25 +55,41 @@ - (UIImage *)decodedImageWithData:(NSData *)data options:(SDImageCoderOptions *) BOOL prefersBitmap = NO; CGSize imageSize = CGSizeZero; BOOL preserveAspectRatio = YES; + +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" // Parse args SDWebImageContext *context = options[SDImageCoderWebImageContext]; if (context[SDWebImageContextPDFPageNumber]) { pageNumber = [context[SDWebImageContextPDFPageNumber] unsignedIntegerValue]; - } - if (context[SDWebImageContextPDFPrefersBitmap]) { - prefersBitmap = [context[SDWebImageContextPDFPrefersBitmap] boolValue]; + } else if (options[SDImageCoderDecodePDFPageNumber]) { + pageNumber = [options[SDImageCoderDecodePDFPageNumber] unsignedIntegerValue]; } if (context[SDWebImageContextPDFImageSize]) { + prefersBitmap = YES; NSValue *sizeValue = context[SDWebImageContextPDFImageSize]; #if SD_MAC imageSize = sizeValue.sizeValue; #else imageSize = sizeValue.CGSizeValue; #endif + } else if (options[SDImageCoderDecodeThumbnailPixelSize]) { + prefersBitmap = YES; + NSValue *sizeValue = options[SDImageCoderDecodeThumbnailPixelSize]; +#if SD_MAC + imageSize = sizeValue.sizeValue; +#else + imageSize = sizeValue.CGSizeValue; +#endif + } else if (context[SDWebImageContextPDFPrefersBitmap]) { + prefersBitmap = [context[SDWebImageContextPDFPrefersBitmap] boolValue]; } if (context[SDWebImageContextPDFImagePreserveAspectRatio]) { preserveAspectRatio = [context[SDWebImageContextPDFImagePreserveAspectRatio] boolValue]; + } else if (options[SDImageCoderDecodePreserveAspectRatio]) { + preserveAspectRatio = [context[SDImageCoderDecodePreserveAspectRatio] boolValue]; } +#pragma clang diagnostic pop UIImage *image; if (!prefersBitmap && [self.class supportsVectorPDFImage]) { diff --git a/SDWebImagePDFCoder/Classes/SDWebImagePDFCoderDefine.h b/SDWebImagePDFCoder/Classes/SDWebImagePDFCoderDefine.h index 646c63f..2de9001 100644 --- a/SDWebImagePDFCoder/Classes/SDWebImagePDFCoderDefine.h +++ b/SDWebImagePDFCoder/Classes/SDWebImagePDFCoderDefine.h @@ -22,24 +22,38 @@ FOUNDATION_EXPORT SDWebImageContextOption _Nonnull const SDWebImageContextPDFPag /** A BOOL value which specify whether we prefer the actual bitmap representation instead of vector representation for PDF image. This is because the UIImage on iOS 11+ (NSImgae on macOS) can use the vector image format, which support dynamic scale without losing any detail. However, for some image processing logic, user may need the actual bitmap representation to manage pixels. Also, for lower firmware on iOS, the `UIImage` does not support vector rendering, user may want to handle them using the same code. (NSNumber) If you don't provide this value, use NO for default value and prefer the vector format when possible. + @note Deprecated, use `SDWebImageContextImageThumbnailPixelSize`. Pass CGSize.zero means the mediaBox size of SVG. */ -FOUNDATION_EXPORT SDWebImageContextOption _Nonnull const SDWebImageContextPDFPrefersBitmap; +FOUNDATION_EXPORT SDWebImageContextOption _Nonnull const SDWebImageContextPDFPrefersBitmap __attribute__((deprecated("Use the new context option (for WebCache category), or coder option (for SDImageCoder protocol) instead. Pass CGSize.zero means the mediaBox size of PDF", "SDWebImageContextImageThumbnailPixelSize"))); #pragma mark - Bitmap Representation Options /** A CGSize raw value which specify the desired PDF image size during image loading. Because vector image like PDF format, may not contains a fixed size, or you want to get a larger size bitmap representation UIImage. (NSValue) - If you don't provide this value, use the PDF cropBox size instead. + If you don't provide this value, use the PDF mediaBox size instead. @note For iOS/tvOS 11+, you don't need this option and it will be ignored. Because UIImage support built-in vector rendering and scaling for PDF. Changing imageView's contentMode and bounds instead. @note For macOS user. Changing imageViews' imageScaling and bounds instead. */ -FOUNDATION_EXPORT SDWebImageContextOption _Nonnull const SDWebImageContextPDFImageSize; +FOUNDATION_EXPORT SDWebImageContextOption _Nonnull const SDWebImageContextPDFImageSize __attribute__((deprecated("Use the new context option (for WebCache category), or coder option (for SDImageCoder protocol) instead", "SDWebImageContextImageThumbnailPixelSize"))); /** - A BOOL value which specify the whether PDF image should keep aspect ratio during image loading. Because when you specify image size via `SDWebImageContextPDFImageSize`, we need to know whether to keep aspect ratio or not when image size is not equal to PDF cropBox size. (NSNumber) + A BOOL value which specify the whether PDF image should keep aspect ratio during image loading. Because when you specify image size via `SDWebImageContextPDFImageSize`, we need to know whether to keep aspect ratio or not when image size is not equal to PDF mediaBox size. (NSNumber) If you don't provide this value, use YES for default value. @note For iOS/tvOS 11+, you don't need this option and it will be ignored. Because UIImage support built-in vector rendering and scaling for PDF. Changing imageView's contentMode and bounds instead. @note For macOS user. Changing imageViews' imageScaling and bounds instead. */ -FOUNDATION_EXPORT SDWebImageContextOption _Nonnull const SDWebImageContextPDFImagePreserveAspectRatio; +FOUNDATION_EXPORT SDWebImageContextOption _Nonnull const SDWebImageContextPDFImagePreserveAspectRatio __attribute__((deprecated("Use the new context option (for WebCache category), or coder option (for SDImageCoder protocol) instead", "SDWebImageContextImagePreserveAspectRatio"))); + +#pragma mark - Coder Options +/** + A unsigned interger raw value which specify the desired PDF image page number. Because PDF can contains mutiple pages. The page number index is started with 0. (NSNumber) + If you don't provide this value, use 0 (the first page) instead. + @note works for `SDImageCoder` + */ +FOUNDATION_EXPORT SDImageCoderOption _Nonnull const SDImageCoderDecodePDFPageNumber; + +/** + `SDImageCoderDecodeThumnailPixelSize`: The same as context option `SDWebImageContextImageThumbnailPixelSize` + `SDImageCoderDecodePreserveAspectRatio`: The same as context option `SDWebImageContextImagePreserveAspectRatio` + */ NS_ASSUME_NONNULL_END diff --git a/SDWebImagePDFCoder/Classes/SDWebImagePDFCoderDefine.m b/SDWebImagePDFCoder/Classes/SDWebImagePDFCoderDefine.m index 5120d1c..8b2d512 100644 --- a/SDWebImagePDFCoder/Classes/SDWebImagePDFCoderDefine.m +++ b/SDWebImagePDFCoder/Classes/SDWebImagePDFCoderDefine.m @@ -11,3 +11,5 @@ SDWebImageContextOption _Nonnull const SDWebImageContextPDFPrefersBitmap = @"pdfPrefersBitmap"; SDWebImageContextOption _Nonnull const SDWebImageContextPDFImageSize = @"pdfImageSize"; SDWebImageContextOption _Nonnull const SDWebImageContextPDFImagePreserveAspectRatio = @"pdfImagePreserveAspectRatio"; + +SDImageCoderOption _Nonnull const SDImageCoderDecodePDFPageNumber = @"decodePDFPageNumber";