Update Posterize, Saturation, Sepia with onPreDraw

pull/535/head
Mattia Iavarone 6 years ago
parent c323586c55
commit c4118ab3f9
  1. 4
      cameraview/src/main/java/com/otaliastudios/cameraview/filters/LomoishFilter.java
  2. 24
      cameraview/src/main/java/com/otaliastudios/cameraview/filters/PosterizeFilter.java
  3. 131
      cameraview/src/main/java/com/otaliastudios/cameraview/filters/SaturationFilter.java
  4. 51
      cameraview/src/main/java/com/otaliastudios/cameraview/filters/SepiaFilter.java

@ -19,12 +19,12 @@ public class LomoishFilter extends BaseFilter {
private final static String FRAGMENT_SHADER = "#extension GL_OES_EGL_image_external : require\n"
+ "precision mediump float;\n"
+ "uniform samplerExternalOES sTexture;\n"
+ "vec2 seed;\n"
+ "uniform float stepsizeX;\n"
+ "uniform float stepsizeY;\n"
+ "float stepsize;\n"
+ "uniform vec2 scale;\n"
+ "uniform float inv_max_dist;\n"
+ "vec2 seed;\n"
+ "float stepsize;\n"
+ "varying vec2 vTextureCoord;\n"
+ "float rand(vec2 loc) {\n"
+ " float theta1 = dot(loc, vec2(0.9898, 0.233));\n"

@ -9,21 +9,23 @@ import com.otaliastudios.cameraview.filter.BaseFilter;
*/
public class PosterizeFilter extends BaseFilter {
private final static String FRAGMENT_SHADER = "#extension GL_OES_EGL_image_external : require\n"
+ "precision mediump float;\n"
+ "uniform samplerExternalOES sTexture;\n"
+ "varying vec2 vTextureCoord;\n" + "void main() {\n"
+ " vec4 color = texture2D(sTexture, vTextureCoord);\n"
+ " vec3 pcolor;\n"
+ " pcolor.r = (color.r >= 0.5) ? 0.75 : 0.25;\n"
+ " pcolor.g = (color.g >= 0.5) ? 0.75 : 0.25;\n"
+ " pcolor.b = (color.b >= 0.5) ? 0.75 : 0.25;\n"
+ " gl_FragColor = vec4(pcolor, color.a);\n"
+ "}\n";
public PosterizeFilter() { }
@NonNull
@Override
public String getFragmentShader() {
return "#extension GL_OES_EGL_image_external : require\n"
+ "precision mediump float;\n"
+ "uniform samplerExternalOES sTexture;\n"
+ "varying vec2 vTextureCoord;\n" + "void main() {\n"
+ " vec4 color = texture2D(sTexture, vTextureCoord);\n"
+ " vec3 pcolor;\n"
+ " pcolor.r = (color.r >= 0.5) ? 0.75 : 0.25;\n"
+ " pcolor.g = (color.g >= 0.5) ? 0.75 : 0.25;\n"
+ " pcolor.b = (color.b >= 0.5) ? 0.75 : 0.25;\n"
+ " gl_FragColor = vec4(pcolor, color.a);\n"
+ "}\n";
return FRAGMENT_SHADER;
}
}

@ -1,15 +1,45 @@
package com.otaliastudios.cameraview.filters;
import android.opengl.GLES20;
import androidx.annotation.NonNull;
import com.otaliastudios.cameraview.filter.BaseFilter;
import com.otaliastudios.cameraview.internal.GlUtils;
/**
* Adjusts color saturation.
*/
public class SaturationFilter extends BaseFilter {
private final static String FRAGMENT_SHADER = "#extension GL_OES_EGL_image_external : require\n"
+ "precision mediump float;\n"
+ "uniform samplerExternalOES sTexture;\n"
+ "uniform float scale;\n"
+ "uniform vec3 exponents;\n"
+ "float shift;\n"
+ "vec3 weights;\n"
+ "varying vec2 vTextureCoord;\n"
+ "void main() {\n"
+ " weights[0] = " + 2f / 8f + ";\n"
+ " weights[1] = " + 5f / 8f + ";\n"
+ " weights[2] = " + 1f / 8f + ";\n"
+ " shift = " + 1.0f / 255.0f + ";\n"
+ " vec4 oldcolor = texture2D(sTexture, vTextureCoord);\n"
+ " float kv = dot(oldcolor.rgb, weights) + shift;\n"
+ " vec3 new_color = scale * oldcolor.rgb + (1.0 - scale) * kv;\n"
+ " gl_FragColor = vec4(new_color, oldcolor.a);\n"
+ " vec4 color = texture2D(sTexture, vTextureCoord);\n"
+ " float de = dot(color.rgb, weights);\n"
+ " float inv_de = 1.0 / de;\n"
+ " vec3 verynew_color = de * pow(color.rgb * inv_de, exponents);\n"
+ " float max_color = max(max(max(verynew_color.r, verynew_color.g), verynew_color.b), 1.0);\n"
+ " gl_FragColor = gl_FragColor+vec4(verynew_color / max_color, color.a);\n"
+ "}\n";
private float scale = 1.0f;
private int scaleLocation = -1;
private int exponentsLocation = -1;
@SuppressWarnings("WeakerAccess")
public SaturationFilter() { }
@ -45,75 +75,52 @@ public class SaturationFilter extends BaseFilter {
return (scale + 1.0f) / 2.0f;
}
@NonNull
@Override
protected BaseFilter onCopy() {
SaturationFilter filter = new SaturationFilter();
filter.setSaturation(getSaturation());
return filter;
public String getFragmentShader() {
return FRAGMENT_SHADER;
}
@NonNull
@Override
public String getFragmentShader() {
float shift = 1.0f / 255.0f;
float[] weights = {2f / 8f, 5f / 8f, 1f / 8f};
float[] exponents = new float[3];
public void onCreate(int programHandle) {
super.onCreate(programHandle);
scaleLocation = GLES20.glGetUniformLocation(programHandle, "scale");
GlUtils.checkLocation(scaleLocation, "scale");
exponentsLocation = GLES20.glGetUniformLocation(programHandle, "exponents");
GlUtils.checkLocation(exponentsLocation, "exponents");
}
String[] weightsString = new String[3];
String[] exponentsString = new String[3];
exponentsString[0] = "";
exponentsString[1] = "";
exponentsString[2] = "";
String scaleString = "";
@Override
public void onDestroy() {
super.onDestroy();
scaleLocation = -1;
exponentsLocation = -1;
}
@Override
protected void onPreDraw(float[] transformMatrix) {
super.onPreDraw(transformMatrix);
if (scale > 0.0f) {
exponents[0] = (0.9f * scale) + 1.0f;
exponents[1] = (2.1f * scale) + 1.0f;
exponents[2] = (2.7f * scale) + 1.0f;
exponentsString[0] = "exponents[0] = " + exponents[0] + ";\n";
exponentsString[1] = "exponents[1] = " + exponents[1] + ";\n";
exponentsString[2] = "exponents[2] = " + exponents[2] + ";\n";
} else
scaleString = "scale = " + (1.0f + scale) + ";\n";
weightsString[0] = "weights[0] = " + weights[0] + ";\n";
weightsString[1] = "weights[1] = " + weights[1] + ";\n";
weightsString[2] = "weights[2] = " + weights[2] + ";\n";
String shiftString = "shift = " + shift + ";\n";
return "#extension GL_OES_EGL_image_external : require\n"
+ "precision mediump float;\n"
+ "uniform samplerExternalOES sTexture;\n"
+ "float scale;\n"
+ "float shift;\n"
+ "vec3 weights;\n"
+ "vec3 exponents;\n"
+ "varying vec2 vTextureCoord;\n"
+ "void main() {\n"
// Parameters that were created above
+ weightsString[0]
+ weightsString[1]
+ weightsString[2]
+ shiftString
+ scaleString
+ " vec4 oldcolor = texture2D(sTexture, vTextureCoord);\n"
+ " float kv = dot(oldcolor.rgb, weights) + shift;\n"
+ " vec3 new_color = scale * oldcolor.rgb + (1.0 - scale) * kv;\n"
+ " gl_FragColor= vec4(new_color, oldcolor.a);\n"
// Parameters that were created above
+ weightsString[0]
+ weightsString[1]
+ weightsString[2]
+ exponentsString[0]
+ exponentsString[1]
+ exponentsString[2]
+ " vec4 color = texture2D(sTexture, vTextureCoord);\n"
+ " float de = dot(color.rgb, weights);\n"
+ " float inv_de = 1.0 / de;\n"
+ " vec3 verynew_color = de * pow(color.rgb * inv_de, exponents);\n"
+ " float max_color = max(max(max(verynew_color.r, verynew_color.g), verynew_color.b), 1.0);\n"
+ " gl_FragColor = gl_FragColor+vec4(verynew_color / max_color, color.a);\n"
+ "}\n";
GLES20.glUniform1f(scaleLocation, 0F);
GlUtils.checkError("glUniform1f");
GLES20.glUniform3f(exponentsLocation,
(0.9f * scale) + 1.0f,
(2.1f * scale) + 1.0f,
(2.7f * scale) + 1.0f
);
GlUtils.checkError("glUniform3f");
} else {
GLES20.glUniform1f(scaleLocation, 1.0F + scale);
GlUtils.checkError("glUniform1f");
GLES20.glUniform3f(exponentsLocation, 0F, 0F, 0F);
GlUtils.checkError("glUniform3f");
}
}
@Override
protected BaseFilter onCopy() {
SaturationFilter filter = new SaturationFilter();
filter.setSaturation(getSaturation());
return filter;
}
}

@ -9,40 +9,31 @@ import com.otaliastudios.cameraview.filter.BaseFilter;
*/
public class SepiaFilter extends BaseFilter {
private final static String FRAGMENT_SHADER = "#extension GL_OES_EGL_image_external : require\n"
+ "precision mediump float;\n"
+ "uniform samplerExternalOES sTexture;\n"
+ "mat3 matrix;\n"
+ "varying vec2 vTextureCoord;\n"
+ "void main() {\n"
+ " matrix[0][0]=" + 805.0f / 2048.0f + ";\n"
+ " matrix[0][1]=" + 715.0f / 2048.0f + ";\n"
+ " matrix[0][2]=" + 557.0f / 2048.0f + ";\n"
+ " matrix[1][0]=" + 1575.0f / 2048.0f + ";\n"
+ " matrix[1][1]=" + 1405.0f / 2048.0f + ";\n"
+ " matrix[1][2]=" + 1097.0f / 2048.0f + ";\n"
+ " matrix[2][0]=" + 387.0f / 2048.0f + ";\n"
+ " matrix[2][1]=" + 344.0f / 2048.0f + ";\n"
+ " matrix[2][2]=" + 268.0f / 2048.0f + ";\n"
+ " vec4 color = texture2D(sTexture, vTextureCoord);\n"
+ " vec3 new_color = min(matrix * color.rgb, 1.0);\n"
+ " gl_FragColor = vec4(new_color.rgb, color.a);\n"
+ "}\n";
public SepiaFilter() { }
@NonNull
@Override
public String getFragmentShader() {
float[] weights = {805.0f / 2048.0f, 715.0f / 2048.0f,
557.0f / 2048.0f, 1575.0f / 2048.0f, 1405.0f / 2048.0f,
1097.0f / 2048.0f, 387.0f / 2048.0f, 344.0f / 2048.0f,
268.0f / 2048.0f};
String[] matrixString = new String[9];
matrixString[0] = " matrix[0][0]=" + weights[0] + ";\n";
matrixString[1] = " matrix[0][1]=" + weights[1] + ";\n";
matrixString[2] = " matrix[0][2]=" + weights[2] + ";\n";
matrixString[3] = " matrix[1][0]=" + weights[3] + ";\n";
matrixString[4] = " matrix[1][1]=" + weights[4] + ";\n";
matrixString[5] = " matrix[1][2]=" + weights[5] + ";\n";
matrixString[6] = " matrix[2][0]=" + weights[6] + ";\n";
matrixString[7] = " matrix[2][1]=" + weights[7] + ";\n";
matrixString[8] = " matrix[2][2]=" + weights[8] + ";\n";
return "#extension GL_OES_EGL_image_external : require\n"
+ "precision mediump float;\n"
+ "uniform samplerExternalOES sTexture;\n"
+ "mat3 matrix;\n"
+ "varying vec2 vTextureCoord;\n"
+ "void main() {\n"
+ matrixString[0] + matrixString[1] + matrixString[2]
+ matrixString[3] + matrixString[4] + matrixString[5]
+ matrixString[6] + matrixString[7] + matrixString[8]
+ " vec4 color = texture2D(sTexture, vTextureCoord);\n"
+ " vec3 new_color = min(matrix * color.rgb, 1.0);\n"
+ " gl_FragColor = vec4(new_color.rgb, color.a);\n"
+ "}\n";
return FRAGMENT_SHADER;
}
}

Loading…
Cancel
Save