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上。

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