iOS | PPT 转图片(UIImage) 解决方案

为了实现PPT 转 图片功能, 首先来看下,iOS系统 有哪些API可以实现PPT预览功能;

iOS 预览PPT 3种方式:

1. UIWebView / wkwebView

通过 UIWebViewwkwebView 可以简单实现PPT 或 office 系列文档的预览功能,代码如下,非常简单:

 NSString * filePath = [[NSBundle mainBundle] pathForResource:@"IOS.pptx" ofType:nil];
 NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL fileURLWithPath:pptFileUrl]];
 //...webView 创建省略...
 [self.webView loadRequest:request];


2. QLPreveiewController

QLPreveiewController 是IOS4.0后,apple推出新的文件预览控件,可以实现在线预览ppt,word,excel,pdf等文件的功能, 使用方法同UITableViewController 类似,创建一个控制器继承QLPreveiewController, 并实现其数据源方法,代码如下:

// .h
#import <UIKit/UIKit.h>
#import <QuickLook/QuickLook.h>

@interface TestViewController : QLPreviewController
@end

// .m
#import "TestViewController.h"

@interface TestViewController ()<QLPreviewControllerDataSource,QLPreviewControllerDelegate>
@end

@implementation TestViewController
- (void)viewDidLoad {
    [super viewDidLoad];
    self.dataSource = self;
    self.delegate = self;
}
- (NSInteger)numberOfPreviewItemsInPreviewController:(QLPreviewController *)controller{
    return 1;
}
- (id <QLPreviewItem>)previewController: (QLPreviewController *)controller previewItemAtIndex:(NSInteger)index{
     NSString * filePath = [[NSBundle mainBundle] pathForResource:@"IOS.pptx" ofType:nil];
     return [NSURL fileURLWithPath:filePath];
}
@end


3.UIDocumentInteractionController

UIDocumentInteractionController是从ios 3.2的sdk开始支持的,他是直接继承自NSObject,因此需要UIDocumentInteractionController提供的方法来展示他, 使用方法也极其简单,需要实现 <UIDocumentInteractionControllerDelegate>协议, 代码如下;

- (void)viewDidLoad {
    [super viewDidLoad];
    NSString * filePath = [[NSBundle mainBundle] pathForResource:@"IOS.pptx" ofType:nil];
    UIDocumentInteractionController *documentController = [UIDocumentInteractionController interactionControllerWithURL:[NSURL fileURLWithPath:filePath]];
    documentController.delegate = self;
    [documentController presentPreviewAnimated:YES];
}
- (UIViewController *)documentInteractionControllerViewControllerForPreview:(UIDocumentInteractionController *)controller{
    return self;
}

上述3种方法,都可以实现PPT等文档的本地查看预览功能, 方法2和方法3,再带有分享分档功能,使用起来都很简单, 接下来我们介绍一下如何将PPT转图片:


PPT 转 Image

问题分析:

  1. 虽然 iOS 为我们提供了多种本地查看预览PPT的功能模块, 但是上述的3种方式,系统都没有提供什么附加信息用于获取每一页PPT的信息,更谈不上转图片了.

  2. WebView 在展示PPT的时候, WebView会将PPT转为相应的HTML代码,然后在放入 WebView 进行展示, 我们可以看一下生成的 html 代码,通过运行JS代码,可以获取页面的HTML代码 :

运行如下代码,即可获取页面的 html 代码信息:

[self.webView stringByEvaluatingJavaScriptFromString:@"document.documentElement.innerHTML"]

获取到得 html 信息如下, 只粘贴了部分结构:


    <!-- 页面一 -->
    <div class="slide" style="top:0; left:0;">
        <div class="s0"></div><img
            src="x-apple-ql-id://1F090401-1846-46C8-863A-5DC9BAA53ED7/x-apple-ql-magic/A979BC4A-42E4-4823-9CB0-8CF19D91D4D2.jpg"
            style="position:absolute; top:22; left:84; width:792; height:495;">
    </div>
    <!-- 页面二 -->
    <div class="slide" style="top:0; left:0;">
        <div class="s0"></div>
        <div style="position:absolute; top:32; left:49; width:861; height:423;">
            <div class="s2">
                <div class="s1">
                    <p style="text-align:center; line-height:3.120000; padding-bottom:0px; font-family:&quot;(null)&quot;; font-size:44;">
                        <span style="color:#000000; font-size:44; font-family:&quot;(null)&quot;;">hello.world!</span>
                    </p>
                </div>
            </div>
        </div>
    </div>
    <!-- 页面三 -->
    <div class="slide" style="top:0; left:0;">
        <div class="s0"></div>
        <div style="position:absolute; top:21; left:48; width:864; height:90;">
            <div class="s3">
                <div class="s1">
                    <p style="text-align:center; padding-bottom:0px; font-family:&quot;(null)&quot;; font-size:44;">
                        <span style="color:#000000; font-size:44; font-family:&quot;(null)&quot;;">测试</span></p>
                </div>
            </div>
        </div><img
            src="x-apple-ql-id://0AF5CA5C-5685-4D8F-9503-2FBF3A206542/x-apple-ql-magic/CAA89CFD-5597-4A35-A6CB-85C050BA2A6A.png"
            style="position:absolute; top:124; left:292; width:340; height:340;">
    </div>
    
    <!-- 其他页面.... -->

我们可以发现规律,每一个PPT 都在一个 div元素内, 对应类选择器为 slide!

  1. 通过运行JS代码,我们来获取一下PPT的页数,以及每一页的尺寸信息

获取PPT页数信息

NSInteger pageCount = [[self.webView stringByEvaluatingJavaScriptFromString:@"document.getElementsByClassName('slide').length"] integerValue];

获取PPT每一页的长宽:

// PPT 宽度
 NSInteger pageWidth = [[self.webView stringByEvaluatingJavaScriptFromString:@"parseInt(window.getComputedStyle(document.getElementsByClassName('slide')[0]).width)"] integerValue];

// PPT高度
NSInteger pageHeight = [[self.webView stringByEvaluatingJavaScriptFromString:@"parseInt(window.getComputedStyle(document.getElementsByClassName('slide')[0]).height)"] integerValue];
  1. 将PPT 展示到 WebView 后,然后通过iOS绘制, 来将每一页PPT保存到本地

绘制代码如下

- (UIImage* )imageWithView:(UIView *)view frame:(CGRect)frame{
    @autoreleasepool {
        UIGraphicsBeginImageContextWithOptions(frame.size, YES, 0.0);
        CGContextRef context = UIGraphicsGetCurrentContext();
        if (!context) {
            return nil;
        }
        [view.layer renderInContext:context];
        UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
        UIGraphicsEndImageContext();
        NSData *imageData = UIImageJPEGRepresentation(image,0.6);
        UIImage *resultImage = [UIImage imageWithData:imageData];
        return resultImage;
    }
}

以上就是通过PPT转图片的大概的一个流程!



我将以上代码进行了简单封装,下面介绍一下使用步骤

使用步骤:

  1. 导入 头文件
#import "PPTToImageTool.h"
  1. 传入PPT本地 url, 获取 转换后的 image 图片
 // 获取本地 ppt url 地址
    NSString * filePath = [[NSBundle mainBundle] pathForResource:@"IOS.pptx" ofType:nil];
    
    // block 内部使用__weakself
    __weak __typeof(self)weakSelf = self;
    
    // 进行 ppt 转换
    [self.toImagetool pptToImageWithPPTFileUrl:filePath
                                      progress:^(CGFloat value) {
                                          
                                          NSLog(@"进度-------%f", value);
                                          
                                      } completion:^(NSArray * _Nonnull images) {
                                          
                                          NSLog(@"转换后图片信息-------%@",images);
                                          weakSelf.imageListView.images = images;
                                          [weakSelf.imageListView reloadData];
                                      }];

是不是非常简单....

踩坑总结

发现webView可以获取 html 代码后, 想着看能否通过 js 实现 html 区域转图片, 使用比较火的 js 三方库html2canvas进行转图片操作, 在写了一套转图片的js代码, 测试浏览器上运行都没啥问题, 但是到了 移动端,由于 html 的同源策略, 就会出现本地图片无法 截取的问题,以及 webView 生成的 html 不是很规范,导致被放弃!

demo 地址: https://github.com/liuchuan-alex/PPTToImage

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,847评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,208评论 1 292
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,587评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,942评论 0 205
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,332评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,587评论 1 218
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,853评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,568评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,273评论 1 242
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,542评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,033评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,373评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,031评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,073评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,830评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,628评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,537评论 2 269

推荐阅读更多精彩内容