iOS上将图片转为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上。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章