iOS上将UIimage转为PDF
最近做项目遇到了这个需求,百度了一下发现还是12年的文章,使用了一下不好用,转为PDF后是空白的,开始Google查文件,现成功实现,效果如下图
1.是我本地的viewcontroller上面的一个view。显示一些请求的结果。可以用手势签名,等等巴拉巴拉的一堆
下面这个是转的时候
然后是打开模拟器的文件夹的PDF文件,看看效果图:
图片可能有点大 对付看吧。
可能看着有点模糊,是因为图片的原因,一会说下在哪里处理就行了。
准备工作:获取要转的image,图1是一个view,首先我是给他转成了一个图片,转成图片有两种方法,一个是view高度不超过屏幕的,一个是超过了屏幕的,我先都写上吧:
+ (UIImage *) snapshotWithScrollView:(UIScrollView *)scrollView{
UIImage* image = nil;
UIGraphicsBeginImageContext(scrollView.contentSize);
{
CGPoint savedContentOffset = scrollView.contentOffset;
CGRect savedFrame = scrollView.frame;
scrollView.contentOffset = CGPointZero;
scrollView.frame = CGRectMake(0, 0, scrollView.contentSize.width, scrollView.contentSize.height);
[scrollView.layer renderInContext: UIGraphicsGetCurrentContext()];
image = UIGraphicsGetImageFromCurrentImageContext();
scrollView.contentOffset = savedContentOffset;
scrollView.frame = savedFrame;
}
UIGraphicsEndImageContext();
if (image != nil) {
return image;
}
return nil;
}
+ (UIImage *)snapshotWithView:(UIView *)view
{
CGSize size = view.bounds.size;
UIGraphicsBeginImageContextWithOptions(size, YES, 0);
[view drawViewHierarchyInRect:view.bounds afterScreenUpdates:YES];
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return image;
}
在得到了image之后,要开始干活了,首先,生成一个图片,我要保存到本地,然后拿到他的URL,使用alassets这个框架
#import <AssetsLibrary/AssetsLibrary.h>
ProStrong ALAssetsLibrary *library;//将它定义为属性,原因下面写了
#define kPadding 20
.
.
.
//上面一堆初始化各种方法的代码不贴了
- (void)saveImage:(UIImage *)image{
//ALAssetsLibrary如果是临时对象。执行完毕就会释放 保存的aseturl就会失效,找不到目标图片了,所以要声明成属性
self.library = [[ALAssetsLibrary alloc] init];
[self.library writeImageToSavedPhotosAlbum:image.CGImage metadata:nil completionBlock:^(NSURL *assetURL, NSError *error) {
NSLog(@"assetURL = %@, error = %@", assetURL, error);
self.saveImagePath = assetURL;
[self turnSelfViewToPDF];
}];
}
保存完图片后在回调内拿到存储的URL。就是self.library这个对象将这个图片存储的地址,不能让library是否,否则地址会失效
第二步:
-(void)turnSelfViewToPDF{
ALAssetsLibrary *assetslibrary = [[ALAssetsLibrary alloc] init];
[assetslibrary assetForURL:self.saveImagePath
resultBlock:^(ALAsset *asset){
//根据URL取到图片
ALAssetRepresentation *rep = [asset defaultRepresentation];
CGImageRef iref = [rep fullScreenImage];
if (iref) {
UIImage *image = [UIImage imageWithCGImage:iref];
[self setupPDFDocumentNamed:self.recordId width:screenWidth height:self.bgScrollView.contentSize.height];
[self addImage:image
atPoint:CGPointMake((_pageSize.width/2)-(image.size.width/2), kPadding)];
NSFileManager *manager = [NSFileManager defaultManager];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES);
NSString *path = [paths lastObject];
NSString * path1 = [path stringByAppendingPathComponent:[NSString stringWithFormat:@"%@.pdf",self.recordId]];
if ([manager fileExistsAtPath:path1]) {
[SVProgressHUD showMessage:@"生成PDF文件成功"];
}else{
[SVProgressHUD showMessage:@"生成PDF文件失败"];
}
}
}
failureBlock:^(NSError *error) {
NSLog(@"从图库获取图片失败: %@",error);
}];
}
- (void)setupPDFDocumentNamed:(NSString*)name width:(float)width height:(float)height {
//设置存储的PDFframe,默认我传的屏幕宽高,根据你的情况改变
_pageSize = CGSizeMake(width, height);
//根据传进来的文件名字 创建文件夹,在内部存储PDF文件
NSString *newPDFName = [NSString stringWithFormat:@"%@.pdf",name];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *pdfPath = [documentsDirectory stringByAppendingPathComponent:newPDFName];
//开始绘制PDF
UIGraphicsBeginPDFContextToFile(pdfPath, CGRectZero, nil);
UIGraphicsBeginPDFPageWithInfo(CGRectMake(0, 0, _pageSize.width, _pageSize.height), nil);
}
- (void)addImage:(UIImage*)image atPoint:(CGPoint)point {
//向PDF内添加图片
CGRect imageFrame = CGRectMake(point.x, point.y, image.size.width, image.size.height);
[image drawInRect:imageFrame];
UIGraphicsEndPDFContext();
}
以上就是基本的图片转PDF的方法,亲测可用,效果杠杠的
其他:你的领导可能让你在转PDF的时候要给PDF润色啦,加个title啦,加个题记,巴拉巴拉的,所以先写一个在PDF文件最上方加title和一个红色细线的方法,心急的朋友可略过此步骤:
- (CGRect)addText:(NSString*)text withFrame:(CGRect)frame fontSize:(float)fontSize {
UIFont *font = [UIFont systemFontOfSize:fontSize];
NSMutableParagraphStyle *style1 = [NSMutableParagraphStyle new];
style1.lineBreakMode = NSLineBreakByWordWrapping;
CGSize stringSize = [text boundingRectWithSize:_pageSize options:NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading attributes:@{NSParagraphStyleAttributeName:style1} context:nil].size;
float textWidth = frame.size.width;
if (textWidth < stringSize.width)
textWidth = stringSize.width;
if (textWidth > _pageSize.width)
textWidth = _pageSize.width - frame.origin.x;
CGRect renderingRect = CGRectMake(frame.origin.x, frame.origin.y, textWidth, stringSize.height);
NSMutableParagraphStyle *style = [NSMutableParagraphStyle new];
style.lineBreakMode = NSLineBreakByWordWrapping;
style.alignment = NSTextAlignmentLeft;
[text drawInRect:renderingRect withAttributes:@{NSFontAttributeName:font,NSParagraphStyleAttributeName:style}];
frame = CGRectMake(frame.origin.x, frame.origin.y, textWidth, stringSize.height);
return frame;
}
然后在这行文字下面加个醒目的线条:
- (CGRect)addLineWithFrame:(CGRect)frame withColor:(UIColor*)color {
CGContextRef currentContext = UIGraphicsGetCurrentContext();
CGContextSetStrokeColorWithColor(currentContext, color.CGColor);
CGContextSetLineWidth(currentContext, frame.size.height);
CGPoint startPoint = frame.origin;
CGPoint endPoint = CGPointMake(frame.origin.x + frame.size.width, frame.origin.y);
CGContextBeginPath(currentContext);
CGContextMoveToPoint(currentContext, startPoint.x, startPoint.y);
CGContextAddLineToPoint(currentContext, endPoint.x, endPoint.y);
CGContextClosePath(currentContext);
CGContextDrawPath(currentContext, kCGPathFillStroke);
return frame;
}
然后调用生成PDF的方法就会是这样:
-(void)turnSelfViewToPDF{
ALAssetsLibrary *assetslibrary = [[ALAssetsLibrary alloc] init];
[assetslibrary assetForURL:self.saveImagePath
resultBlock:^(ALAsset *asset){
ALAssetRepresentation *rep = [asset defaultRepresentation];
CGImageRef iref = [rep fullScreenImage];
if (iref) {
UIImage *image = [UIImage imageWithCGImage:iref];
[self setupPDFDocumentNamed:self.recordId width:screenWidth height:self.bgScrollView.contentSize.height];
//顶部添加title
CGRect textRect = [self addText:@"这里是标题,呵呵呵呵呵呵" withFrame:CGRectMake(kPadding, kPadding, 400, 200) fontSize:48.0f];
//在title下面画线
CGRect blueLineRect = [self addLineWithFrame:CGRectMake(kPadding, textRect.origin.y + textRect.size.height + kPadding, _pageSize.width - kPadding*2, 4) withColor:[UIColor blueColor]];
//在线下面添加图片
[self addImage:anImage
atPoint:CGPointMake((_pageSize.width/2)-(anImage.size.width/2), blueLineRect.origin.y + blueLineRect.size.height + kPadding)]
NSFileManager *manager = [NSFileManager defaultManager];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES);
NSString *path = [paths lastObject];
NSString * path1 = [path stringByAppendingPathComponent:[NSString stringWithFormat:@"%@.pdf",self.recordId]];
if ([manager fileExistsAtPath:path1]) {
[SVProgressHUD showMessage:@"生成PDF文件成功"];
}else{
[SVProgressHUD showMessage:@"生成PDF文件失败"];
}
}
}
failureBlock:^(NSError *error) {
NSLog(@"从图库获取图片失败: %@",error);
}];
}
最底部还可以调用addline的方法来添加线。不过要获得image的y,可以改变addimage的方法的返回值让他返回imageframe,然后把UIGraphicsEndPDFContext()拿到这里来结束PDF生成即可。有不懂的留言问吧
demo正在做,做好了会更新文章放到github上。