公司最近提了個將 PPT 轉(zhuǎn)成圖片并顯示需求绩蜻,經(jīng)過各種查資料終于實現(xiàn),分享一下思路倦炒!
首先一個 UIView 對象要轉(zhuǎn)換成一張圖片获枝,我們可以使用如下代碼:
UIGraphicsBeginImageContext(boundsSize);
[view.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
于是我想到了使用可以展示 ppt 文件的 UIWebView 來展示 ppt 文件:
NSString* filePath = [[NSBundle mainBundle] pathForResource:@"iOS" ofType:@"pptx"];
NSURL *fileUrl = [NSURL fileURLWithPath:filePath];
UIWebView *webView = [[UIWebView alloc] initWithFrame:self.view.frame];
webView.scalesPageToFit = YES;
webView.scrollView.minimumZoomScale = 0;
webView.scrollView.maximumZoomScale = 1;
webView.delegate = self;
[self.view addSubview:webView];
[webView loadRequest:[NSURLRequest requestWithURL:fileUrl]];
接下來就是將 UIWebView 的每一個 page 渲染成一張圖片并保存!
渲染思路如下:
- 打印webview 的 html 闯割,并觀察html 文件的結(jié)構(gòu)
// 打印 html 文件
NSLog(@"%@", [webView stringByEvaluatingJavaScriptFromString:@"document.body.innerHTML"]);
// html 結(jié)構(gòu)
<div class="slide" style="position:absolute; overflow:hidden; top:0; left:0; width:959; height:540;">
<div class="slide" style="position:absolute; overflow:hidden; top:1635; left:0; width:959; height:540;">
...
- 觀察 html 文件我們發(fā)現(xiàn)每一頁 ppt 就是一個div class="slide"彻消,所以我們可以使用iOS 調(diào)用 js 代碼獲取到 ppt 的長寬,頂部位置以及 ppt 的總頁數(shù)等屬性
NSUInteger pageCount = [[webView stringByEvaluatingJavaScriptFromString:@"document.getElementsByClassName('slide').length"] intValue];
CGFloat height = [[webView stringByEvaluatingJavaScriptFromString:[NSString stringWithFormat:@"document.getElementsByClassName('slide')[%li].style.height", _currentPage]] floatValue];
CGFloat width= [[webView stringByEvaluatingJavaScriptFromString:[NSString stringWithFormat:@"document.getElementsByClassName('slide')[%li].style.width", _currentPage]] floatValue];
CGFloat offset = [[webView stringByEvaluatingJavaScriptFromString:[NSString stringWithFormat:@"document.getElementsByClassName('slide')[%li].style.top", _currentPage]] floatValue];
- 獲取到這些屬性后宙拉,我們可以設(shè)置webView的大小為 pdf 頁面的大小宾尚,webView 的 scrollView 的contentOffset,設(shè)置 webView 顯示的偏移谢澈。使用如下代碼為每一頁生成 UIImage
webView.bounds = CGRectMake(0, 0, width, height);
[webView.scrollView setContentOffset:CGPointMake(0, offset)];
UIGraphicsBeginImageContext(boundsSize);
[view.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
以上可實現(xiàn) PPT 轉(zhuǎn)成圖片功能
然而經(jīng)壓力測試發(fā)現(xiàn)黑屏閃退
md央勒,內(nèi)存泄露!
通過 instrument 測試發(fā)現(xiàn) [view.layer renderInContext:UIGraphicsGetCurrentContext()];內(nèi)存一直不釋放澳化!oh my god崔步!
查資料得出的思路
self.view.layer.contents = nil;
然而并沒有卵用
借鑒查找到的思路,最終我采取的策略是:每加載一次 webView 我只 render 一次缎谷, 移除掉 webView 然后再加載 webView 再 render
[webview removeFromSuperview];
webview = nil;
NSString* filePath = [[NSBundle mainBundle] pathForResource:@"iOS" ofType:@"pptx"];
NSURL *fileUrl = [NSURL fileURLWithPath:filePath];
UIWebView *webView = [[UIWebView alloc] initWithFrame:self.view.frame];
webView.scalesPageToFit = YES;
webView.scrollView.minimumZoomScale = 0;
webView.scrollView.maximumZoomScale = 1;
webView.delegate = self;
[self.view addSubview:webView];
[webView loadRequest:[NSURLRequest requestWithURL:fileUrl]];
這種做法雖然效率很低但是閃退的問題解決了井濒!
當(dāng)然也可以將粒度調(diào)高一點,比如每加載一次 webView列林,render 5頁或者10頁瑞你,這個可以根據(jù)個人需求去優(yōu)化!