diff --git a/CameraFilter/src/main/java/com/frank/camerafilter/factory/BeautyFilterFactory.java b/CameraFilter/src/main/java/com/frank/camerafilter/factory/BeautyFilterFactory.java index ef67a70..be5ceb6 100644 --- a/CameraFilter/src/main/java/com/frank/camerafilter/factory/BeautyFilterFactory.java +++ b/CameraFilter/src/main/java/com/frank/camerafilter/factory/BeautyFilterFactory.java @@ -2,7 +2,7 @@ package com.frank.camerafilter.factory; import android.content.Context; -import com.frank.camerafilter.filter.advance.BeautyCrayonFilter; +import com.frank.camerafilter.filter.advance.BeautyHueFilter; import com.frank.camerafilter.filter.advance.BeautySketchFilter; import com.frank.camerafilter.filter.BaseFilter; @@ -15,8 +15,8 @@ public class BeautyFilterFactory { switch (type) { case SKETCH: return new BeautySketchFilter(context); - case CRAYON: - return new BeautyCrayonFilter(context); + case HUE: + return new BeautyHueFilter(context); default: return null; } diff --git a/CameraFilter/src/main/java/com/frank/camerafilter/factory/BeautyFilterType.java b/CameraFilter/src/main/java/com/frank/camerafilter/factory/BeautyFilterType.java index bdc350e..47f9040 100644 --- a/CameraFilter/src/main/java/com/frank/camerafilter/factory/BeautyFilterType.java +++ b/CameraFilter/src/main/java/com/frank/camerafilter/factory/BeautyFilterType.java @@ -2,6 +2,6 @@ package com.frank.camerafilter.factory; public enum BeautyFilterType { NONE, - CRAYON, + HUE, SKETCH } diff --git a/CameraFilter/src/main/java/com/frank/camerafilter/filter/advance/BeautyCrayonFilter.java b/CameraFilter/src/main/java/com/frank/camerafilter/filter/advance/BeautyCrayonFilter.java deleted file mode 100644 index a239e6c..0000000 --- a/CameraFilter/src/main/java/com/frank/camerafilter/filter/advance/BeautyCrayonFilter.java +++ /dev/null @@ -1,42 +0,0 @@ -package com.frank.camerafilter.filter.advance; - -import android.content.Context; -import android.opengl.GLES20; - -import com.frank.camerafilter.R; -import com.frank.camerafilter.filter.BaseFilter; -import com.frank.camerafilter.util.OpenGLUtil; - -public class BeautyCrayonFilter extends BaseFilter { - - // 1.0--5.0 - private int mStrengthLocation; - - private int mStepOffsetLocation; - - public BeautyCrayonFilter(Context context) { - super(NORMAL_VERTEX_SHADER, OpenGLUtil.readShaderFromSource(context, R.raw.crayon)); - } - - protected void onInit() { - super.onInit(); - mStrengthLocation = GLES20.glGetUniformLocation(getProgramId(), "strength"); - mStepOffsetLocation = GLES20.glGetUniformLocation(getProgramId(), "singleStepOffset"); - } - - protected void onInitialized() { - super.onInitialized(); - setFloat(mStrengthLocation, 2.0f); - } - - @Override - public void onInputSizeChanged(int width, int height) { - super.onInputSizeChanged(width, height); - setFloatVec2(mStepOffsetLocation, new float[] {1.0f / width, 1.0f / height}); - } - - protected void onDestroy() { - super.onDestroy(); - } - -} diff --git a/CameraFilter/src/main/java/com/frank/camerafilter/filter/advance/BeautyHueFilter.java b/CameraFilter/src/main/java/com/frank/camerafilter/filter/advance/BeautyHueFilter.java new file mode 100644 index 0000000..824ffe9 --- /dev/null +++ b/CameraFilter/src/main/java/com/frank/camerafilter/filter/advance/BeautyHueFilter.java @@ -0,0 +1,33 @@ +package com.frank.camerafilter.filter.advance; + +import android.content.Context; +import android.opengl.GLES30; + +import com.frank.camerafilter.R; +import com.frank.camerafilter.filter.BaseFilter; +import com.frank.camerafilter.util.OpenGLUtil; + +public class BeautyHueFilter extends BaseFilter { + + private int hueAdjust; + + public BeautyHueFilter(Context context) { + super(NORMAL_VERTEX_SHADER, OpenGLUtil.readShaderFromSource(context, R.raw.hue)); + } + + protected void onInit() { + super.onInit(); + hueAdjust = GLES30.glGetUniformLocation(getProgramId(), "hueAdjust"); + } + + protected void onInitialized() { + super.onInitialized(); + setFloat(hueAdjust, 3.0f); + } + + @Override + public void onInputSizeChanged(int width, int height) { + super.onInputSizeChanged(width, height); + } + +} diff --git a/CameraFilter/src/main/res/raw/crayon.glsl b/CameraFilter/src/main/res/raw/crayon.glsl deleted file mode 100644 index b477a6d..0000000 --- a/CameraFilter/src/main/res/raw/crayon.glsl +++ /dev/null @@ -1,53 +0,0 @@ -varying highp vec2 textureCoordinate; -precision mediump float; - -uniform sampler2D inputImageTexture; -uniform vec2 singleStepOffset; -uniform float strength; - -const highp vec3 W = vec3(0.299,0.587,0.114); - -const mat3 rgb2yiqMatrix = mat3( - 0.299, 0.587, 0.114, - 0.596,-0.275,-0.321, - 0.212,-0.523, 0.311); - -const mat3 yiq2rgbMatrix = mat3( - 1.0, 0.956, 0.621, - 1.0,-0.272,-1.703, - 1.0,-1.106, 0.0); - - -void main() -{ - vec4 oralColor = texture2D(inputImageTexture, textureCoordinate); - - vec3 maxValue = vec3(0.,0.,0.); - - for(int i = -2; i<=2; i++) - { - for(int j = -2; j<=2; j++) - { - vec4 tempColor = texture2D(inputImageTexture, textureCoordinate+singleStepOffset*vec2(i,j)); - maxValue.r = max(maxValue.r,tempColor.r); - maxValue.g = max(maxValue.g,tempColor.g); - maxValue.b = max(maxValue.b,tempColor.b); - } - } - - vec3 textureColor = oralColor.rgb / maxValue; - - float gray = dot(textureColor, W); - float k = 0.223529; - float alpha = min(gray,k)/k; - - textureColor = textureColor * alpha + (1.-alpha)*oralColor.rgb; - - vec3 yiqColor = textureColor * rgb2yiqMatrix; - - yiqColor.r = max(0.0,min(1.0,pow(gray,strength))); - - textureColor = yiqColor * yiq2rgbMatrix; - - gl_FragColor = vec4(textureColor, oralColor.w); -} \ No newline at end of file diff --git a/CameraFilter/src/main/res/raw/hue.glsl b/CameraFilter/src/main/res/raw/hue.glsl new file mode 100644 index 0000000..de084c2 --- /dev/null +++ b/CameraFilter/src/main/res/raw/hue.glsl @@ -0,0 +1,43 @@ +precision highp float; +varying highp vec2 textureCoordinate; + +uniform sampler2D inputImageTexture; +uniform mediump float hueAdjust; +const highp vec4 kRGBToYPrime = vec4 (0.299, 0.587, 0.114, 0.0); +const highp vec4 kRGBToI = vec4 (0.595716, -0.274453, -0.321263, 0.0); +const highp vec4 kRGBToQ = vec4 (0.211456, -0.522591, 0.31135, 0.0); + +const highp vec4 kYIQToR = vec4 (1.0, 0.9563, 0.6210, 0.0); +const highp vec4 kYIQToG = vec4 (1.0, -0.2721, -0.6474, 0.0); +const highp vec4 kYIQToB = vec4 (1.0, -1.1070, 1.7046, 0.0); + +void main () +{ + // Sample the input pixel + highp vec4 color = texture2D(inputImageTexture, textureCoordinate); + + // Convert to YIQ + highp float YPrime = dot (color, kRGBToYPrime); + highp float I = dot (color, kRGBToI); + highp float Q = dot (color, kRGBToQ); + + // Calculate the hue and chroma + highp float hue = atan (Q, I); + highp float chroma = sqrt (I * I + Q * Q); + + // Make the user's adjustments + hue += (-hueAdjust); //why negative rotation? + + // Convert back to YIQ + Q = chroma * sin (hue); + I = chroma * cos (hue); + + // Convert back to RGB + highp vec4 yIQ = vec4 (YPrime, I, Q, 0.0); + color.r = dot (yIQ, kYIQToR); + color.g = dot (yIQ, kYIQToG); + color.b = dot (yIQ, kYIQToB); + + // Save the result + gl_FragColor = color; +} \ No newline at end of file diff --git a/CameraFilter/src/main/res/raw/sketch.glsl b/CameraFilter/src/main/res/raw/sketch.glsl index ee14800..5239dfe 100644 --- a/CameraFilter/src/main/res/raw/sketch.glsl +++ b/CameraFilter/src/main/res/raw/sketch.glsl @@ -2,45 +2,42 @@ varying highp vec2 textureCoordinate; precision mediump float; uniform sampler2D inputImageTexture; -uniform vec2 singleStepOffset; +uniform vec2 singleStepOffset; uniform float strength; -const highp vec3 W = vec3(0.299,0.587,0.114); +const highp vec3 W = vec3(0.299, 0.587, 0.114); void main() -{ - float threshold = 0.0; - //pic1 - vec4 oralColor = texture2D(inputImageTexture, textureCoordinate); - - //pic2 - vec3 maxValue = vec3(0.,0.,0.); - - for(int i = -2; i<=2; i++) - { - for(int j = -2; j<=2; j++) - { - vec4 tempColor = texture2D(inputImageTexture, textureCoordinate+singleStepOffset*vec2(i,j)); - maxValue.r = max(maxValue.r,tempColor.r); - maxValue.g = max(maxValue.g,tempColor.g); - maxValue.b = max(maxValue.b,tempColor.b); - threshold += dot(tempColor.rgb, W); - } - } - //pic3 - float gray1 = dot(oralColor.rgb, W); - - //pic4 - float gray2 = dot(maxValue, W); - - //pic5 - float contour = gray1 / gray2; - - threshold = threshold / 25.; - float alpha = max(1.0,gray1>threshold?1.0:(gray1/threshold)); - - float result = contour * alpha + (1.0-alpha)*gray1; - - gl_FragColor = vec4(vec3(result,result,result), oralColor.w); +{ + float threshold = 0.0; + //pic1 + vec4 oralColor = texture2D(inputImageTexture, textureCoordinate); + //pic2 + vec3 maxValue = vec3(0., 0., 0.); + + for (int i = -2; i<=2; i++) + { + for (int j = -2; j<=2; j++) + { + vec4 tempColor = texture2D(inputImageTexture, textureCoordinate+singleStepOffset*vec2(i, j)); + maxValue.r = max(maxValue.r, tempColor.r); + maxValue.g = max(maxValue.g, tempColor.g); + maxValue.b = max(maxValue.b, tempColor.b); + threshold += dot(tempColor.rgb, W); + } + } + //pic3 + float gray1 = dot(oralColor.rgb, W); + //pic4 + float gray2 = dot(maxValue, W); + //pic5 + float contour = gray1 / gray2; + + threshold = threshold / 25.; + float alpha = max(1.0, gray1>threshold?1.0:(gray1/threshold)); + + float result = contour * alpha + (1.0-alpha)*gray1; + + gl_FragColor = vec4(vec3(result, result, result), oralColor.w); } \ No newline at end of file