完整代码查看# AndroidShaderDemo下的WaterMarkActivity
加个"Android Shader Demo"的文字水印,模拟器里跑的最终效果:
水印一般用图片,原理就是把图片作为纹理和之前的图片混合。这里实现下文字水印,原理是先把文字写入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();
}