/* * 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; /** * For each pixel, this sets it to the maximum value of each color channel in a rectangular neighborhood extending * out dilationRadius pixels from the center. * This extends out brighter colors, and can be used for abstraction of color images. */ public class GPUImageRGBDilationFilter extends GPUImageTwoPassTextureSamplingFilter { public static final String VERTEX_SHADER_1 = "attribute vec4 position;\n" + "attribute vec2 inputTextureCoordinate;\n" + "\n" + "uniform float texelWidthOffset; \n" + "uniform float texelHeightOffset; \n" + "\n" + "varying vec2 centerTextureCoordinate;\n" + "varying vec2 oneStepPositiveTextureCoordinate;\n" + "varying vec2 oneStepNegativeTextureCoordinate;\n" + "\n" + "void main()\n" + "{\n" + "gl_Position = position;\n" + "\n" + "vec2 offset = vec2(texelWidthOffset, texelHeightOffset);\n" + "\n" + "centerTextureCoordinate = inputTextureCoordinate;\n" + "oneStepNegativeTextureCoordinate = inputTextureCoordinate - offset;\n" + "oneStepPositiveTextureCoordinate = inputTextureCoordinate + offset;\n" + "}\n"; public static final String VERTEX_SHADER_2 = "attribute vec4 position;\n" + "attribute vec2 inputTextureCoordinate;\n" + "\n" + "uniform float texelWidthOffset;\n" + "uniform float texelHeightOffset;\n" + "\n" + "varying vec2 centerTextureCoordinate;\n" + "varying vec2 oneStepPositiveTextureCoordinate;\n" + "varying vec2 oneStepNegativeTextureCoordinate;\n" + "varying vec2 twoStepsPositiveTextureCoordinate;\n" + "varying vec2 twoStepsNegativeTextureCoordinate;\n" + "\n" + "void main()\n" + "{\n" + "gl_Position = position;\n" + "\n" + "vec2 offset = vec2(texelWidthOffset, texelHeightOffset);\n" + "\n" + "centerTextureCoordinate = inputTextureCoordinate;\n" + "oneStepNegativeTextureCoordinate = inputTextureCoordinate - offset;\n" + "oneStepPositiveTextureCoordinate = inputTextureCoordinate + offset;\n" + "twoStepsNegativeTextureCoordinate = inputTextureCoordinate - (offset * 2.0);\n" + "twoStepsPositiveTextureCoordinate = inputTextureCoordinate + (offset * 2.0);\n" + "}\n"; public static final String VERTEX_SHADER_3 = "attribute vec4 position;\n" + "attribute vec2 inputTextureCoordinate;\n" + "\n" + "uniform float texelWidthOffset;\n" + "uniform float texelHeightOffset;\n" + "\n" + "varying vec2 centerTextureCoordinate;\n" + "varying vec2 oneStepPositiveTextureCoordinate;\n" + "varying vec2 oneStepNegativeTextureCoordinate;\n" + "varying vec2 twoStepsPositiveTextureCoordinate;\n" + "varying vec2 twoStepsNegativeTextureCoordinate;\n" + "varying vec2 threeStepsPositiveTextureCoordinate;\n" + "varying vec2 threeStepsNegativeTextureCoordinate;\n" + "\n" + "void main()\n" + "{\n" + "gl_Position = position;\n" + "\n" + "vec2 offset = vec2(texelWidthOffset, texelHeightOffset);\n" + "\n" + "centerTextureCoordinate = inputTextureCoordinate;\n" + "oneStepNegativeTextureCoordinate = inputTextureCoordinate - offset;\n" + "oneStepPositiveTextureCoordinate = inputTextureCoordinate + offset;\n" + "twoStepsNegativeTextureCoordinate = inputTextureCoordinate - (offset * 2.0);\n" + "twoStepsPositiveTextureCoordinate = inputTextureCoordinate + (offset * 2.0);\n" + "threeStepsNegativeTextureCoordinate = inputTextureCoordinate - (offset * 3.0);\n" + "threeStepsPositiveTextureCoordinate = inputTextureCoordinate + (offset * 3.0);\n" + "}\n"; public static final String VERTEX_SHADER_4 = "attribute vec4 position;\n" + "attribute vec2 inputTextureCoordinate;\n" + "\n" + "uniform float texelWidthOffset;\n" + "uniform float texelHeightOffset;\n" + "\n" + "varying vec2 centerTextureCoordinate;\n" + "varying vec2 oneStepPositiveTextureCoordinate;\n" + "varying vec2 oneStepNegativeTextureCoordinate;\n" + "varying vec2 twoStepsPositiveTextureCoordinate;\n" + "varying vec2 twoStepsNegativeTextureCoordinate;\n" + "varying vec2 threeStepsPositiveTextureCoordinate;\n" + "varying vec2 threeStepsNegativeTextureCoordinate;\n" + "varying vec2 fourStepsPositiveTextureCoordinate;\n" + "varying vec2 fourStepsNegativeTextureCoordinate;\n" + "\n" + "void main()\n" + "{\n" + "gl_Position = position;\n" + "\n" + "vec2 offset = vec2(texelWidthOffset, texelHeightOffset);\n" + "\n" + "centerTextureCoordinate = inputTextureCoordinate;\n" + "oneStepNegativeTextureCoordinate = inputTextureCoordinate - offset;\n" + "oneStepPositiveTextureCoordinate = inputTextureCoordinate + offset;\n" + "twoStepsNegativeTextureCoordinate = inputTextureCoordinate - (offset * 2.0);\n" + "twoStepsPositiveTextureCoordinate = inputTextureCoordinate + (offset * 2.0);\n" + "threeStepsNegativeTextureCoordinate = inputTextureCoordinate - (offset * 3.0);\n" + "threeStepsPositiveTextureCoordinate = inputTextureCoordinate + (offset * 3.0);\n" + "fourStepsNegativeTextureCoordinate = inputTextureCoordinate - (offset * 4.0);\n" + "fourStepsPositiveTextureCoordinate = inputTextureCoordinate + (offset * 4.0);\n" + "}\n"; public static final String FRAGMENT_SHADER_1 = "precision highp float;\n" + "\n" + "varying vec2 centerTextureCoordinate;\n" + "varying vec2 oneStepPositiveTextureCoordinate;\n" + "varying vec2 oneStepNegativeTextureCoordinate;\n" + "\n" + "uniform sampler2D inputImageTexture;\n" + "\n" + "void main()\n" + "{\n" + "lowp vec4 centerIntensity = texture2D(inputImageTexture, centerTextureCoordinate);\n" + "lowp vec4 oneStepPositiveIntensity = texture2D(inputImageTexture, oneStepPositiveTextureCoordinate);\n" + "lowp vec4 oneStepNegativeIntensity = texture2D(inputImageTexture, oneStepNegativeTextureCoordinate);\n" + "\n" + "lowp vec4 maxValue = max(centerIntensity, oneStepPositiveIntensity);\n" + "\n" + "gl_FragColor = max(maxValue, oneStepNegativeIntensity);\n" + "}\n"; public static final String FRAGMENT_SHADER_2 = "precision highp float;\n" + "\n" + "varying vec2 centerTextureCoordinate;\n" + "varying vec2 oneStepPositiveTextureCoordinate;\n" + "varying vec2 oneStepNegativeTextureCoordinate;\n" + "varying vec2 twoStepsPositiveTextureCoordinate;\n" + "varying vec2 twoStepsNegativeTextureCoordinate;\n" + "\n" + "uniform sampler2D inputImageTexture;\n" + "\n" + "void main()\n" + "{\n" + "lowp vec4 centerIntensity = texture2D(inputImageTexture, centerTextureCoordinate);\n" + "lowp vec4 oneStepPositiveIntensity = texture2D(inputImageTexture, oneStepPositiveTextureCoordinate);\n" + "lowp vec4 oneStepNegativeIntensity = texture2D(inputImageTexture, oneStepNegativeTextureCoordinate);\n" + "lowp vec4 twoStepsPositiveIntensity = texture2D(inputImageTexture, twoStepsPositiveTextureCoordinate);\n" + "lowp vec4 twoStepsNegativeIntensity = texture2D(inputImageTexture, twoStepsNegativeTextureCoordinate);\n" + "\n" + "lowp vec4 maxValue = max(centerIntensity, oneStepPositiveIntensity);\n" + "maxValue = max(maxValue, oneStepNegativeIntensity);\n" + "maxValue = max(maxValue, twoStepsPositiveIntensity);\n" + "maxValue = max(maxValue, twoStepsNegativeIntensity);\n" + "\n" + "gl_FragColor = max(maxValue, twoStepsNegativeIntensity);\n" + "}\n"; public static final String FRAGMENT_SHADER_3 = "precision highp float;\n" + "\n" + "varying vec2 centerTextureCoordinate;\n" + "varying vec2 oneStepPositiveTextureCoordinate;\n" + "varying vec2 oneStepNegativeTextureCoordinate;\n" + "varying vec2 twoStepsPositiveTextureCoordinate;\n" + "varying vec2 twoStepsNegativeTextureCoordinate;\n" + "varying vec2 threeStepsPositiveTextureCoordinate;\n" + "varying vec2 threeStepsNegativeTextureCoordinate;\n" + "\n" + "uniform sampler2D inputImageTexture;\n" + "\n" + "void main()\n" + "{\n" + "lowp vec4 centerIntensity = texture2D(inputImageTexture, centerTextureCoordinate);\n" + "lowp vec4 oneStepPositiveIntensity = texture2D(inputImageTexture, oneStepPositiveTextureCoordinate);\n" + "lowp vec4 oneStepNegativeIntensity = texture2D(inputImageTexture, oneStepNegativeTextureCoordinate);\n" + "lowp vec4 twoStepsPositiveIntensity = texture2D(inputImageTexture, twoStepsPositiveTextureCoordinate);\n" + "lowp vec4 twoStepsNegativeIntensity = texture2D(inputImageTexture, twoStepsNegativeTextureCoordinate);\n" + "lowp vec4 threeStepsPositiveIntensity = texture2D(inputImageTexture, threeStepsPositiveTextureCoordinate);\n" + "lowp vec4 threeStepsNegativeIntensity = texture2D(inputImageTexture, threeStepsNegativeTextureCoordinate);\n" + "\n" + "lowp vec4 maxValue = max(centerIntensity, oneStepPositiveIntensity);\n" + "maxValue = max(maxValue, oneStepNegativeIntensity);\n" + "maxValue = max(maxValue, twoStepsPositiveIntensity);\n" + "maxValue = max(maxValue, twoStepsNegativeIntensity);\n" + "maxValue = max(maxValue, threeStepsPositiveIntensity);\n" + "\n" + "gl_FragColor = max(maxValue, threeStepsNegativeIntensity);\n" + "}\n"; public static final String FRAGMENT_SHADER_4 = "precision highp float;\n" + "\n" + "varying vec2 centerTextureCoordinate;\n" + "varying vec2 oneStepPositiveTextureCoordinate;\n" + "varying vec2 oneStepNegativeTextureCoordinate;\n" + "varying vec2 twoStepsPositiveTextureCoordinate;\n" + "varying vec2 twoStepsNegativeTextureCoordinate;\n" + "varying vec2 threeStepsPositiveTextureCoordinate;\n" + "varying vec2 threeStepsNegativeTextureCoordinate;\n" + "varying vec2 fourStepsPositiveTextureCoordinate;\n" + "varying vec2 fourStepsNegativeTextureCoordinate;\n" + "\n" + "uniform sampler2D inputImageTexture;\n" + "\n" + "void main()\n" + "{\n" + "lowp vec4 centerIntensity = texture2D(inputImageTexture, centerTextureCoordinate);\n" + "lowp vec4 oneStepPositiveIntensity = texture2D(inputImageTexture, oneStepPositiveTextureCoordinate);\n" + "lowp vec4 oneStepNegativeIntensity = texture2D(inputImageTexture, oneStepNegativeTextureCoordinate);\n" + "lowp vec4 twoStepsPositiveIntensity = texture2D(inputImageTexture, twoStepsPositiveTextureCoordinate);\n" + "lowp vec4 twoStepsNegativeIntensity = texture2D(inputImageTexture, twoStepsNegativeTextureCoordinate);\n" + "lowp vec4 threeStepsPositiveIntensity = texture2D(inputImageTexture, threeStepsPositiveTextureCoordinate);\n" + "lowp vec4 threeStepsNegativeIntensity = texture2D(inputImageTexture, threeStepsNegativeTextureCoordinate);\n" + "lowp vec4 fourStepsPositiveIntensity = texture2D(inputImageTexture, fourStepsPositiveTextureCoordinate);\n" + "lowp vec4 fourStepsNegativeIntensity = texture2D(inputImageTexture, fourStepsNegativeTextureCoordinate);\n" + "\n" + "lowp vec4 maxValue = max(centerIntensity, oneStepPositiveIntensity);\n" + "maxValue = max(maxValue, oneStepNegativeIntensity);\n" + "maxValue = max(maxValue, twoStepsPositiveIntensity);\n" + "maxValue = max(maxValue, twoStepsNegativeIntensity);\n" + "maxValue = max(maxValue, threeStepsPositiveIntensity);\n" + "maxValue = max(maxValue, threeStepsNegativeIntensity);\n" + "maxValue = max(maxValue, fourStepsPositiveIntensity);\n" + "\n" + "gl_FragColor = max(maxValue, fourStepsNegativeIntensity);\n" + "}\n"; public GPUImageRGBDilationFilter() { this(1); } /** * Acceptable values for dilationRadius, which sets the distance in pixels to sample out * from the center, are 1, 2, 3, and 4. * * @param radius 1, 2, 3 or 4 */ public GPUImageRGBDilationFilter(int radius) { this(getVertexShader(radius), getFragmentShader(radius)); } private GPUImageRGBDilationFilter(String vertexShader, String fragmentShader) { super(vertexShader, fragmentShader, vertexShader, fragmentShader); } private static String getVertexShader(int radius) { switch (radius) { case 0: case 1: return VERTEX_SHADER_1; case 2: return VERTEX_SHADER_2; case 3: return VERTEX_SHADER_3; default: return VERTEX_SHADER_4; } } private static String getFragmentShader(int radius) { switch (radius) { case 0: case 1: return FRAGMENT_SHADER_1; case 2: return FRAGMENT_SHADER_2; case 3: return FRAGMENT_SHADER_3; default: return FRAGMENT_SHADER_4; } } }