Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I "subtract" a color filter using GPUImageLibrary?

Currently the BlendModes (Subtract, Exclusion, etc.) use the LauncherImage as the mask. Can I apply these BlendModes to a ColorMatrix?

I'm using the GPUImageLibrary:

colorMatrix[     0.393, 0.7689999, 0.18899999, 0, 0,     0.349, 0.6859999, 0.16799999, 0, 0,     0.272, 0.5339999, 0.13099999, 0, 0,     0,     0,         0,          1, 0]; 

SubtractBlendFilter.java

public class GPUImageSubtractBlendFilter extends GPUImageTwoInputFilter {     public static final String SUBTRACT_BLEND_FRAGMENT_SHADER = "varying highp vec2 textureCoordinate;\n" +             " varying highp vec2 textureCoordinate2;\n" +             "\n" +             " uniform sampler2D inputImageTexture;\n" +             " uniform sampler2D inputImageTexture2;\n" +             " \n" +             " void main()\n" +             " {\n" +             "   lowp vec4 textureColor = texture2D(inputImageTexture, textureCoordinate);\n" +             "   lowp vec4 textureColor2 = texture2D(inputImageTexture2, textureCoordinate2);\n" +             "\n" +             "   gl_FragColor = vec4(textureColor.rgb - textureColor2.rgb, textureColor.a);\n" +             " }";      public GPUImageSubtractBlendFilter() {         super(SUBTRACT_BLEND_FRAGMENT_SHADER);     } } 

GPUIMageTwoInputFilter.java

public class GPUImageTwoInputFilter extends GPUImageFilter {     private static final String VERTEX_SHADER = "attribute vec4 position;\n" +             "attribute vec4 inputTextureCoordinate;\n" +             "attribute vec4 inputTextureCoordinate2;\n" +             " \n" +             "varying vec2 textureCoordinate;\n" +             "varying vec2 textureCoordinate2;\n" +             " \n" +             "void main()\n" +             "{\n" +             "    gl_Position = position;\n" +             "    textureCoordinate = inputTextureCoordinate.xy;\n" +             "    textureCoordinate2 = inputTextureCoordinate2.xy;\n" +             "}";      public int mFilterSecondTextureCoordinateAttribute;     public int mFilterInputTextureUniform2;     public int mFilterSourceTexture2 = OpenGlUtils.NO_TEXTURE;     private ByteBuffer mTexture2CoordinatesBuffer;     private Bitmap mBitmap;      public GPUImageTwoInputFilter(String fragmentShader) {         this(VERTEX_SHADER, fragmentShader);     }      public GPUImageTwoInputFilter(String vertexShader, String fragmentShader) {         super(vertexShader, fragmentShader);         setRotation(Rotation.NORMAL, false, false);     }      @Override     public void onInit() {         super.onInit();          mFilterSecondTextureCoordinateAttribute = GLES20.glGetAttribLocation(getProgram(), "inputTextureCoordinate2");         mFilterInputTextureUniform2 = GLES20.glGetUniformLocation(getProgram(), "inputImageTexture2"); // This does assume a name of "inputImageTexture2" for second input texture in the fragment shader         GLES20.glEnableVertexAttribArray(mFilterSecondTextureCoordinateAttribute);          if (mBitmap != null&&!mBitmap.isRecycled()) {             setBitmap(mBitmap);         }     }      public void setBitmap(final Bitmap bitmap) {         if (bitmap != null && bitmap.isRecycled()) {             return;         }         mBitmap = bitmap;         if (mBitmap == null) {             return;         }         runOnDraw(new Runnable() {             public void run() {                 if (mFilterSourceTexture2 == OpenGlUtils.NO_TEXTURE) {                     if (bitmap == null || bitmap.isRecycled()) {                         return;                     }                     GLES20.glActiveTexture(GLES20.GL_TEXTURE3);                     mFilterSourceTexture2 = OpenGlUtils.loadTexture(bitmap, OpenGlUtils.NO_TEXTURE, false);                 }             }         });     }      public Bitmap getBitmap() {         return mBitmap;     }      public void recycleBitmap() {         if (mBitmap != null && !mBitmap.isRecycled()) {             mBitmap.recycle();             mBitmap = null;         }     }      public void onDestroy() {         super.onDestroy();         GLES20.glDeleteTextures(1, new int[]{                 mFilterSourceTexture2         }, 0);         mFilterSourceTexture2 = OpenGlUtils.NO_TEXTURE;     }      @Override     protected void onDrawArraysPre() {         GLES20.glEnableVertexAttribArray(mFilterSecondTextureCoordinateAttribute);         GLES20.glActiveTexture(GLES20.GL_TEXTURE3);         GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mFilterSourceTexture2);         GLES20.glUniform1i(mFilterInputTextureUniform2, 3);          mTexture2CoordinatesBuffer.position(0);         GLES20.glVertexAttribPointer(mFilterSecondTextureCoordinateAttribute, 2, GLES20.GL_FLOAT, false, 0, mTexture2CoordinatesBuffer);     }      public void setRotation(final Rotation rotation, final boolean flipHorizontal, final boolean flipVertical) {         float[] buffer = TextureRotationUtil.getRotation(rotation, flipHorizontal, flipVertical);          ByteBuffer bBuffer = ByteBuffer.allocateDirect(32).order(ByteOrder.nativeOrder());         FloatBuffer fBuffer = bBuffer.asFloatBuffer();         fBuffer.put(buffer);         fBuffer.flip();          mTexture2CoordinatesBuffer = bBuffer;     } } 

My guess it involves changing something with String SUBTRACT_BLEND_GRAGMENT_SHADER & String VERTEX_SHADER .

like image 516
Zen Avatar asked Oct 27 '15 00:10

Zen


1 Answers

Color matrix is the entity that defines new color component values for some pixel as linear functions of the current color components of the same pixel. I.e. the only input for color matrix conversion is the pixel, which colors should be transformed. There is no way to involve another pixels to such conversion. Regardless if they are pixels from another image or even neighbors of transformed pixel - it is impossible.

like image 90
Sergio Avatar answered Sep 20 '22 13:09

Sergio