How to Display blurred bitmap of screenshot using opengl es 2.0 on android?

*爱你&永不变心* 提交于 2019-12-12 03:41:01

问题


I am trying to create an app, in android using opengl es 2.0, that has a button on pressing which it would take the screenshot and would blurr it using any blur algo (here Fast blur) and would display the blurred screenshot. The sole aim of developing such an app is to try and implement blurring. Using various internet resources i was able to take the screenshot and implement blurring but i dont know how to display the blurred bitmap on the screen in opengl. Can anyone please help me with this? Thanks in advance. Following is my Main activity:

package com.example.ankurtest;

import android.app.Activity;
import android.opengl.GLSurfaceView;
import android.os.Bundle;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;

public class MainActivity extends Activity {
GLSurfaceView mView;
GLRendererEX myRenderer;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    //setContentView(mView);
    mView = (MyGLSurfaceview)findViewById(R.id.glSurfaceViewID);
    myRenderer = new GLRendererEX(this);

    mView.setEGLContextClientVersion(2);
    mView.setRenderer(myRenderer);
    myRenderer.queueDoSomethingNextTick(GLRendererEX.DO_THIS);

    findViewById(R.id.buttonID).setOnTouchListener(new OnTouchListener(){

       /* public void onTouch(MotionEvent event){
            myRenderer.queueDoSomethingNextTick(GLRendererEX.DO_THAT);
           // Compiler might complain about myRenderer not being final
        }*/

        @Override
        public boolean onTouch(View v, MotionEvent event) {
            if(event.getAction() == MotionEvent.ACTION_UP){
            myRenderer.queueDoSomethingNextTick(GLRendererEX.DO_THAT);
            return true;
            }
            return false;
        }
});
}

@Override
protected void onPause() {
    // TODO Auto-generated method stub
    super.onPause();
    mView.onPause();
}

@Override
protected void onResume() {
    // TODO Auto-generated method stub
    super.onResume();
    mView.onResume();
}

    }

Following is my MyGLsurfaceview class:

package com.example.ankurtest;

import android.content.Context;
import android.opengl.GLSurfaceView;
import android.util.AttributeSet;

public class MyGLSurfaceview extends GLSurfaceView {

//private final GLRendererEX mRenderer;

public MyGLSurfaceview(Context context) {
    super(context);

    // Create an OpenGL ES 2.0 context.
    //setEGLContextClientVersion(2);

    // Set the Renderer for drawing on the GLSurfaceView
    //mRenderer = new GLRendererEX();
    //setRenderer(mRenderer);

    // Render the view only when there is a change in the drawing data
    setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY);
}
public MyGLSurfaceview(Context context, AttributeSet attrs)
{
  super(context, attrs);

  // Create an OpenGL ES 2.0 context.
  setEGLContextClientVersion(2);

  // Set the Renderer for drawing on the GLSurfaceView
  //mRenderer = new GLRendererEX();
  //setRenderer(mRenderer);
}

}

Following is my Renderer class:

package com.example.ankurtest;

import java.nio.ByteBuffer;
import java.nio.ByteOrder;

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

import android.annotation.TargetApi;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Point;
import android.opengl.GLES20;
import android.opengl.GLSurfaceView.Renderer;
import android.os.Build;
import android.view.Display;
import android.view.WindowManager;

@TargetApi(Build.VERSION_CODES.HONEYCOMB_MR2)
public class GLRendererEX implements Renderer{

private final Context context;

private int command;
public static final int DO_THIS = 1;
public static final int DO_THAT = 2;


public GLRendererEX(Context activitycontext) {
    context = activitycontext;

}


public void onSurfaceCreated(GL10 gl, EGLConfig config) {
    GLES20.glClearColor(0.8f, 0.0f, 0.2f, 1f);

    // TODO Auto-generated method stub

}
@Override
public void onDrawFrame(GL10 gl) {

    if (command==DO_THAT) {
        GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);

        Point size = new Point();
        WindowManager wm = (WindowManager)  context.getSystemService(Context.WINDOW_SERVICE);
        Display display = wm.getDefaultDisplay();
        //myactivity.getWindowManager().getDefaultDisplay().getSize(size);
        display.getSize(size);
        int width = size.x; // use your favorite width
        int height = size.y; // use your favorite height
        int screenshotSize = width * height;
        ByteBuffer bb = ByteBuffer.allocateDirect(screenshotSize * 4);
        bb.order(ByteOrder.nativeOrder());
        GLES20.glReadPixels(0, 0, width, height, GLES20.GL_RGBA, GLES20.GL_UNSIGNED_BYTE, bb);
        int pixelsBuffer[] = new int[screenshotSize];
        bb.asIntBuffer().get(pixelsBuffer);
        bb = null;

        for (int i = 0; i < screenshotSize; ++i) {
            // The alpha and green channels' positions are preserved while the      red and blue are swapped
            pixelsBuffer[i] = ((pixelsBuffer[i] & 0xff00ff00)) |    ((pixelsBuffer[i] & 0x000000ff) << 16) | ((pixelsBuffer[i] & 0x00ff0000) >> 16);
        }

        Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
        bitmap.setPixels(pixelsBuffer, screenshotSize-width, -width, 0, 0, width, height);
Bitmap fast = Fastblur(bitmap,10);
        command = DO_THIS;
    }
    // TODO Auto-generated method stub

}

@Override
public void onSurfaceChanged(GL10 gl, int width, int height) {
    // TODO Auto-generated method stub

}

public void queueDoSomethingNextTick(int command){

    this.command = command;

}

}

Herein Fastblur() method is used to blur the screenshot and it returns the blurred screenshot. Now, my question is how to display the bitmap returned by Fastblur() using opengl?


回答1:


The common method to display a full sized image is to use an orthogonal projection matrix:

(example using fixed functionality)

GLES20.glViewport(0, 0, windowWidth, windowHeight);
GLES20.glMatrixMode(GL_PROJECTION);
GLES20.glLoadIdentity();
GLES20.glOrtho(-1, 1, -1, 1, 1, -1);

than draw a fullscreen quad with your image bound as texture2D.

basic texture tutorial here.

basic quad tutorial here.

set quad coordinate as follow:

static float squareCoords[] = {
        -1f, -1f, 0.0f,   // top left
        -1f, 1f, 0.0f,   // bottom left
         1f, 1f, 0.0f,   // bottom right
         1f, -1f, 0.0f }; // top right


来源:https://stackoverflow.com/questions/22574817/how-to-display-blurred-bitmap-of-screenshot-using-opengl-es-2-0-on-android

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!