|  | /* | 
|  | * Copyright (C) 2012 The Android Open Source Project | 
|  | * | 
|  | * 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 com.example.android.mediafx; | 
|  |  | 
|  | import android.app.Activity; | 
|  | import android.graphics.Bitmap; | 
|  | import android.graphics.BitmapFactory; | 
|  | import android.graphics.Color; | 
|  | import android.os.Bundle; | 
|  | import android.view.Menu; | 
|  | import android.view.MenuInflater; | 
|  | import android.view.MenuItem; | 
|  |  | 
|  | import android.media.effect.Effect; | 
|  | import android.media.effect.EffectContext; | 
|  | import android.media.effect.EffectFactory; | 
|  |  | 
|  | import android.opengl.GLES20; | 
|  | import android.opengl.GLSurfaceView; | 
|  | import android.opengl.GLUtils; | 
|  |  | 
|  | import javax.microedition.khronos.egl.EGLConfig; | 
|  | import javax.microedition.khronos.opengles.GL10; | 
|  |  | 
|  | public class HelloEffects extends Activity implements GLSurfaceView.Renderer { | 
|  |  | 
|  | private GLSurfaceView mEffectView; | 
|  | private int[] mTextures = new int[2]; | 
|  | private EffectContext mEffectContext; | 
|  | private Effect mEffect; | 
|  | private TextureRenderer mTexRenderer = new TextureRenderer(); | 
|  | private int mImageWidth; | 
|  | private int mImageHeight; | 
|  | private boolean mInitialized = false; | 
|  | int mCurrentEffect; | 
|  |  | 
|  | public void setCurrentEffect(int effect) { | 
|  | mCurrentEffect = effect; | 
|  | } | 
|  |  | 
|  | @Override | 
|  | public void onCreate(Bundle savedInstanceState) { | 
|  | super.onCreate(savedInstanceState); | 
|  | setContentView(R.layout.main); | 
|  | /** | 
|  | * Initialize the renderer and tell it to only render when | 
|  | * explicity requested with the RENDERMODE_WHEN_DIRTY option | 
|  | */ | 
|  | mEffectView = (GLSurfaceView) findViewById(R.id.effectsview); | 
|  | mEffectView.setEGLContextClientVersion(2); | 
|  | mEffectView.setRenderer(this); | 
|  | mEffectView.setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY); | 
|  | mCurrentEffect = R.id.none; | 
|  | } | 
|  |  | 
|  | private void loadTextures() { | 
|  | // Generate textures | 
|  | GLES20.glGenTextures(2, mTextures, 0); | 
|  |  | 
|  | // Load input bitmap | 
|  | Bitmap bitmap = BitmapFactory.decodeResource(getResources(), | 
|  | R.drawable.puppy); | 
|  | mImageWidth = bitmap.getWidth(); | 
|  | mImageHeight = bitmap.getHeight(); | 
|  | mTexRenderer.updateTextureSize(mImageWidth, mImageHeight); | 
|  |  | 
|  | // Upload to texture | 
|  | GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mTextures[0]); | 
|  | GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, bitmap, 0); | 
|  |  | 
|  | // Set texture parameters | 
|  | GLToolbox.initTexParams(); | 
|  | } | 
|  |  | 
|  | private void initEffect() { | 
|  | EffectFactory effectFactory = mEffectContext.getFactory(); | 
|  | if (mEffect != null) { | 
|  | mEffect.release(); | 
|  | } | 
|  | /** | 
|  | * Initialize the correct effect based on the selected menu/action item | 
|  | */ | 
|  | switch (mCurrentEffect) { | 
|  |  | 
|  | case R.id.none: | 
|  | break; | 
|  |  | 
|  | case R.id.autofix: | 
|  | mEffect = effectFactory.createEffect( | 
|  | EffectFactory.EFFECT_AUTOFIX); | 
|  | mEffect.setParameter("scale", 0.5f); | 
|  | break; | 
|  |  | 
|  | case R.id.bw: | 
|  | mEffect = effectFactory.createEffect( | 
|  | EffectFactory.EFFECT_BLACKWHITE); | 
|  | mEffect.setParameter("black", .1f); | 
|  | mEffect.setParameter("white", .7f); | 
|  | break; | 
|  |  | 
|  | case R.id.brightness: | 
|  | mEffect = effectFactory.createEffect( | 
|  | EffectFactory.EFFECT_BRIGHTNESS); | 
|  | mEffect.setParameter("brightness", 2.0f); | 
|  | break; | 
|  |  | 
|  | case R.id.contrast: | 
|  | mEffect = effectFactory.createEffect( | 
|  | EffectFactory.EFFECT_CONTRAST); | 
|  | mEffect.setParameter("contrast", 1.4f); | 
|  | break; | 
|  |  | 
|  | case R.id.crossprocess: | 
|  | mEffect = effectFactory.createEffect( | 
|  | EffectFactory.EFFECT_CROSSPROCESS); | 
|  | break; | 
|  |  | 
|  | case R.id.documentary: | 
|  | mEffect = effectFactory.createEffect( | 
|  | EffectFactory.EFFECT_DOCUMENTARY); | 
|  | break; | 
|  |  | 
|  | case R.id.duotone: | 
|  | mEffect = effectFactory.createEffect( | 
|  | EffectFactory.EFFECT_DUOTONE); | 
|  | mEffect.setParameter("first_color", Color.YELLOW); | 
|  | mEffect.setParameter("second_color", Color.DKGRAY); | 
|  | break; | 
|  |  | 
|  | case R.id.filllight: | 
|  | mEffect = effectFactory.createEffect( | 
|  | EffectFactory.EFFECT_FILLLIGHT); | 
|  | mEffect.setParameter("strength", .8f); | 
|  | break; | 
|  |  | 
|  | case R.id.fisheye: | 
|  | mEffect = effectFactory.createEffect( | 
|  | EffectFactory.EFFECT_FISHEYE); | 
|  | mEffect.setParameter("scale", .5f); | 
|  | break; | 
|  |  | 
|  | case R.id.flipvert: | 
|  | mEffect = effectFactory.createEffect( | 
|  | EffectFactory.EFFECT_FLIP); | 
|  | mEffect.setParameter("vertical", true); | 
|  | break; | 
|  |  | 
|  | case R.id.fliphor: | 
|  | mEffect = effectFactory.createEffect( | 
|  | EffectFactory.EFFECT_FLIP); | 
|  | mEffect.setParameter("horizontal", true); | 
|  | break; | 
|  |  | 
|  | case R.id.grain: | 
|  | mEffect = effectFactory.createEffect( | 
|  | EffectFactory.EFFECT_GRAIN); | 
|  | mEffect.setParameter("strength", 1.0f); | 
|  | break; | 
|  |  | 
|  | case R.id.grayscale: | 
|  | mEffect = effectFactory.createEffect( | 
|  | EffectFactory.EFFECT_GRAYSCALE); | 
|  | break; | 
|  |  | 
|  | case R.id.lomoish: | 
|  | mEffect = effectFactory.createEffect( | 
|  | EffectFactory.EFFECT_LOMOISH); | 
|  | break; | 
|  |  | 
|  | case R.id.negative: | 
|  | mEffect = effectFactory.createEffect( | 
|  | EffectFactory.EFFECT_NEGATIVE); | 
|  | break; | 
|  |  | 
|  | case R.id.posterize: | 
|  | mEffect = effectFactory.createEffect( | 
|  | EffectFactory.EFFECT_POSTERIZE); | 
|  | break; | 
|  |  | 
|  | case R.id.rotate: | 
|  | mEffect = effectFactory.createEffect( | 
|  | EffectFactory.EFFECT_ROTATE); | 
|  | mEffect.setParameter("angle", 180); | 
|  | break; | 
|  |  | 
|  | case R.id.saturate: | 
|  | mEffect = effectFactory.createEffect( | 
|  | EffectFactory.EFFECT_SATURATE); | 
|  | mEffect.setParameter("scale", .5f); | 
|  | break; | 
|  |  | 
|  | case R.id.sepia: | 
|  | mEffect = effectFactory.createEffect( | 
|  | EffectFactory.EFFECT_SEPIA); | 
|  | break; | 
|  |  | 
|  | case R.id.sharpen: | 
|  | mEffect = effectFactory.createEffect( | 
|  | EffectFactory.EFFECT_SHARPEN); | 
|  | break; | 
|  |  | 
|  | case R.id.temperature: | 
|  | mEffect = effectFactory.createEffect( | 
|  | EffectFactory.EFFECT_TEMPERATURE); | 
|  | mEffect.setParameter("scale", .9f); | 
|  | break; | 
|  |  | 
|  | case R.id.tint: | 
|  | mEffect = effectFactory.createEffect( | 
|  | EffectFactory.EFFECT_TINT); | 
|  | mEffect.setParameter("tint", Color.MAGENTA); | 
|  | break; | 
|  |  | 
|  | case R.id.vignette: | 
|  | mEffect = effectFactory.createEffect( | 
|  | EffectFactory.EFFECT_VIGNETTE); | 
|  | mEffect.setParameter("scale", .5f); | 
|  | break; | 
|  |  | 
|  | default: | 
|  | break; | 
|  |  | 
|  | } | 
|  | } | 
|  |  | 
|  | private void applyEffect() { | 
|  | mEffect.apply(mTextures[0], mImageWidth, mImageHeight, mTextures[1]); | 
|  | } | 
|  |  | 
|  | private void renderResult() { | 
|  | if (mCurrentEffect != R.id.none) { | 
|  | // if no effect is chosen, just render the original bitmap | 
|  | mTexRenderer.renderTexture(mTextures[1]); | 
|  | } | 
|  | else { | 
|  | // render the result of applyEffect() | 
|  | mTexRenderer.renderTexture(mTextures[0]); | 
|  | } | 
|  | } | 
|  |  | 
|  | @Override | 
|  | public void onDrawFrame(GL10 gl) { | 
|  | if (!mInitialized) { | 
|  | //Only need to do this once | 
|  | mEffectContext = EffectContext.createWithCurrentGlContext(); | 
|  | mTexRenderer.init(); | 
|  | loadTextures(); | 
|  | mInitialized = true; | 
|  | } | 
|  | if (mCurrentEffect != R.id.none) { | 
|  | //if an effect is chosen initialize it and apply it to the texture | 
|  | initEffect(); | 
|  | applyEffect(); | 
|  | } | 
|  | renderResult(); | 
|  | } | 
|  |  | 
|  | @Override | 
|  | public void onSurfaceChanged(GL10 gl, int width, int height) { | 
|  | if (mTexRenderer != null) { | 
|  | mTexRenderer.updateViewSize(width, height); | 
|  | } | 
|  | } | 
|  |  | 
|  | @Override | 
|  | public void onSurfaceCreated(GL10 gl, EGLConfig config) { | 
|  | } | 
|  |  | 
|  | @Override | 
|  | public boolean onCreateOptionsMenu(Menu menu) { | 
|  | MenuInflater inflater = getMenuInflater(); | 
|  | inflater.inflate(R.menu.options_menu, menu); | 
|  | return true; | 
|  | } | 
|  |  | 
|  | @Override | 
|  | public boolean onOptionsItemSelected(MenuItem item) { | 
|  | setCurrentEffect(item.getItemId()); | 
|  | mEffectView.requestRender(); | 
|  | return true; | 
|  | } | 
|  | } |