JS 骨骼動畫 (DragonBones) 在 iOS 端截屏功能

需求背景:

使用 DragonBones 在 Webview 中繪制骨骼動畫,并對當(dāng)前的骨骼頁面進(jìn)行圖層截取,實(shí)現(xiàn)保存本地和分享功能。

問題:

使用 DragonBones 制作骨骼動畫時(shí)遇到一個(gè)問題,使用 WKWebView 加載骨骼動畫正常,再對 WKWebView 的父容器 view (控制器 view )進(jìn)行截圖是出現(xiàn)空白。

解決思路及方案一:

通過資料查閱,發(fā)現(xiàn) WKWebView 在截圖時(shí)比較特殊,需要調(diào)用 UIView 的分類,也就是

- (nullable UIView *)snapshotViewAfterScreenUpdates:(BOOL)afterUpdates NS_AVAILABLE_IOS(7_0);

進(jìn)行View圖層的快照獲取,推測和 WKWebView 的渲染原理相關(guān)。因?yàn)檎A鞒潭际峭ㄟ^ UIGraphics 去捕捉 UIView 的上下文來生成 UIImage 對象,進(jìn)而分享或保存到本地。

+ (UIImage *)getSharingImageWithView:(UIView *)originView {
    UIImage *snapshotImage = nil;
    UIGraphicsBeginImageContextWithOptions(originView.bounds.size, NO, [UIScreen mainScreen].scale);
    [originView.layer renderInContext:UIGraphicsGetCurrentContext()];
    snapshotImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return snapshotImage;
}

對 WkWebView、TableView 等滾動視圖循環(huán)截屏可參考 TYSnapshotScroll。
當(dāng)然,例如 TYSnapshotScroll 提供的 WKWebView 截圖方式(snapshotViewAfterScreenUpdates)截取方式對類似 github、google 等首頁的截取非常完美。

但是,在加載骨骼動畫時(shí)只有動畫背景,沒有任務(wù)形象。

解決思路及方案二:

根據(jù)從安卓和前端收集的信息來看:

  1. h5 骨骼動畫底層使用了 canvas 繪圖(一個(gè)類似于 iOS CoreGraphic 的庫,專門負(fù)責(zé)繪制復(fù)雜圖形。)
  2. JavaScript 使用 canvas 繪圖時(shí),會存在這樣的關(guān)系,直接上圖
canvas 的七大姑八大姨
  1. 上圖中最有價(jià)值的線索是,canvas 會調(diào)用 webGL 進(jìn)行渲染,同時(shí)會調(diào)用硬件加速功能
  2. 安卓端在手動關(guān)閉硬件加速后,該頁面截屏恢復(fù)正常。

然鵝,只有 Safari 中有對 WebGL 有控制權(quán),WKWebView 并不能通過代碼關(guān)閉硬件加速。
所以只能放棄使用 canvas 動態(tài)繪制的 webView 進(jìn)行圖像提取。

所以,我們采取了采取了雙端結(jié)合的思路:

  • 由 JavaScript 通過 canvas 輸出 base64 圖片字符串,以及人物背景圖片的URL
    JavaScript生成圖片:
var fullQuality = canvas.toDataURL('image/jpeg', 1.0); // 參數(shù)二控制圖片質(zhì)量
// data:image/jpeg;base64,/9j/4AAQSkZJRgABAQ...9oADAMBAAIRAxEAPwD/AD/6AP/Z"
var mediumQuality = canvas.toDataURL('image/jpeg', 0.5);
var lowQuality = canvas.toDataURL('image/jpeg', 0.1);

Native 解析圖片:

NSData *decodedImageData = [NSData dataWithContentsOfURL:[NSURL URLWithString:base64String]];
UIImage *decodedImage = [UIImage imageWithData:decodedImageData
                                         scale:[UIScreen mainScreen].scale];
personImageView.image = decodedImage;
  • 由 Native 對使用這些資源進(jìn)行布局渲染,并且控制截屏?xí)r用戶信息、二維碼等元素的展示,效果如圖:
骨骼動畫截屏

總結(jié)

對于部分特殊控件的圖像處理可能要會出現(xiàn)位置的異常,需要對對應(yīng)的底層實(shí)現(xiàn)技術(shù)點(diǎn)進(jìn)行剖析,倒推引起的原因。

參考:

HTML5 Canvas,WebGL,CSS Shaders,GLSL的曖昧關(guān)系
egret
dragonBone

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 發(fā)現(xiàn) 關(guān)注 消息 iOS 第三方庫、插件、知名博客總結(jié) 作者大灰狼的小綿羊哥哥關(guān)注 2017.06.26 09:4...
    肇東周閱讀 15,021評論 4 61
  • 1、先謀生,再謀愛 2、學(xué)會自我治愈,是生活的必修課 就像馮侖說過的:偉大,都是熬出來的。生活中走得遠(yuǎn)的,都是自愈...
    羅沫沫66閱讀 1,708評論 0 0
  • 兩歲五個(gè)多月的可可什么都要自己來?!拔易约簛??!拔铱梢缘摹!薄拔視摹!背商鞉煸谧爝?。行,你盡管做,爛攤子...
    往事回首閱讀 169評論 0 0
  • 柯達(dá)是在大學(xué)微信群里得知陸珈然已經(jīng)結(jié)婚的。在過去一個(gè)小時(shí)的唇槍舌戰(zhàn)里,柯達(dá)覺得自己的腦細(xì)胞大量死亡,喉嚨里像被生生...
    張未眠閱讀 455評論 0 3

友情鏈接更多精彩內(nèi)容