Android Open Source - camera-shade Edge Detection Renderer






From Project

Back to project page camera-shade.

License

The source code is released under:

MIT License

If you think the Android project camera-shade listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.

Java Source Code

package bwr.camerashade;
//from  ww w.j a  va2 s  . com
import android.util.Log;
import java.io.IOException;
import java.io.InputStream;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import java.util.concurrent.locks.ReentrantLock;

import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;

import android.content.Context;
import android.graphics.SurfaceTexture;
import android.graphics.SurfaceTexture.OnFrameAvailableListener;
import android.hardware.Camera;
import static android.opengl.GLES20.*;
import android.opengl.GLES11Ext;
import android.opengl.GLSurfaceView;
import android.opengl.GLUtils;

public class EdgeDetectionRenderer extends GLSurfaceView implements GLSurfaceView.Renderer, OnFrameAvailableListener {
  private static String TAG = "CameraShade";
  
  private final int FLOAT_SIZE_BYTES = 4;
  
  private FloatBuffer vertexBuffer;
  private int vertexPositionAttribute;
  private int imageInputTexture;

  // A triangle that covers the entire viewport
  private final float[] vertex_array = {
      -2.0f, -1.0f, 
       0.0f, 3.0f, 
       3.0f, -1.0f, 
  };

  private SurfaceTexture surfaceTexture = null;
  private int shaderProgram;
  private int vertexShader;
  private int fragmentShader;
  private int displayWidth, displayHeight;
  private boolean newFrameAvailable = false;

  private Camera camera;
  private ReentrantLock lock = new ReentrantLock();

  private void checkGlError(String op) {
    int error;
    while ((error = glGetError()) != GL_NO_ERROR) {
      Log.e(TAG, op + ": glError " + error);
      Log.e(TAG, GLUtils.getEGLErrorString(error));

      throw new RuntimeException(op + ": glError " + error);
    }
  }

  public EdgeDetectionRenderer(Context context) {
    super(context);
    setEGLContextClientVersion(2);
    setRenderer(this);

    setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY);

    vertexBuffer = ByteBuffer
        .allocateDirect(vertex_array.length * FLOAT_SIZE_BYTES)
        .order(ByteOrder.nativeOrder()).asFloatBuffer();
    vertexBuffer.put(vertex_array).position(0);
  }

  private int loadShader(int shaderType, String source) {
    int shader = glCreateShader(shaderType);
    if (shader != 0) {
      glShaderSource(shader, source);
      glCompileShader(shader);
      int[] compiled = new int[1];
      glGetShaderiv(shader, GL_COMPILE_STATUS, compiled, 0);
      if (compiled[0] == 0) {
        Log.e(TAG, "Could not compile shader " + shaderType + ":");
        Log.e(TAG, glGetShaderInfoLog(shader));
        glDeleteShader(shader);
        shader = 0;
      }
    }
    return shader;
  }

  private int loadShaderAsset(int type, String asset) {
    StringBuffer sourceBuffer = new StringBuffer();

    byte[] buffer = new byte[1024];

    try {
      InputStream in = getContext().getAssets().open(asset);
      int len;
      while ((len = in.read(buffer)) > 0) {
        sourceBuffer.append(new String(buffer, 0, len));
      }
      in.close();

      String shaderSource = sourceBuffer.toString();

      return loadShader(type, shaderSource);

    } catch (IOException e) {
      e.printStackTrace();
    }

    return 0;
  }

  @Override
  public void onPause() {
    super.onPause();

    if (camera != null) {
      camera.stopPreview();
      camera.release();
      camera = null;
    }
  }

  @Override
  public void onResume() {
    super.onResume();
  }

  @Override
  public void onDrawFrame(GL10 nil) {
    if (surfaceTexture == null) {
      glClear(GL_COLOR_BUFFER_BIT);
      return;
    }

    lock.lock();
    try {
      if (newFrameAvailable) {
        surfaceTexture.updateTexImage();
        newFrameAvailable = false;
      } else {
        glClear(GL_COLOR_BUFFER_BIT);
        return;
      }

      glUseProgram(shaderProgram);
      checkGlError("use program");

      int th = glGetUniformLocation(shaderProgram, "inputImage");
      glActiveTexture(GL_TEXTURE0);
      glBindTexture(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, imageInputTexture);
      glUniform1i(th, 0);
      
      int displayUniform = glGetUniformLocation(shaderProgram, "display");
      glUniform2f(displayUniform, displayWidth, displayHeight);
      
      vertexPositionAttribute = glGetAttribLocation(shaderProgram, "position");
      checkGlError("get position handle");

      vertexBuffer.position(0);
      glVertexAttribPointer(vertexPositionAttribute, 2, GL_FLOAT, false,
          FLOAT_SIZE_BYTES * 2, vertexBuffer);
      checkGlError("vertices");

      glEnableVertexAttribArray(vertexPositionAttribute);
      checkGlError("position handle");

      glDrawArrays(GL_TRIANGLES, 0, 3);
      checkGlError("draw arrays");
      glFlush();
    } finally {
      lock.unlock();
    }
  }

  private void initSurfaceTexture() {
    int[] textures = new int[1];
    glGenTextures(1, textures, 0);
    glBindTexture(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, textures[0]);
    glTexParameteri(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_S, GL_REPEAT);
    glTexParameteri(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_T, GL_REPEAT);
    glTexParameteri(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexParameteri(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MAG_FILTER, GL_NEAREST);

    imageInputTexture = textures[0];
    
    surfaceTexture = new SurfaceTexture(imageInputTexture);
    surfaceTexture.setOnFrameAvailableListener(this);
  }

  public void setupStuff() {
    initSurfaceTexture();

    vertexShader = loadShaderAsset(GL_VERTEX_SHADER, "vertex.glsl");
    fragmentShader = loadShaderAsset(GL_FRAGMENT_SHADER, "fragment.glsl");
    
    shaderProgram = glCreateProgram();
    if (shaderProgram != 0) {
      glAttachShader(shaderProgram, vertexShader);
      checkGlError("glAttachShader");
      glAttachShader(shaderProgram, fragmentShader);
      checkGlError("glAttachShader");
      glLinkProgram(shaderProgram);
      int[] linkStatus = new int[1];
      glGetProgramiv(shaderProgram, GL_LINK_STATUS, linkStatus, 0);
      if (linkStatus[0] != GL_TRUE) {
        Log.e(TAG, "Could not link program: ");
        Log.e(TAG, glGetProgramInfoLog(shaderProgram));
        glDeleteProgram(shaderProgram);
        shaderProgram = 0;
      }
    }

  }

  @Override
  public void onSurfaceChanged(GL10 nil, int width, int height) {
    glViewport(0, 0, width, height);
    
    displayWidth = width;
    displayHeight = height;
    
    camera = Camera.open();
    try {
      camera.setPreviewTexture(surfaceTexture);
    } catch (IOException e) {
      e.printStackTrace(); 
    }

    Camera.Parameters param = camera.getParameters();
        
    camera.setParameters(param);
    
    camera.startPreview();
  }

  @Override
  public void onSurfaceCreated(GL10 nil, EGLConfig glConfig) {
    glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
    setupStuff();
  }

  @Override
  public void onFrameAvailable(SurfaceTexture surfaceTexture) {
    lock.lock();
    try {
      newFrameAvailable = true;
    } finally {
      lock.unlock();
      requestRender();
    }
  }

}




Java Source Code List

bwr.camerashade.EdgeDetectionRenderer.java
bwr.camerashade.MainActivity.java