Skip to content

Update to support SDWebImage 5.5's new thumbnailPixelSize option #6

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

Merged
merged 6 commits into from
Jan 31, 2020
Merged
Show file tree
Hide file tree
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
2 changes: 1 addition & 1 deletion Cartfile
Original file line number Diff line number Diff line change
@@ -1 +1 @@
github "SDWebImage/SDWebImage" ~> 5.0
github "SDWebImage/SDWebImage" ~> 5.5
2 changes: 1 addition & 1 deletion Cartfile.resolved
Original file line number Diff line number Diff line change
@@ -1 +1 @@
github "SDWebImage/SDWebImage" "5.0.2"
github "SDWebImage/SDWebImage" "5.5.2"
15 changes: 14 additions & 1 deletion Example/SDWebImagePDFCoder/SDViewController.m
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -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) {
Expand All @@ -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:^{
Expand All @@ -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
Expand Down
2 changes: 1 addition & 1 deletion Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
26 changes: 15 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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")
]
)
```
Expand Down Expand Up @@ -86,18 +86,18 @@ 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

```objectivec
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
Expand All @@ -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
Expand All @@ -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
Expand Down
2 changes: 1 addition & 1 deletion SDWebImagePDFCoder.podspec
Original file line number Diff line number Diff line change
Expand Up @@ -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
12 changes: 6 additions & 6 deletions SDWebImagePDFCoder/Classes/SDImagePDFCoder.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 <SDImageCoder>

@property (nonatomic, class, readonly) SDImagePDFCoder *sharedCoder;
Expand Down
22 changes: 19 additions & 3 deletions SDWebImagePDFCoder/Classes/SDImagePDFCoder.m
Original file line number Diff line number Diff line change
Expand Up @@ -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]) {
Expand Down
24 changes: 19 additions & 5 deletions SDWebImagePDFCoder/Classes/SDWebImagePDFCoderDefine.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
2 changes: 2 additions & 0 deletions SDWebImagePDFCoder/Classes/SDWebImagePDFCoderDefine.m
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,5 @@
SDWebImageContextOption _Nonnull const SDWebImageContextPDFPrefersBitmap = @"pdfPrefersBitmap";
SDWebImageContextOption _Nonnull const SDWebImageContextPDFImageSize = @"pdfImageSize";
SDWebImageContextOption _Nonnull const SDWebImageContextPDFImagePreserveAspectRatio = @"pdfImagePreserveAspectRatio";

SDImageCoderOption _Nonnull const SDImageCoderDecodePDFPageNumber = @"decodePDFPageNumber";