icon
一.前言
曾經(jīng)有個(gè)項(xiàng)目要求給實(shí)時(shí)畫面添加時(shí)間水印驾讲,當(dāng)時(shí)在老大的帶領(lǐng)下岔乔,使用的方案是ffmpeg+freetype瞻佛,但是這種方案有兩點(diǎn)不太好
- 性能問(wèn)題梅忌,視頻分辨率設(shè)置為1920*1080時(shí)就有點(diǎn)處理不過(guò)來(lái)并且CPU略高
-
水印看不清問(wèn)題
1.jpeg
因?yàn)槲覀兊臅r(shí)間水印是白色匕垫,這樣一旦背景是白色時(shí)僧鲁,就會(huì)導(dǎo)致水印看不到,當(dāng)時(shí)是給白色字體加了黑邊來(lái)規(guī)避這個(gè)問(wèn)題象泵,但是看到很多大廠都是用反色的方案
水印反色
二.實(shí)現(xiàn)思路
- 視頻畫面作為一路原始圖像輸入寞秃,背景透明的時(shí)間水印(背景的alpha值為0,時(shí)間字體的alpha值不為0)作為第二路的原始圖像輸入,然后判斷以下兩個(gè)條件同時(shí)成立偶惠,將時(shí)間水印的像素點(diǎn)變黑
- 時(shí)間水印背景不透明時(shí)(也就是當(dāng)前渲染的像素點(diǎn)為時(shí)間像素時(shí))
- 視頻背景為白色時(shí)
-
如何判斷視頻畫面為白色呢春寿,不會(huì)真的去判斷RGB三個(gè)像素都等于1.0把,這樣的代碼計(jì)算也太嚴(yán)格了點(diǎn)洲鸠,參考下面RGB轉(zhuǎn)YUV公式我們可以知道堂淡,當(dāng)RGB值都比較大時(shí),亮度分量Y的值也會(huì)比較大扒腕,因此這里我們用亮度分量Y來(lái)判斷绢淀,當(dāng)Y大于某個(gè)值時(shí),我們就覺得背景色比較白會(huì)導(dǎo)致我們的時(shí)間水印看不清了
RGB轉(zhuǎn)換YUV公式 - 采用OpenGL用GPU代替CPU的方式來(lái)做圖像處理瘾腰,增加效率
三.實(shí)現(xiàn)后的效果
3F1D8F41-8313-4B6A-A918-48F30A805528.jpeg
四.關(guān)鍵代碼
- 生成時(shí)間水印
- (UIImage *)string2image皆的;
- (char*)image2pixel:(CGImageRef)image;
- shader判斷當(dāng)背景亮度大于0.85時(shí)將時(shí)間像素變?yōu)楹谏?/li>
// gray是Y分量的大小
time = mix(time, vec4(vec3(0.0), time.a), step(0.85, gray));
- shader判斷當(dāng)時(shí)間水印像素點(diǎn)不透明度大于0.9時(shí)顯示時(shí)間水印像素蹋盆,否則顯示視頻畫面
time = mix(result, time, step(0.90, time.a));
五.遇到的問(wèn)題
- 用UIGraphicsBeginImageContextWithOptions開啟包含透明通道的位圖并用NSString的drawInRect畫字符串上去時(shí)以為只要有字符串的地方alpha一定是1.0费薄,然后判斷alpha只有為1.0時(shí)才顯示時(shí)間,結(jié)果導(dǎo)致時(shí)間水印顯示不全栖雾,后來(lái)一個(gè)像素一個(gè)像素去讀才發(fā)現(xiàn)并不是有時(shí)間像素的位置alpha一定是1.0
- 時(shí)間水印在OpenGL中的紋理環(huán)繞方式之前用的GL_REPEAT楞抡,結(jié)果導(dǎo)致時(shí)間水印顯示不出來(lái),改用GL_CLAMP_TO_EDGE后正常析藕,這個(gè)問(wèn)題是沒(méi)有找到原因的召廷,因?yàn)檫@兩個(gè)參數(shù)按道理是超出紋理坐標(biāo)后的貼圖方式,個(gè)人不覺得在這個(gè)Demo里會(huì)影響水印顯示的账胧,希望有高人能指出原因吧竞慢。
六.總結(jié)
- Demo在1920x1080 30fps 渲染時(shí)的CPU大概維持在百分之8左右,加入時(shí)間水印的邏輯后CPU大概在百分之14左右治泥,因此在性能上是沒(méi)問(wèn)題的
- OpenGL的學(xué)習(xí)個(gè)人感覺難度還是不小的筹煮,因?yàn)镺penGL的接口出錯(cuò)不那么好定位,而且稍微有調(diào)用接口順序不對(duì)居夹,就容易黑屏败潦,因此定位問(wèn)題需要更扎實(shí)的理論基礎(chǔ)本冲,繼續(xù)加強(qiáng)學(xué)習(xí)吧
- 剛開始學(xué)習(xí)OpenGL的同學(xué)可以跟著這位大神的博客,本人最開始學(xué)習(xí)就參考了他的很多文章及Demo
落影l(fā)oyinglin:OpenGLES
七.參考書籍及文章
天天P圖攻城獅:OpenGL shader性能優(yōu)化策略一減少分支語(yǔ)句
LearnOpenGL CN-紋理
Dev_Maskmale:iOS 開發(fā)之字符串轉(zhuǎn)圖片
書籍:音視頻開發(fā)進(jìn)階指南(基于Android與iOS平臺(tái)的實(shí)踐)