renouncement
I initially answered another question from the same author, and it seems to have been asked as part of the same problem. I decided not to mark this one as a duplicate, because the first question has no context for using GPUImageLibrary , which simplifies the work. However, I do not want to overestimate, therefore, if you need any additional details, please refer to the original answer . Here I just outline the solution.
In fact, you do not need to extend the GPUImageSubtractBlendFilter or any descendants of the GPUImageTwoInputFilter , because (as Sergio correctly noted) you have to deal with only one instance of the texture. Instead, define your own fragment shader that will take the color filter, apply it and subtract the resulting value from the original pixel:
precision mediump float; struct ColorFilter { mat4 factor; vec4 shift; }; uniform sampler2D inputImageTexture; uniform ColorFilter uColorFilter; varying vec2 textureCoordinate; void main() { vec4 originalColor = texture2D(inputImageTexture, textureCoordinate); originalColor.rgb *= originalColor.a; vec4 filteredColor = (originalColor * uColorFilter.factor) + uColorFilter.shift; filteredColor.rgb *= filteredColor.a; gl_FragColor = vec4(originalColor.rgb - filteredColor.rgb, originalColor.a); }
Now just attach the color filter matrix to the shader:
@Override public void onInitialized() { super.onInitialized(); attachColorFilter(getProgram()); } // ========================================== // // Private // ========================================== // private void attachColorFilter(int program) { final float[] colorFilterFactor = new float[4 * 4]; final float[] colorFilterShift = new float[4]; for (int i = 0; i < mColorFilter.length; i++) { final float value = mColorFilter[i]; final int calculateIndex = i + 1; if (calculateIndex % 5 == 0) { colorFilterShift[calculateIndex / 5 - 1] = value / 255; } else { colorFilterFactor[i - calculateIndex / 5] = value; } } final int colorFactorLocation = GLES20.glGetUniformLocation(program, "uColorFilter.factor"); setUniformMatrix4f(colorFactorLocation, colorFilterFactor); final int colorShiftLocation = GLES20.glGetUniformLocation(program, "uColorFilter.shift"); setFloatVec4(colorShiftLocation, colorFilterShift); }
Feel free to use the entity with a working subclass. Just instantiate it and go to GPUImageView :
mBlendedImageView.setFilter(new ColorMatrixSubtractFilter(new float[] { 0.393f, 0.7689999f, 0.18899999f, 0, 0, 0.349f, 0.6859999f, 0.16799999f, 0, 0, 0.272f, 0.5339999f, 0.13099999f, 0, 0, 0, 0, 0, 1, 0 }));
On the right you see the result of the subtracted filter applied to the image on the left:
