| /* | |
| * 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; | |
| } | |
| } |