【发布时间】:2014-03-22 07:34:22
【问题描述】:
我正在尝试使用opengl es 2.0在android中创建一个应用程序,该应用程序有一个按下按钮,它将截取屏幕截图并使用任何模糊算法(此处为快速模糊)对其进行模糊处理,并显示模糊的屏幕截图。开发这样一个应用程序的唯一目的是尝试和实现模糊。使用各种互联网资源,我能够截取屏幕截图并实现模糊,但我不知道如何在 opengl 的屏幕上显示模糊的位图。谁能帮我解决这个问题?提前致谢。 以下是我的主要活动:
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();
}
}
以下是我的 MyGLsurfaceview 类:
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);
}
}
以下是我的渲染器类:
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;
}
}
这里使用Fastblur()方法对截图进行模糊处理,返回模糊后的截图。现在,我的问题是如何使用 opengl 显示 Fastblur() 返回的位图?
【问题讨论】:
-
用orthographic projection绘制一个由2个三角形组成的带纹理的四边形(精灵)或使用任何你喜欢的精灵绘图包装器。
标签: android opengl-es bitmap blur