[程序員日記]iOS截圖(2)生成長圖

屏幕截屏的操作是項目中常見的,在很多項目中用于分享到第三方,在之前項目中寫了一篇文章生成分享的圖片,這里我們探討一下如何生成長圖。

iOS截圖(1)生成分享圖片
iOS截圖(3)截取網(wǎng)頁片段

下面我們來截取一張網(wǎng)頁的圖片,webView是一個滾動視圖,在截圖時需要知道截圖的長度寬度,然后才能渲染上面的信息。例如,我們截取簡書的網(wǎng)頁。

打開網(wǎng)頁

iOS截圖(1)生成分享圖片中了解到,所謂截圖操作的實現(xiàn),是生成一個view,然后根據(jù)這個view生成圖片,生成圖片的方法是在兩個C語言函數(shù)中實現(xiàn)的。代碼寫在兩個函數(shù)中間。

UIGraphicsBeginImageContext(imageSize);
UIGraphicsEndImageContext();

與截取短圖不同的是,因為截取長圖,尤其是滾動視圖,我們能夠獲取到圖片的寬度(webView.scrollView.contentSize.width),高度(webView.scrollView.contentSize.height),但要如何截取,就要用到循環(huán),截取若干張圖片,然后拼接成一張。

NSMutableArray *images = [NSMutableArray array];
  while (contentHeight > 0) {
    UIGraphicsBeginImageContextWithOptions(boundsSize, NO, [UIScreen mainScreen].scale);
    [self.webView.layer renderInContext:UIGraphicsGetCurrentContext()];
    UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    [images addObject:image];

    CGFloat offsetY = self.webView.scrollView.contentOffset.y;
    [self.webView.scrollView setContentOffset:CGPointMake(0, offsetY + boundsHeight)];
    contentHeight -= boundsHeight;
  }

以上操作做完,截圖也就end了,接下來就要拼接圖片了,使用imagedrawInRect方法畫一張。

[images enumerateObjectsUsingBlock:^(UIImage *image, NSUInteger idx, BOOL *stop) {
[image drawInRect:CGRectMake(0,
              scale * boundsHeight * idx,
              scale * boundsWidth,
              scale * boundsHeight)];
  }];

最后生成的圖片就是這樣了。

生成圖片

[注]由于現(xiàn)在的網(wǎng)頁都做了適配,因此只考慮了寬度,對于上下左右均能滾動的網(wǎng)頁可以用雙重循環(huán)實現(xiàn),再根據(jù)寬度來個循環(huán)。

[補充]

WKWebView入坑

如果你用WKWebView使用這個方法,會發(fā)現(xiàn)最終截取的只有屏幕上顯示的一部分(還要感謝 特里并不獨行發(fā)現(xiàn)這個問題,對待上述內(nèi)容又有了一些新的探索),是因為UIWebView與WKWebView渲染機制的不同。

WKWebView的好處就不說了,省內(nèi)存,加載快等等,但正因如此,也導致了這個問題的解決方式有變。

在嘗試以上方法時發(fā)現(xiàn)對wkWebView操作時發(fā)現(xiàn)截取內(nèi)容中為空,有資料說wkWebView應使用- (BOOL)drawViewHierarchyInRect:(CGRect)rect afterScreenUpdates:(BOOL)afterUpdates;截圖,然而因為渲染機制對不同只能截取當前屏幕顯示的一部分,而其余區(qū)域空白。

在博客在我只是想要截個屏(續(xù))文章中,博主提出一種方法, 就是去截取WKWebView的父視圖, 因為無論WKWebView怎么改變, 通過WKWebView父視圖截圖是可以正確獲取對應的界面的。

通過優(yōu)化后大致的流程如下:
1.基于WKWebView的尺寸偽造一個UIView, 并拉長至ContentSize高度
2.將偽造的UIView作為WKWebView的父視圖
3.放置一張大畫布長度和WKWebView的ContentSize高度一致
4.對父視圖進行普通截圖并放置在大畫布中
5.將WKWebView的高度上移一個父視圖的高度
6.循環(huán)執(zhí)行步驟3和步驟4直到總高度和WKWebView的ContentSize高度一致
7.讀取畫布中的圖像并返回

參考內(nèi)容:

文章優(yōu)先發(fā)表于:http://keyliu.com
轉(zhuǎn)載請注明出處。

最后編輯于
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內(nèi)容

  • 發(fā)現(xiàn) 關注 消息 iOS 第三方庫、插件、知名博客總結 作者大灰狼的小綿羊哥哥關注 2017.06.26 09:4...
    肇東周閱讀 12,246評論 4 61
  • 人人都知道該跨學科學習,但往往不知道何處著手。少數(shù)人知道如何跨學科學習,但幾乎沒人分享出跨學科學習的實踐技巧。 本...
    陳素封閱讀 1,256評論 3 37
  • 睜開眼 你掉進我黑色的瞳仁 越陷越深 直入腦心 睜眼閉眼 都是你綽約身影! 從此 心門被你充盈 靈魂被你牽引 為你...
    平天下之文世界閱讀 158評論 1 8
  • 風水的原理其實就是四個字——「心生萬法」。 外在的事物影響了心,心反過來就會影響一切,所以改變風水從根本上講就是改...
    為_福慧閱讀 1,973評論 0 1