Skip to content

Commit 53b354a

Browse files
committed
Merge pull request cats-oss#6 from swcai/develop
x86 support, GPUImageHueFilter, GPUImagePixelationFilter
2 parents 72234e4 + 53f3230 commit 53b354a

File tree

6 files changed

+237
-2
lines changed

6 files changed

+237
-2
lines changed

library/jni/Application.mk

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
# Build both ARMv5TE and ARMv7-A machine code.
2+
APP_ABI := armeabi x86

library/src/jp/co/cyberagent/android/gpuimage/GPUImageFilter.java

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -156,16 +156,55 @@ public int getUniformTexture() {
156156
return mGLUniformTexture;
157157
}
158158

159-
protected void setFloat(final int location, final float floatValue) {
159+
protected void setInteger(final int location, final int intValue) {
160160
runOnDraw(new Runnable() {
161+
@Override public void run() {
162+
GLES20.glUniform1i(location, intValue);
163+
}
164+
});
165+
}
161166

167+
protected void setFloat(final int location, final float floatValue) {
168+
runOnDraw(new Runnable() {
162169
@Override
163170
public void run() {
164171
GLES20.glUniform1f(location, floatValue);
165172
}
166173
});
167174
}
168175

176+
protected void setFloatVec2(final int location, final float[] arrayValue) {
177+
runOnDraw(new Runnable() {
178+
@Override public void run() {
179+
GLES20.glUniform2fv(location, 1, arrayValue);
180+
}
181+
});
182+
}
183+
184+
protected void setFloatVec3(final int location, final float[] arrayValue) {
185+
runOnDraw(new Runnable() {
186+
@Override public void run() {
187+
GLES20.glUniform3fv(location, 1, arrayValue);
188+
}
189+
});
190+
}
191+
192+
protected void setFloatVec4(final int location, final float[] arrayValue) {
193+
runOnDraw(new Runnable() {
194+
@Override public void run() {
195+
GLES20.glUniform4fv(location, 1, arrayValue);
196+
}
197+
});
198+
}
199+
200+
protected void setFloatArray(final int location, final float[] arrayValue) {
201+
runOnDraw(new Runnable() {
202+
@Override public void run() {
203+
GLES20.glUniform1fv(location, sizeof(arrayValue), arrayValue);
204+
}
205+
});
206+
}
207+
169208
protected void setUniformMatrix3f(final int location, final float[] matrix) {
170209
runOnDraw(new Runnable() {
171210

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
package jp.co.cyberagent.android.gpuimage;
2+
3+
import android.opengl.GLES20;
4+
5+
public class GPUImageHueFilter extends GPUImageFilter {
6+
public static final String HUE_FRAGMENT_SHADER = "" +
7+
"precision highp float;\n" +
8+
"varying highp vec2 textureCoordinate;\n" +
9+
"\n" +
10+
"uniform sampler2D inputImageTexture;\n" +
11+
"uniform mediump float hueAdjust;\n" +
12+
"const highp vec4 kRGBToYPrime = vec4 (0.299, 0.587, 0.114, 0.0);\n" +
13+
"const highp vec4 kRGBToI = vec4 (0.595716, -0.274453, -0.321263, 0.0);\n" +
14+
"const highp vec4 kRGBToQ = vec4 (0.211456, -0.522591, 0.31135, 0.0);\n" +
15+
"\n" +
16+
"const highp vec4 kYIQToR = vec4 (1.0, 0.9563, 0.6210, 0.0);\n" +
17+
"const highp vec4 kYIQToG = vec4 (1.0, -0.2721, -0.6474, 0.0);\n" +
18+
"const highp vec4 kYIQToB = vec4 (1.0, -1.1070, 1.7046, 0.0);\n" +
19+
"\n" +
20+
"void main ()\n" +
21+
"{\n" +
22+
" // Sample the input pixel\n" +
23+
" highp vec4 color = texture2D(inputImageTexture, textureCoordinate);\n" +
24+
"\n" +
25+
" // Convert to YIQ\n" +
26+
" highp float YPrime = dot (color, kRGBToYPrime);\n" +
27+
" highp float I = dot (color, kRGBToI);\n" +
28+
" highp float Q = dot (color, kRGBToQ);\n" +
29+
"\n" +
30+
" // Calculate the hue and chroma\n" +
31+
" highp float hue = atan (Q, I);\n" +
32+
" highp float chroma = sqrt (I * I + Q * Q);\n" +
33+
"\n" +
34+
" // Make the user's adjustments\n" +
35+
" hue += (-hueAdjust); //why negative rotation?\n" +
36+
"\n" +
37+
" // Convert back to YIQ\n" +
38+
" Q = chroma * sin (hue);\n" +
39+
" I = chroma * cos (hue);\n" +
40+
"\n" +
41+
" // Convert back to RGB\n" +
42+
" highp vec4 yIQ = vec4 (YPrime, I, Q, 0.0);\n" +
43+
" color.r = dot (yIQ, kYIQToR);\n" +
44+
" color.g = dot (yIQ, kYIQToG);\n" +
45+
" color.b = dot (yIQ, kYIQToB);\n" +
46+
"\n" +
47+
" // Save the result\n" +
48+
" gl_FragColor = color;\n" +
49+
"}\n";
50+
51+
private float mHue;
52+
private int mHueLocation;
53+
54+
public GPUImageHueFilter() {
55+
this(90.0f);
56+
}
57+
58+
public GPUImageHueFilter(final float hue) {
59+
super(NO_FILTER_VERTEX_SHADER, HUE_FRAGMENT_SHADER);
60+
mHue = hue;
61+
}
62+
63+
@Override
64+
public void onInit() {
65+
super.onInit();
66+
mHueLocation = GLES20.glGetUniformLocation(getProgram(), "hueAdjust");
67+
}
68+
69+
@Override
70+
public void onInitialized() {
71+
super.onInitialized();
72+
setHue(mHue);
73+
}
74+
75+
public void setHue(final float hue) {
76+
mHue = hue;
77+
float hueAdjust = (mHue % 360.0f) * (float) Math.PI / 180.0f;
78+
setFloat(mHueLocation, hueAdjust);
79+
}
80+
}
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
/*
2+
* Copyright (C) 2012 CyberAgent
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package jp.co.cyberagent.android.gpuimage;
18+
19+
import android.opengl.GLES20;
20+
/**
21+
* Applies a grayscale effect to the image.
22+
*/
23+
public class GPUImagePixelationFilter extends GPUImageFilter {
24+
public static final String PIXELATION_FRAGMENT_SHADER = "" +
25+
"precision highp float;\n" +
26+
27+
"varying vec2 textureCoordinate;\n" +
28+
29+
"uniform float imageWidthFactor;\n" +
30+
"uniform float imageHeightFactor;\n" +
31+
"uniform sampler2D inputImageTexture;\n" +
32+
"uniform float pixel;\n" +
33+
34+
"void main()\n" +
35+
"{\n" +
36+
" vec2 uv = textureCoordinate.xy;\n" +
37+
" float dx = pixel * imageWidthFactor;\n" +
38+
" float dy = pixel * imageHeightFactor;\n" +
39+
" vec2 coord = vec2(dx * floor(uv.x / dx), dy * floor(uv.y / dy));\n" +
40+
" vec3 tc = texture2D(inputImageTexture, coord).xyz;\n" +
41+
" gl_FragColor = vec4(tc, 1.0);\n" +
42+
"}";
43+
44+
private int mImageWidthFactorLocation;
45+
private int mImageHeightFactorLocation;
46+
private float mPixel;
47+
private int mPixelLocation;
48+
49+
public GPUImagePixelationFilter() {
50+
super(NO_FILTER_VERTEX_SHADER, PIXELATION_FRAGMENT_SHADER);
51+
mPixel = 1.0f;
52+
}
53+
54+
@Override
55+
public void onInit() {
56+
super.onInit();
57+
mImageWidthFactorLocation = GLES20.glGetUniformLocation(getProgram(), "imageWidthFactor");
58+
mImageHeightFactorLocation = GLES20.glGetUniformLocation(getProgram(), "imageHeightFactor");
59+
mPixelLocation = GLES20.glGetUniformLocation(getProgram(), "pixel");
60+
setPixel(mPixel);
61+
}
62+
63+
@Override
64+
public void onOutputSizeChanged(final int width, final int height) {
65+
super.onOutputSizeChanged(width, height);
66+
setFloat(mImageWidthFactorLocation, 1.0f / width);
67+
setFloat(mImageHeightFactorLocation, 1.0f / height);
68+
}
69+
70+
public void setPixel(final float pixel) {
71+
mPixel = pixel;
72+
setFloat(mPixelLocation, mPixel);
73+
}
74+
}

sample/src/jp/co/cyberagent/android/gpuimage/sample/GPUImageFilterTools.java

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@
3434
import jp.co.cyberagent.android.gpuimage.GPUImageSharpenFilter;
3535
import jp.co.cyberagent.android.gpuimage.GPUImageSobelEdgeDetection;
3636
import jp.co.cyberagent.android.gpuimage.GPUImageColorInvertFilter;
37+
import jp.co.cyberagent.android.gpuimage.GPUImageHueFilter;
38+
import jp.co.cyberagent.android.gpuimage.GPUImagePixelationFilter;
3739
import android.app.AlertDialog;
3840
import android.content.Context;
3941
import android.content.DialogInterface;
@@ -44,6 +46,8 @@ public static void showDialog(final Context context,
4446
final FilterList filters = new FilterList();
4547
filters.addFilter("Contrast", FilterType.CONTRAST);
4648
filters.addFilter("Invert", FilterType.INVERT);
49+
filters.addFilter("Pixelation", FilterType.PIXELATION);
50+
filters.addFilter("Hue", FilterType.HUE);
4751
filters.addFilter("Gamma", FilterType.GAMMA);
4852
filters.addFilter("Brightness", FilterType.BRIGHTNESS);
4953
filters.addFilter("Sepia", FilterType.SEPIA);
@@ -76,6 +80,10 @@ private static GPUImageFilter createFilterForType(final Context context, final F
7680
return new GPUImageGammaFilter(2.0f);
7781
case INVERT:
7882
return new GPUImageColorInvertFilter();
83+
case PIXELATION:
84+
return new GPUImagePixelationFilter();
85+
case HUE:
86+
return new GPUImageHueFilter(90.0f);
7987
case BRIGHTNESS:
8088
return new GPUImageBrightnessFilter(1.5f);
8189
case GRAYSCALE:
@@ -117,7 +125,7 @@ public interface OnGpuImageFilterChosenListener {
117125
}
118126

119127
private enum FilterType {
120-
CONTRAST, GRAYSCALE, SHARPEN, SEPIA, SOBEL_EDGE_DETECTION, THREE_X_THREE_CONVOLUTION, FILTER_GROUP, EMBOSS, POSTERIZE, GAMMA, BRIGHTNESS, INVERT,
128+
CONTRAST, GRAYSCALE, SHARPEN, SEPIA, SOBEL_EDGE_DETECTION, THREE_X_THREE_CONVOLUTION, FILTER_GROUP, EMBOSS, POSTERIZE, GAMMA, BRIGHTNESS, INVERT, HUE, PIXELATION,
121129
}
122130

123131
private static class FilterList {
@@ -150,8 +158,12 @@ public FilterAdjuster(final GPUImageFilter filter) {
150158
adjuster = new GPU3x3TextureAdjuster().filter(filter);
151159
} else if (filter instanceof GPUImageEmbossFilter) {
152160
adjuster = new EmbossAdjuster().filter(filter);
161+
} else if (filter instanceof GPUImageHueFilter) {
162+
adjuster = new HueAdjuster().filter(filter);
153163
} else if (filter instanceof GPUImagePosterizeFilter) {
154164
adjuster = new PosterizeAdjuster().filter(filter);
165+
} else if (filter instanceof GPUImagePixelationFilter) {
166+
adjuster = new PixelationAdjuster().filter(filter);
155167
} else {
156168
adjuster = null;
157169
}
@@ -194,6 +206,20 @@ public void adjust(final int percentage) {
194206
}
195207
}
196208

209+
private class PixelationAdjuster extends Adjuster<GPUImagePixelationFilter> {
210+
@Override
211+
public void adjust(final int percentage) {
212+
getFilter().setPixel(range(percentage, 1.0f, 100.0f));
213+
}
214+
}
215+
216+
private class HueAdjuster extends Adjuster<GPUImageHueFilter> {
217+
@Override
218+
public void adjust(final int percentage) {
219+
getFilter().setHue(range(percentage, 0.0f, 360.0f));
220+
}
221+
}
222+
197223
private class ContrastAdjuster extends Adjuster<GPUImageContrastFilter> {
198224
@Override
199225
public void adjust(final int percentage) {

utils/Shader2String.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
#!/usr/bin/python
2+
3+
import sys
4+
5+
f = sys.stdin
6+
if len(sys.argv) > 1:
7+
f = open(sys.argv[1])
8+
9+
lines = f.readlines()
10+
for line in lines[:-1]:
11+
print '"' + line.rstrip() + '\\n\" +'
12+
print '"' + lines[-1].rstrip() + '\\n\"'
13+
14+
f.close()

0 commit comments

Comments
 (0)