完整代碼查看# AndroidShaderDemo下的WaterMarkActivity
加個"Android Shader Demo"的文字水印,模擬器里跑的最終效果:
watermark.png
水印一般用圖片,原理就是把圖片作為紋理和之前的圖片混合。這里實現下文字水印,原理是先把文字寫入bitmap,再把bitmap當做紋理。
第一步,把文字寫入bitmap,這里封裝成TextTextureHelper,主要代碼如下:
public static Bitmap createBitmap(String text, int width, int height, int textSize){
Bitmap bitmap;
bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);//消除鋸齒
paint.setColor(Color.argb(255, 255, 255,255));
paint.setShadowLayer(1, 0, 1, Color.DKGRAY);
paint.setTextSize(textSize);
paint.setTextAlign(Paint.Align.CENTER);
canvas.drawText(text, width / 2,height/2 , paint);
return bitmap;
}
第二步渲染水印,這里把水印渲染封裝成WatermarkFilter,里面用到的private int texture就是上面生成的文字bitmap轉化成紋理。
渲染方法是:
public void onDrawFrame() {
glViewport(0, 0, width, height);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_DST_ALPHA);
watermarkProgram.useProgram();
watermarkProgram.setUniforms(texture);
vertexArray.setVertexAttribPointer(
0,
watermarkProgram.getPositionAttributeLocation(),
POSITION_COMPONENT_COUNT,
STRIDE);
vertexArray.setVertexAttribPointer(
POSITION_COMPONENT_COUNT,
watermarkProgram.getTextureCoordinatesAttributeLocation(),
TEXTURE_COORDINATES_COMPONENT_COUNT,
STRIDE);
GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4);
GLES20.glDisable(GLES20.GL_BLEND);
}
要注意的有兩點,首先設置ViewPort,表示水印被渲染的位置,當然還有通過矩陣變換設置水印位置的方法。接著就是設置混合方法。
最后設置下水印開關,如果水印打開,在CameraView的渲染主方法最后調用:
if(openWatermarkFilter){
watermarkFilter.onDrawFrame();
}