Skip to content

Commit

Permalink
Add filter blend color: Screen, Overlay, Multiply
Browse files Browse the repository at this point in the history
- Blend photo with custom color without create new solid color bitmap.
Ex:
float[] mVec4RedColor = new float[]{1f,0f,0f,1f};
GPUImageOverlayColorBlendFilter filter = new GPUImageOverlayColorBlendFilter(mVec4RedColor);
  • Loading branch information
dockusan authored and dockusan committed Aug 3, 2022
1 parent cd663a9 commit 5b55ee6
Show file tree
Hide file tree
Showing 4 changed files with 255 additions and 22 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
/*
* Copyright (C) 2012 CyberAgent
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package jp.co.cyberagent.android.gpuimage;

import android.opengl.GLES20;

public class GPUImageMultiplyColorBlendFilter extends GPUImageFilter {
public static final String MULTIPLY_COLOR_BLEND_FRAGMENT_SHADER = "varying highp vec2 textureCoordinate;\n" +
" uniform sampler2D inputImageTexture;\n" +
" uniform vec4 mColor;\n" +
" \n" +
" void main()\n" +
" {\n" +
" lowp vec4 base = texture2D(inputImageTexture, textureCoordinate);\n" +
" \n" +
" gl_FragColor = mColor * base + mColor * (1.0 - base.a) + base * (1.0 - mColor.a);\n" +
" }";
private float[] mColor;
private int mColorLocation;

public GPUImageMultiplyColorBlendFilter(final float[] mColor) {
super(NO_FILTER_VERTEX_SHADER, MULTIPLY_COLOR_BLEND_FRAGMENT_SHADER);
this.mColor = mColor;
}

public GPUImageMultiplyColorBlendFilter() {
this(new float[]{0.0f, 0.0f, 0.0f, 0.0f});
}

@Override
public void onInit() {
super.onInit();
mColorLocation = GLES20.glGetUniformLocation(getProgram(), "mColor");
setBlendColor(mColor);
}

public void setBlendColor(final float[] color) {
mColor = color;
setFloatVec4(mColorLocation, mColor);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
/*
* Copyright (C) 2012 CyberAgent
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package jp.co.cyberagent.android.gpuimage;

import android.opengl.GLES20;

public class GPUImageOverlayColorBlendFilter extends GPUImageFilter {
public static final String OVERLAY_COLOR_BLEND_FRAGMENT_SHADER = "varying highp vec2 textureCoordinate;\n" +
"\n" +
" uniform sampler2D inputImageTexture;\n" +
" uniform vec4 mVec4Color;\n" +
" \n" +
" void main()\n" +
" {\n" +
" mediump vec4 base = texture2D(inputImageTexture, textureCoordinate);\n" +
" \n" +
" mediump float ra;\n" +
" if (2.0 * base.r < base.a) {\n" +
" ra = 2.0 * mVec4Color.r * base.r + mVec4Color.r * (1.0 - base.a) + base.r * (1.0 - mVec4Color.a);\n" +
" } else {\n" +
" ra = mVec4Color.a * base.a - 2.0 * (base.a - base.r) * (mVec4Color.a - mVec4Color.r) + mVec4Color.r * (1.0 - base.a) + base.r * (1.0 - mVec4Color.a);\n" +
" }\n" +
" \n" +
" mediump float ga;\n" +
" if (2.0 * base.g < base.a) {\n" +
" ga = 2.0 * mVec4Color.g * base.g + mVec4Color.g * (1.0 - base.a) + base.g * (1.0 - mVec4Color.a);\n" +
" } else {\n" +
" ga = mVec4Color.a * base.a - 2.0 * (base.a - base.g) * (mVec4Color.a - mVec4Color.g) + mVec4Color.g * (1.0 - base.a) + base.g * (1.0 - mVec4Color.a);\n" +
" }\n" +
" \n" +
" mediump float ba;\n" +
" if (2.0 * base.b < base.a) {\n" +
" ba = 2.0 * mVec4Color.b * base.b + mVec4Color.b * (1.0 - base.a) + base.b * (1.0 - mVec4Color.a);\n" +
" } else {\n" +
" ba = mVec4Color.a * base.a - 2.0 * (base.a - base.b) * (mVec4Color.a - mVec4Color.b) + mVec4Color.b * (1.0 - base.a) + base.b * (1.0 - mVec4Color.a);\n" +
" }\n" +
" \n" +
" gl_FragColor = vec4(ra, ga, ba, 1.0);\n" +
" }";

private float[] mVec4Color;
private int mColorLocation;

public GPUImageOverlayColorBlendFilter(final float[] mColor) {
super(NO_FILTER_VERTEX_SHADER, OVERLAY_COLOR_BLEND_FRAGMENT_SHADER);
this.mVec4Color = mColor;
}

public GPUImageOverlayColorBlendFilter() {
this(new float[]{0.0f, 0.0f, 0.0f, 0.0f});
}

@Override
public void onInit() {
super.onInit();
mColorLocation = GLES20.glGetUniformLocation(getProgram(), "mVec4Color");
setBlendColor(mVec4Color);
}

public void setBlendColor(final float[] color) {
mVec4Color = color;
setFloatVec4(mColorLocation, mVec4Color);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
/*
* Copyright (C) 2012 CyberAgent
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package jp.co.cyberagent.android.gpuimage;

import android.opengl.GLES20;

public class GPUImageScreenColorBlendFilter extends GPUImageFilter {
public static final String SCREEN_COLOR_BLEND_FRAGMENT_SHADER = "varying highp vec2 textureCoordinate;\n" +
" varying highp vec2 textureCoordinate2;\n" +
"\n" +
" uniform sampler2D inputImageTexture;\n" +
" uniform vec4 mVec4Color;\n" +
" \n" +
" void main()\n" +
" {\n" +
" mediump vec4 textureColor = texture2D(inputImageTexture, textureCoordinate);\n" +
" mediump vec4 whiteColor = vec4(1.0);\n" +
" gl_FragColor = whiteColor - ((whiteColor - mVec4Color) * (whiteColor - textureColor));\n" +
" }";


private float[] mVec4Color;
private int mColorLocation;

public GPUImageScreenColorBlendFilter(final float[] mColor) {
super(NO_FILTER_VERTEX_SHADER, SCREEN_COLOR_BLEND_FRAGMENT_SHADER);
this.mVec4Color = mColor;
}

public GPUImageScreenColorBlendFilter() {
this(new float[]{0.0f, 0.0f, 0.0f, 0.0f});
}

@Override
public void onInit() {
super.onInit();
mColorLocation = GLES20.glGetUniformLocation(getProgram(), "mVec4Color");
setBlendColor(mVec4Color);
}

public void setBlendColor(final float[] color) {
mVec4Color = color;
setFloatVec4(mColorLocation, mVec4Color);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,14 @@
import android.graphics.PointF;
import android.opengl.Matrix;

import jp.co.cyberagent.android.gpuimage.*;

import java.util.LinkedList;
import java.util.List;

import jp.co.cyberagent.android.gpuimage.*;

public class GPUImageFilterTools {
public static void showDialog(final Context context,
final OnGpuImageFilterChosenListener listener) {
final OnGpuImageFilterChosenListener listener) {
final FilterList filters = new FilterList();
filters.addFilter("Contrast", FilterType.CONTRAST);
filters.addFilter("Invert", FilterType.INVERT);
Expand Down Expand Up @@ -68,8 +68,11 @@ public static void showDialog(final Context context,
filters.addFilter("Blend (Add)", FilterType.BLEND_ADD);
filters.addFilter("Blend (Divide)", FilterType.BLEND_DIVIDE);
filters.addFilter("Blend (Multiply)", FilterType.BLEND_MULTIPLY);
filters.addFilter("Blend Color (Multiply)", FilterType.BLEND_COLOR_MULTIPLY);
filters.addFilter("Blend (Overlay)", FilterType.BLEND_OVERLAY);
filters.addFilter("Blend Color (Overlay)", FilterType.BLEND_COLOR_OVERLAY);
filters.addFilter("Blend (Screen)", FilterType.BLEND_SCREEN);
filters.addFilter("Blend Color (Screen)", FilterType.BLEND_COLOR_SCREEN);
filters.addFilter("Blend (Alpha)", FilterType.BLEND_ALPHA);
filters.addFilter("Blend (Color)", FilterType.BLEND_COLOR);
filters.addFilter("Blend (Hue)", FilterType.BLEND_HUE);
Expand Down Expand Up @@ -109,7 +112,7 @@ public static void showDialog(final Context context,

filters.addFilter("Levels Min (Mid Adjust)", FilterType.LEVELS_FILTER_MIN);

filters. addFilter("Bilateral Blur", FilterType.BILATERAL_BLUR);
filters.addFilter("Bilateral Blur", FilterType.BILATERAL_BLUR);

filters.addFilter("Transform (2-D)", FilterType.TRANSFORM2D);

Expand Down Expand Up @@ -153,7 +156,7 @@ private static GPUImageFilter createFilterForType(final Context context, final F
return new GPUImageSobelEdgeDetection();
case THREE_X_THREE_CONVOLUTION:
GPUImage3x3ConvolutionFilter convolution = new GPUImage3x3ConvolutionFilter();
convolution.setConvolutionKernel(new float[] {
convolution.setConvolutionKernel(new float[]{
-1.0f, 0.0f, 1.0f,
-2.0f, 0.0f, 2.0f,
-1.0f, 0.0f, 1.0f
Expand All @@ -174,9 +177,9 @@ private static GPUImageFilter createFilterForType(final Context context, final F
case EXPOSURE:
return new GPUImageExposureFilter(0.0f);
case HIGHLIGHT_SHADOW:
return new GPUImageHighlightShadowFilter(0.0f, 1.0f);
return new GPUImageHighlightShadowFilter(0.0f, 1.0f);
case MONOCHROME:
return new GPUImageMonochromeFilter(1.0f, new float[]{0.6f, 0.45f, 0.3f, 1.0f});
return new GPUImageMonochromeFilter(1.0f, new float[]{0.6f, 0.45f, 0.3f, 1.0f});
case OPACITY:
return new GPUImageOpacityFilter(1.0f);
case RGB:
Expand All @@ -187,7 +190,7 @@ private static GPUImageFilter createFilterForType(final Context context, final F
PointF centerPoint = new PointF();
centerPoint.x = 0.5f;
centerPoint.y = 0.5f;
return new GPUImageVignetteFilter(centerPoint, new float[] {0.0f, 0.0f, 0.0f}, 0.3f, 0.75f);
return new GPUImageVignetteFilter(centerPoint, new float[]{0.0f, 0.0f, 0.0f}, 0.3f, 0.75f);
case TONE_CURVE:
GPUImageToneCurveFilter toneCurveFilter = new GPUImageToneCurveFilter();
toneCurveFilter.setFromCurveFileInputStream(
Expand All @@ -207,8 +210,6 @@ private static GPUImageFilter createFilterForType(final Context context, final F
return createBlendFilter(context, GPUImageDissolveBlendFilter.class);
case BLEND_EXCLUSION:
return createBlendFilter(context, GPUImageExclusionBlendFilter.class);


case BLEND_HARD_LIGHT:
return createBlendFilter(context, GPUImageHardLightBlendFilter.class);
case BLEND_LIGHTEN:
Expand All @@ -219,10 +220,16 @@ private static GPUImageFilter createFilterForType(final Context context, final F
return createBlendFilter(context, GPUImageDivideBlendFilter.class);
case BLEND_MULTIPLY:
return createBlendFilter(context, GPUImageMultiplyBlendFilter.class);
case BLEND_COLOR_MULTIPLY:
return new GPUImageMultiplyColorBlendFilter(new float[]{1.0f, 1.0f, 1.0f, 1.0f});
case BLEND_OVERLAY:
return createBlendFilter(context, GPUImageOverlayBlendFilter.class);
case BLEND_COLOR_OVERLAY:
return new GPUImageOverlayColorBlendFilter(new float[]{1.0f, 1.0f, 1.0f, 1.0f});
case BLEND_SCREEN:
return createBlendFilter(context, GPUImageScreenBlendFilter.class);
case BLEND_COLOR_SCREEN:
return new GPUImageScreenColorBlendFilter(new float[]{1.0f, 1.0f, 1.0f, 1.0f});
case BLEND_ALPHA:
return createBlendFilter(context, GPUImageAlphaBlendFilter.class);
case BLEND_COLOR:
Expand Down Expand Up @@ -327,7 +334,7 @@ public interface OnGpuImageFilterChosenListener {
private enum FilterType {
CONTRAST, GRAYSCALE, SHARPEN, SEPIA, SOBEL_EDGE_DETECTION, THREE_X_THREE_CONVOLUTION, FILTER_GROUP, EMBOSS, POSTERIZE, GAMMA, BRIGHTNESS, INVERT, HUE, PIXELATION,
SATURATION, EXPOSURE, HIGHLIGHT_SHADOW, MONOCHROME, OPACITY, RGB, WHITE_BALANCE, VIGNETTE, TONE_CURVE, BLEND_COLOR_BURN, BLEND_COLOR_DODGE, BLEND_DARKEN, BLEND_DIFFERENCE,
BLEND_DISSOLVE, BLEND_EXCLUSION, BLEND_SOURCE_OVER, BLEND_HARD_LIGHT, BLEND_LIGHTEN, BLEND_ADD, BLEND_DIVIDE, BLEND_MULTIPLY, BLEND_OVERLAY, BLEND_SCREEN, BLEND_ALPHA,
BLEND_DISSOLVE, BLEND_EXCLUSION, BLEND_SOURCE_OVER, BLEND_HARD_LIGHT, BLEND_LIGHTEN, BLEND_ADD, BLEND_DIVIDE, BLEND_MULTIPLY, BLEND_COLOR_MULTIPLY, BLEND_OVERLAY, BLEND_COLOR_OVERLAY, BLEND_SCREEN, BLEND_COLOR_SCREEN, BLEND_ALPHA,
BLEND_COLOR, BLEND_HUE, BLEND_SATURATION, BLEND_LUMINOSITY, BLEND_LINEAR_BURN, BLEND_SOFT_LIGHT, BLEND_SUBTRACT, BLEND_CHROMA_KEY, BLEND_NORMAL, LOOKUP_AMATORKA,
GAUSSIAN_BLUR, CROSSHATCH, BOX_BLUR, CGA_COLORSPACE, DILATION, KUWAHARA, RGB_DILATION, SKETCH, TOON, SMOOTH_TOON, BULGE_DISTORTION, GLASS_SPHERE, HAZE, LAPLACIAN, NON_MAXIMUM_SUPPRESSION,
SPHERE_REFRACTION, SWIRL, WEAK_PIXEL_INCLUSION, FALSE_COLOR, COLOR_BALANCE, LEVELS_FILTER_MIN, BILATERAL_BLUR, HALFTONE, TRANSFORM2D
Expand Down Expand Up @@ -409,9 +416,13 @@ public FilterAdjuster(final GPUImageFilter filter) {
adjuster = new BilateralAdjuster().filter(filter);
} else if (filter instanceof GPUImageTransformFilter) {
adjuster = new RotateAdjuster().filter(filter);
}
else {

} else if (filter instanceof GPUImageMultiplyColorBlendFilter) {
adjuster = new MultiplyColorAdjuster().filter(filter);
} else if (filter instanceof GPUImageScreenColorBlendFilter) {
adjuster = new ScreenColorAdjuster().filter(filter);
} else if (filter instanceof GPUImageOverlayColorBlendFilter) {
adjuster = new OverlayColorAdjuster().filter(filter);
} else {
adjuster = null;
}
}
Expand Down Expand Up @@ -458,17 +469,17 @@ public void adjust(final int percentage) {
}

private class PixelationAdjuster extends Adjuster<GPUImagePixelationFilter> {
@Override
public void adjust(final int percentage) {
getFilter().setPixel(range(percentage, 1.0f, 100.0f));
}
@Override
public void adjust(final int percentage) {
getFilter().setPixel(range(percentage, 1.0f, 100.0f));
}
}

private class HueAdjuster extends Adjuster<GPUImageHueFilter> {
@Override
public void adjust(final int percentage) {
getFilter().setHue(range(percentage, 0.0f, 360.0f));
}
@Override
public void adjust(final int percentage) {
getFilter().setHue(range(percentage, 0.0f, 360.0f));
}
}

private class ContrastAdjuster extends Adjuster<GPUImageContrastFilter> {
Expand Down Expand Up @@ -659,6 +670,36 @@ public void adjust(int percentage) {
}
}

private class MultiplyColorAdjuster extends Adjuster<GPUImageMultiplyColorBlendFilter> {

@Override
public void adjust(int percentage) {
getFilter().setBlendColor(new float[]{
range(percentage, 0.0f, 1.0f),
1.0f, 1.0f, 1.0f});
}
}

private class ScreenColorAdjuster extends Adjuster<GPUImageScreenColorBlendFilter> {

@Override
public void adjust(int percentage) {
getFilter().setBlendColor(new float[]{
range(percentage, 0.0f, 1.0f),
1.0f, 1.0f, 1.0f});
}
}

private class OverlayColorAdjuster extends Adjuster<GPUImageOverlayColorBlendFilter> {

@Override
public void adjust(int percentage) {
getFilter().setBlendColor(new float[]{
range(percentage, 0.0f, 1.0f),
1.0f, 1.0f, 1.0f});
}
}

private class LevelsMinMidAdjuster extends Adjuster<GPUImageLevelsFilter> {
@Override
public void adjust(int percentage) {
Expand Down

0 comments on commit 5b55ee6

Please sign in to comment.