效果展示
“我是水印”的文字,還有心形氣泡組成的水印。
處理中的動態圖,上面是進度,下面是文字水印:“我是水印”,動態圖像水印:心形氣泡。
核心思路
- 1、UIView上面有UILabel(文字水印)和UIImageView(圖片水印),再通過GPUImageUIElement把UIView對象轉換成紋理對象,進入響應鏈;
- 2、視頻文件的圖像數據通過GPUImageMovie進入響應鏈;
- 3、GPUImageDissolveBlenderFilter合并水印圖像和視頻,把數據傳給響應鏈的終點GPUImageView以顯示到UI和GPUImageMovieWriter以寫入臨時文件;
- 4、視頻文件的音頻數據通過GPUImageMovie傳給GPUImageMovieWriter以寫入臨時文件;
- 5、最后臨時文件通過ALAssetsLibrary寫入系統庫。
具體細節
1、GPUImageUIElement
GPUImageUIElement繼承GPUImageOutput類,作為響應鏈的源頭。通過CoreGraphics把UIView渲染到圖像,并通過glTexImage2D綁定到outputFramebuffer指定的紋理,最后通知targets紋理就緒。
2、GPUImageOutput和GPUImageFilter
本次demo主要用到了frameProcessingCompletionBlock屬性,當GPUImageFilter渲染完紋理后,會調用frameProcessingCompletionBlock回調。
3、響應鏈解析
- 1、當GPUImageMovie的紋理就緒時,會通知GPUImageFilter處理圖像;
- 2、GPUImageFilter會調用frameProcessingCompletionBlock回調;
- 3、GPUImageUIElement在回調中渲染圖像,紋理就緒后通知
GPUImageDissolveBlendFilter; - 4、frameProcessingCompletionBlock回調結束后,通知
GPUImageDissolveBlendFilter紋理就緒; - 5、GPUImageDissolveBlendFilter收到兩個紋理后開始渲染,紋理就緒后通知GPUImageMovieWriter;
如圖
總結
本篇的內容與上一篇視頻水印有類似的地方。GPUImageUIElement是新的知識點,但是如果對CoreGraphics和OpenGL ES熟悉可以秒懂。
附上代碼
思考題
思考1:響應鏈解析中的GPUImageFilter有什么作用?是否可以去掉?
思考2:frameProcessingCompletionBlock里面需要做什么樣的操作?為什么?
思考3:能否對圖像水印進行復雜的位置變換?
答案
思考1:目的是每幀回調;去掉會導致圖像無法顯示。
思考2:回調需要調用update操作;因為update只會輸出一次紋理信息,只適用于一幀。
思考3:在回調中對UIView進行操作即可;或者使用GPUImageTransformFilter。