我们有个需求,h5传过来base64数据,客户端加载PDF,然后把PDF转换图片分享出去。
我之前做过view转图片,于是我就用WKWebview 去加载PDF,然后准备把wkwebview的scrollview转成图片分享出去。
结果在view转图片的时候出问题了。只要WKWebview加载了PDF 就截图截不出来。搜了好多资料,都没解决。
后来问了我一个同学,他说他那边可以,最后发现用的是uiwebview。这肯定不行,这东西都弃用了,然后他也找资料,最后给我一张解释。
也就是说解决不了。
后面又找资料,最后同学给了两个方法,
第一个在iOS11以上可以截图。
- (void)takeSnapshotCompleted:(void(^)(UIImage *image))completed
{
if (@available(iOS 11.0, *)) {
WKSnapshotConfiguration *congif = [[WKSnapshotConfiguration alloc] init];
congif.rect = self.webView.bounds;
[self.webView takeSnapshotWithConfiguration:congif completionHandler:^(UIImage * _Nullable snapshotImage, NSError * _Nullable error) {
if (completed) {
completed(snapshotImage);
}
}];
} else {
// Fallback on earlier versions
if (completed) {
completed(nil);
}
}
}
还有另外一个方法yykit里的, 用这个方法把pdf直接读出来截取。这样调用[self _yy_imageWithPDF:dataOrPath resize:NO size:CGSizeZero];
-
(UIImage *)_yy_imageWithPDF:(id)dataOrPath resize:(BOOL)resize size:(CGSize)size {
CGPDFDocumentRef pdf = NULL;
if ([dataOrPath isKindOfClass:[NSData class]]) {
CGDataProviderRef provider = CGDataProviderCreateWithCFData((__bridge CFDataRef)dataOrPath);
pdf = CGPDFDocumentCreateWithProvider(provider);
CGDataProviderRelease(provider);
} else if ([dataOrPath isKindOfClass:[NSString class]]) {
pdf = CGPDFDocumentCreateWithURL((__bridge CFURLRef)[NSURL fileURLWithPath:dataOrPath]);
}
if (!pdf) return nil;CGPDFPageRef page = CGPDFDocumentGetPage(pdf, 1);
if (!page) {
CGPDFDocumentRelease(pdf);
return nil;
}CGRect pdfRect = CGPDFPageGetBoxRect(page, kCGPDFCropBox);
CGSize pdfSize = resize ? size : pdfRect.size;
CGFloat scale = [UIScreen mainScreen].scale;
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
CGContextRef ctx = CGBitmapContextCreate(NULL, pdfSize.width * scale, pdfSize.height * scale, 8, 0, colorSpace, kCGBitmapByteOrderDefault | kCGImageAlphaPremultipliedFirst);
if (!ctx) {
CGColorSpaceRelease(colorSpace);
CGPDFDocumentRelease(pdf);
return nil;
}CGContextScaleCTM(ctx, scale, scale);
CGContextTranslateCTM(ctx, -pdfRect.origin.x, -pdfRect.origin.y);
CGContextDrawPDFPage(ctx, page);
CGPDFDocumentRelease(pdf);CGImageRef image = CGBitmapContextCreateImage(ctx);
UIImage *pdfImage = [[UIImage alloc] initWithCGImage:image scale:scale orientation:UIImageOrientationUp];
CGImageRelease(image);
CGContextRelease(ctx);
CGColorSpaceRelease(colorSpace);return pdfImage;
}
这两方法都可以。但是也是不满足我的需求,我们写的是WeexComponents 组件,截图组件和PDF组件是分开的。h5那边 把PDF的组件加到截图的组件上,h5按钮触发截屏组件里的事件 进行截图,换句话说,截图的组件里,拿不到加载PDF的wkwebview 没法截取PDF的图片。
后来没办法了,就想起之前写PDF涂鸦 的那套加载PDF的方式了。
终极大招 CGPDFDocumentRef。其实这个加载PDF方式和yykit是一样,只不过yykit的代码是别人贴给我的,我没仔细研究过yykit。CGPDFDocumentRef这个加载方式是我自己找资料实现的。
//通过url获取CGPDFDocumentRef 然后去加载
-
(CGPDFDocumentRef)pdfRefByFilePath:(NSString *)aFilePath {
CFStringRef path;
CFURLRef url;
CGPDFDocumentRef document;path = CFStringCreateWithCString(NULL, [aFilePath UTF8String], kCFStringEncodingUTF8);
url = CFURLCreateWithFileSystemPath(NULL, path, kCFURLPOSIXPathStyle, NO);
document = CGPDFDocumentCreateWithURL(url);CFRelease(path);
CFRelease(url);return document;
}
怎么用CGPDFDocumentRef加载PDF,我这里的代码很乱,大家还是自己百度写下,反正就是用CGPDFDocumentRef的方式去加载PDF。这种方式就和wkwebview 没关系了。所以在截图的组件里 就可以view转图片了。
大家可以用yykit的就可以。或者自己百度用CGPDFDocumentRef加载pdf然后就能截图了。
如果帮到了您,动下金手指,点个赞。
最后 感谢我栋栋大哥。