网上搜罗了一堆的美颜滤镜效果,可惜尽不如人意。最后偶然看到ios上提供了一个用OC写的美颜滤镜,好吧,改写成Java的试试。好在大学时期搞过一段时间IOS开发,用自己的半吊子的水平,没想到还真改成功了。
先上效果图:
网上搜涨痘痘的图片,搜到刘涛了,罪过罪过~
原图:
美颜后:
可见有四个可滑动的bar,从上到下分别是,磨皮度,磨皮值,美白,红润。
美颜原理
磨皮:本质就是让像素点模糊,可以使用高斯模糊,但是可能导致边缘会不清晰,用双边滤波(Bilateral Filter) ,有针对性的模糊像素点,能保证边缘不被模糊。
美白:本质就是提高亮度。
红润:本质就是改变色调。
Photoshop混合模式详解及中英文对照:http://www.jianshu.com/p/175631f45ec6
下面是滤镜源码:
import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.opengl.GLES20;
import android.opengl.GLSurfaceView;
import android.opengl.Matrix;
import android.view.WindowManager;
import com.ws.gl.opengltexture.programs.TextureShaderProgram;
import com.ws.gl.opengltexture.util.GLBitmapUtils;
import com.ws.gl.opengltexture.util.MatrixHelper;
import com.ws.gl.opengltexture.util.TextureHelper;
import com.ws.ijk.openglpicture.R;
import java.nio.FloatBuffer;
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;
public class BeautyRenderer implements GLSurfaceView.Renderer{
public static final String VERTEX_SHADER = "" +
"attribute vec4 vPosition;\n" +
"uniform mat4 vMatrix;\n"+
"attribute vec2 vCoordinate;\n" +
" \n" +
"varying vec2 textureCoordinate;\n" +
" \n" +
"void main()\n" +
"{\n" +
" gl_Position =vMatrix* vPosition;\n" +
" textureCoordinate = vCoordinate;\n" +
"}";
public static final String BILATERAL_FRAGMENT_SHADER = "" +
"precision highp float;\n"+
" varying highp vec2 textureCoordinate;\n" +
"\n" +
" uniform sampler2D vTexture;\n" +
"\n" +
" uniform highp vec2 singleStepOffset;\n" +
" uniform highp vec4 params;\n" +
" uniform highp float brightness;\n" +
" uniform float texelWidthOffset;\n"+
" uniform float texelHeightOffset;\n"+
"\n" +
" const highp vec3 W = vec3(0.299, 0.587, 0.114);\n" +
" const highp mat3 saturateMatrix = mat3(\n" +
" 1.1102, -0.0598, -0.061,\n" +
" -0.0774, 1.0826, -0.1186,\n" +
" -0.0228, -0.0228, 1.1772);\n" +
" highp vec2 blurCoordinates[24];\n" +
"\n" +
" highp float hardLight(highp float color) {\n" +
" if (color <= 0.5)\n" +
" color = color * color * 2.0;\n" +
" else\n" +
" color = 1.0 - ((1.0 - color)*(1.0 - color) * 2.0);\n" +
" return color;\n" +
"}\n" +
"\n" +
" void main(){\n" +
" highp vec3 centralColor = texture2D(vTexture, textureCoordinate).rgb;\n" +
" vec2 singleStepOffset=vec2(texelWidthOffset,texelHeightOffset);\n"+
" blurCoordinates[0] = textureCoordinate.xy + singleStepOffset * vec2(0.0, -10.0);\n" +
" blurCoordinates[1] = textureCoordinate.xy + singleStepOffset * vec2(0.0, 10.0);\n" +
" blurCoordinates[2] = textureCoordinate.xy + singleStepOffset * vec2(-10.0, 0.0);\n" +
" blurCoordinates[3] = textureCoordinate.xy + singleStepOffset * vec2(10.0, 0.0);\n" +
" blurCoordinates[4] = textureCoordinate.xy + singleStepOffset * vec2(5.0, -8.0);\n" +