iOS 小知识iOS Developer

iOS PPT 转图片(UIImage)实现思路

2017-08-21  本文已影响476人  一只代码狗
公司最近提了个将 PPT 转成图片并显示需求,经过各种查资料终于实现,分享一下思路!

首先一个 UIView 对象要转换成一张图片,我们可以使用如下代码:

    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 渲染成一张图片并保存!
渲染思路如下:

    // 打印 html 文件
    NSLog(@"%@", [webView stringByEvaluatingJavaScriptFromString:@"document.body.innerHTML"]);
    // html 结构
    <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;">
...
    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];
  webView.bounds = CGRectMake(0, 0, width, height);
  [webView.scrollView setContentOffset:CGPointMake(0, offset)];
  UIGraphicsBeginImageContext(boundsSize); 
  [view.layer renderInContext:UIGraphicsGetCurrentContext()];
  UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
  UIGraphicsEndImageContext();

以上可实现 PPT 转成图片功能

然而经压力测试发现黑屏闪退

md,内存泄露!
通过 instrument 测试发现 [view.layer renderInContext:UIGraphicsGetCurrentContext()];内存一直不释放!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]];

这种做法虽然效率很低但是闪退的问题解决了!
当然也可以将粒度调高一点,比如每加载一次 webView,render 5页或者10页,这个可以根据个人需求去优化!

跪求Star
上一篇 下一篇

猜你喜欢

热点阅读