1 /* 2 * Copyright (C) 2012 The Android Open Source Project 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 com.example.android.mediafx; 18 19 import android.app.Activity; 20 import android.graphics.Bitmap; 21 import android.graphics.BitmapFactory; 22 import android.graphics.Color; 23 import android.os.Bundle; 24 import android.view.Menu; 25 import android.view.MenuInflater; 26 import android.view.MenuItem; 27 28 import android.media.effect.Effect; 29 import android.media.effect.EffectContext; 30 import android.media.effect.EffectFactory; 31 32 import android.opengl.GLES20; 33 import android.opengl.GLSurfaceView; 34 import android.opengl.GLUtils; 35 36 import javax.microedition.khronos.egl.EGLConfig; 37 import javax.microedition.khronos.opengles.GL10; 38 39 public class HelloEffects extends Activity implements GLSurfaceView.Renderer { 40 41 private GLSurfaceView mEffectView; 42 private int[] mTextures = new int[2]; 43 private EffectContext mEffectContext; 44 private Effect mEffect; 45 private TextureRenderer mTexRenderer = new TextureRenderer(); 46 private int mImageWidth; 47 private int mImageHeight; 48 private boolean mInitialized = false; 49 int mCurrentEffect; 50 setCurrentEffect(int effect)51 public void setCurrentEffect(int effect) { 52 mCurrentEffect = effect; 53 } 54 55 @Override onCreate(Bundle savedInstanceState)56 public void onCreate(Bundle savedInstanceState) { 57 super.onCreate(savedInstanceState); 58 setContentView(R.layout.main); 59 /** 60 * Initialize the renderer and tell it to only render when 61 * explicity requested with the RENDERMODE_WHEN_DIRTY option 62 */ 63 mEffectView = (GLSurfaceView) findViewById(R.id.effectsview); 64 mEffectView.setEGLContextClientVersion(2); 65 mEffectView.setRenderer(this); 66 mEffectView.setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY); 67 mCurrentEffect = R.id.none; 68 } 69 loadTextures()70 private void loadTextures() { 71 // Generate textures 72 GLES20.glGenTextures(2, mTextures, 0); 73 74 // Load input bitmap 75 Bitmap bitmap = BitmapFactory.decodeResource(getResources(), 76 R.drawable.puppy); 77 mImageWidth = bitmap.getWidth(); 78 mImageHeight = bitmap.getHeight(); 79 mTexRenderer.updateTextureSize(mImageWidth, mImageHeight); 80 81 // Upload to texture 82 GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mTextures[0]); 83 GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, bitmap, 0); 84 85 // Set texture parameters 86 GLToolbox.initTexParams(); 87 } 88 initEffect()89 private void initEffect() { 90 EffectFactory effectFactory = mEffectContext.getFactory(); 91 if (mEffect != null) { 92 mEffect.release(); 93 } 94 /** 95 * Initialize the correct effect based on the selected menu/action item 96 */ 97 switch (mCurrentEffect) { 98 99 case R.id.none: 100 break; 101 102 case R.id.autofix: 103 mEffect = effectFactory.createEffect( 104 EffectFactory.EFFECT_AUTOFIX); 105 mEffect.setParameter("scale", 0.5f); 106 break; 107 108 case R.id.bw: 109 mEffect = effectFactory.createEffect( 110 EffectFactory.EFFECT_BLACKWHITE); 111 mEffect.setParameter("black", .1f); 112 mEffect.setParameter("white", .7f); 113 break; 114 115 case R.id.brightness: 116 mEffect = effectFactory.createEffect( 117 EffectFactory.EFFECT_BRIGHTNESS); 118 mEffect.setParameter("brightness", 2.0f); 119 break; 120 121 case R.id.contrast: 122 mEffect = effectFactory.createEffect( 123 EffectFactory.EFFECT_CONTRAST); 124 mEffect.setParameter("contrast", 1.4f); 125 break; 126 127 case R.id.crossprocess: 128 mEffect = effectFactory.createEffect( 129 EffectFactory.EFFECT_CROSSPROCESS); 130 break; 131 132 case R.id.documentary: 133 mEffect = effectFactory.createEffect( 134 EffectFactory.EFFECT_DOCUMENTARY); 135 break; 136 137 case R.id.duotone: 138 mEffect = effectFactory.createEffect( 139 EffectFactory.EFFECT_DUOTONE); 140 mEffect.setParameter("first_color", Color.YELLOW); 141 mEffect.setParameter("second_color", Color.DKGRAY); 142 break; 143 144 case R.id.filllight: 145 mEffect = effectFactory.createEffect( 146 EffectFactory.EFFECT_FILLLIGHT); 147 mEffect.setParameter("strength", .8f); 148 break; 149 150 case R.id.fisheye: 151 mEffect = effectFactory.createEffect( 152 EffectFactory.EFFECT_FISHEYE); 153 mEffect.setParameter("scale", .5f); 154 break; 155 156 case R.id.flipvert: 157 mEffect = effectFactory.createEffect( 158 EffectFactory.EFFECT_FLIP); 159 mEffect.setParameter("vertical", true); 160 break; 161 162 case R.id.fliphor: 163 mEffect = effectFactory.createEffect( 164 EffectFactory.EFFECT_FLIP); 165 mEffect.setParameter("horizontal", true); 166 break; 167 168 case R.id.grain: 169 mEffect = effectFactory.createEffect( 170 EffectFactory.EFFECT_GRAIN); 171 mEffect.setParameter("strength", 1.0f); 172 break; 173 174 case R.id.grayscale: 175 mEffect = effectFactory.createEffect( 176 EffectFactory.EFFECT_GRAYSCALE); 177 break; 178 179 case R.id.lomoish: 180 mEffect = effectFactory.createEffect( 181 EffectFactory.EFFECT_LOMOISH); 182 break; 183 184 case R.id.negative: 185 mEffect = effectFactory.createEffect( 186 EffectFactory.EFFECT_NEGATIVE); 187 break; 188 189 case R.id.posterize: 190 mEffect = effectFactory.createEffect( 191 EffectFactory.EFFECT_POSTERIZE); 192 break; 193 194 case R.id.rotate: 195 mEffect = effectFactory.createEffect( 196 EffectFactory.EFFECT_ROTATE); 197 mEffect.setParameter("angle", 180); 198 break; 199 200 case R.id.saturate: 201 mEffect = effectFactory.createEffect( 202 EffectFactory.EFFECT_SATURATE); 203 mEffect.setParameter("scale", .5f); 204 break; 205 206 case R.id.sepia: 207 mEffect = effectFactory.createEffect( 208 EffectFactory.EFFECT_SEPIA); 209 break; 210 211 case R.id.sharpen: 212 mEffect = effectFactory.createEffect( 213 EffectFactory.EFFECT_SHARPEN); 214 break; 215 216 case R.id.temperature: 217 mEffect = effectFactory.createEffect( 218 EffectFactory.EFFECT_TEMPERATURE); 219 mEffect.setParameter("scale", .9f); 220 break; 221 222 case R.id.tint: 223 mEffect = effectFactory.createEffect( 224 EffectFactory.EFFECT_TINT); 225 mEffect.setParameter("tint", Color.MAGENTA); 226 break; 227 228 case R.id.vignette: 229 mEffect = effectFactory.createEffect( 230 EffectFactory.EFFECT_VIGNETTE); 231 mEffect.setParameter("scale", .5f); 232 break; 233 234 default: 235 break; 236 237 } 238 } 239 applyEffect()240 private void applyEffect() { 241 mEffect.apply(mTextures[0], mImageWidth, mImageHeight, mTextures[1]); 242 } 243 renderResult()244 private void renderResult() { 245 if (mCurrentEffect != R.id.none) { 246 // if no effect is chosen, just render the original bitmap 247 mTexRenderer.renderTexture(mTextures[1]); 248 } 249 else { 250 // render the result of applyEffect() 251 mTexRenderer.renderTexture(mTextures[0]); 252 } 253 } 254 255 @Override onDrawFrame(GL10 gl)256 public void onDrawFrame(GL10 gl) { 257 if (!mInitialized) { 258 //Only need to do this once 259 mEffectContext = EffectContext.createWithCurrentGlContext(); 260 mTexRenderer.init(); 261 loadTextures(); 262 mInitialized = true; 263 } 264 if (mCurrentEffect != R.id.none) { 265 //if an effect is chosen initialize it and apply it to the texture 266 initEffect(); 267 applyEffect(); 268 } 269 renderResult(); 270 } 271 272 @Override onSurfaceChanged(GL10 gl, int width, int height)273 public void onSurfaceChanged(GL10 gl, int width, int height) { 274 if (mTexRenderer != null) { 275 mTexRenderer.updateViewSize(width, height); 276 } 277 } 278 279 @Override onSurfaceCreated(GL10 gl, EGLConfig config)280 public void onSurfaceCreated(GL10 gl, EGLConfig config) { 281 } 282 283 @Override onCreateOptionsMenu(Menu menu)284 public boolean onCreateOptionsMenu(Menu menu) { 285 MenuInflater inflater = getMenuInflater(); 286 inflater.inflate(R.menu.options_menu, menu); 287 return true; 288 } 289 290 @Override onOptionsItemSelected(MenuItem item)291 public boolean onOptionsItemSelected(MenuItem item) { 292 setCurrentEffect(item.getItemId()); 293 mEffectView.requestRender(); 294 return true; 295 } 296 } 297