diff --git a/Example/SDWebImagePDFCoder-Example-macOS/ViewController.m b/Example/SDWebImagePDFCoder-Example-macOS/ViewController.m index c68f44a..1367d79 100644 --- a/Example/SDWebImagePDFCoder-Example-macOS/ViewController.m +++ b/Example/SDWebImagePDFCoder-Example-macOS/ViewController.m @@ -40,7 +40,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 context:@{SDWebImageContextImageThumbnailPixelSize : @(imageView2.bounds.size)} progress:nil completed:^(UIImage * _Nullable image, NSError * _Nullable error, SDImageCacheType cacheType, NSURL * _Nullable imageURL) { if (image) { NSLog(@"PDF load animation success"); [NSAnimationContext runAnimationGroup:^(NSAnimationContext * _Nonnull context) { diff --git a/README.md b/README.md index a2f3811..bbbb09f 100644 --- a/README.md +++ b/README.md @@ -22,7 +22,7 @@ You can modify the code or use some other PDF files to check the compatibility. + tvOS 9+ + macOS 10.11+ + watchOS 2+ -+ Xcode 11+ ++ Xcode 13+ ## Installation @@ -50,7 +50,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.6") + .package(url: "https://github.com/SDWebImage/SDWebImagePDFCoder.git", from: "1.0") ] ) ``` @@ -115,24 +115,21 @@ imageView.sd_setImage(with: url, placeholderImage: nil, options: [], context: [. `SDWebImagePDFCoder` provide an easy way to export the PDF image generated from framework, to the original PDF data. -Note: For firmware which is below iOS/tvOS 11+, UIImage does not support PDF vector image as well as exporting. The bitmap form of PDF does not support PDF data export as well. +If the input image is already vector PDF based, will export that instead (fast). +Else we will create an empty PDF page with the bitmap image drawn on (slow). + Objective-C ```objectivec 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]; -} +NSData *pdfData = [pdfImage sd_imageDataAsFormat:SDImageFormatPDF]; // May return the vector data, or create new PDF with current image drawn on ``` + Swift ```swift 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) -} +let pdfData = pdfImage.sd_imageData(as: .PDF) // May return the vector data, or create new PDF with current image drawn on ``` ## Screenshot diff --git a/SDWebImagePDFCoder/Classes/SDImagePDFCoder.m b/SDWebImagePDFCoder/Classes/SDImagePDFCoder.m index 3097454..446d053 100644 --- a/SDWebImagePDFCoder/Classes/SDImagePDFCoder.m +++ b/SDWebImagePDFCoder/Classes/SDImagePDFCoder.m @@ -62,7 +62,7 @@ - (UIImage *)decodedImageWithData:(NSData *)data options:(SDImageCoderOptions *) BOOL prefersBitmap = NO; CGSize imageSize = CGSizeZero; BOOL preserveAspectRatio = YES; - + // Parse args if (options[SDImageCoderDecodePDFPageNumber]) { pageNumber = [options[SDImageCoderDecodePDFPageNumber] unsignedIntegerValue]; @@ -101,20 +101,20 @@ - (BOOL)canEncodeToFormat:(SDImageFormat)format { - (NSData *)encodedDataWithImage:(UIImage *)image format:(SDImageFormat)format options:(SDImageCoderOptions *)options { if (![self.class supportsVectorPDFImage]) { - return nil; + return [self.class createPDFDataWithBitmapImage:image]; } #if SD_MAC // Pixel size use `NSImageRepMatchesDevice` to avoid CGImage bitmap format NSRect imageRect = NSMakeRect(0, 0, NSImageRepMatchesDevice, NSImageRepMatchesDevice); NSImageRep *imageRep = [image bestRepresentationForRect:imageRect context:nil hints:nil]; if (![imageRep isKindOfClass:NSPDFImageRep.class]) { - return nil; + return [self.class createPDFDataWithBitmapImage:image]; } return ((NSPDFImageRep *)imageRep).PDFRepresentation; #else CGPDFPageRef page = ((CGPDFPageRef (*)(id,SEL))[image methodForSelector:SDCGPDFPageSEL])(image, SDCGPDFPageSEL); if (!page) { - return nil; + return [self.class createPDFDataWithBitmapImage:image]; } // Draw the PDF page using PDFContextToData @@ -175,6 +175,26 @@ - (UIImage *)createVectorPDFWithData:(nonnull NSData *)data pageNumber:(NSUInteg return image; } +#pragma mark - Bitmap PDF creation ++ (NSData *)createPDFDataWithBitmapImage:(UIImage *)image { + CGImageRef imageRef = image.CGImage; + if (!imageRef) { + return nil; + } + NSMutableData *pdfData = [NSMutableData data]; + CGDataConsumerRef pdfConsumer = CGDataConsumerCreateWithCFData((__bridge CFMutableDataRef)pdfData); + + CGSize imageSize = CGSizeMake(CGImageGetWidth(imageRef), CGImageGetHeight(imageRef)); + CGRect mediaBox = CGRectMake(0, 0, imageSize.width, imageSize.height); + CGContextRef context = CGPDFContextCreate(pdfConsumer, &mediaBox, NULL); + + CGContextBeginPage(context, &mediaBox); + CGContextDrawImage(context, mediaBox, imageRef); + CGContextEndPage(context); + + return [pdfData copy]; +} + + (BOOL)supportsVectorPDFImage { #if SD_MAC // macOS's `NSImage` supports PDF built-in rendering