屏幕截屏的操作是項目中常見的,在很多項目中用于分享到第三方,在之前項目中寫了一篇文章生成分享的圖片,這里我們探討一下如何生成長圖。
iOS截圖(1)生成分享圖片
iOS截圖(3)截取網(wǎng)頁片段
下面我們來截取一張網(wǎng)頁的圖片,webView
是一個滾動視圖,在截圖時需要知道截圖的長度寬度,然后才能渲染上面的信息。例如,我們截取簡書的網(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了,接下來就要拼接圖片了,使用image
的drawInRect
方法畫一張。
[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)載請注明出處。