本文介绍了显示黑屏,同时GLSurfaceView捕获屏幕截图的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我徘徊了七个小时来解决我的问题。我创建的项目中,即时通讯使用的 GLSurfaceView 上,我已设置一个图像之后,我在使用上实现它不同的效果的 EffectFactory 类。

但我的问题是,当我已经采取了截屏与影响的图像,它总是显示为黑屏,而不是与形象。我知道这可能是因为 SurFaceview 的。但是,如果有任何建议,这可能是对我有帮助的。

在此先感谢。

下面是我的code。

 公共类EffectsFilterActivity扩展活动器具
    GLSurfaceView.Renderer {

私人GLSurfaceView mEffectView;
私人INT [] mTextures =新INT [2];
私人EffectContext mEffectContext;
民营影响mEffect;
私人TextureRenderer mTexRenderer =新TextureRenderer();
私人诠释mImageWidth;
私人诠释mImageHeight;
私人布尔mInitialized = FALSE;
INT mCurrentEffect;

公共无效setCurrentEffect(INT效应){
    mCurrentEffect =效果;
}

@覆盖
公共无效的onCreate(包savedInstanceState){
    super.onCreate(savedInstanceState);
    requestWindowFeature(Window.FEATURE_NO_TITLE);
    的setContentView(R.layout.main);

    按钮B =(按钮)findViewById(R.id.button1);
    b.setOnClickListener(新OnClickListener(){

        @覆盖
        公共无效的onClick(视图v){
            // TODO自动生成方法存根
            位图B = takeScreenshot();
            saveBitmap(B);

        }
    });

    mEffectView =(GLSurfaceView)findViewById(R.id.effectsview);
    mEffectView.setEGLContextClientVersion(2);
    mEffectView.setRenderer(本);
    mEffectView.setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY);
    mCurrentEffect = R.id.none;
}

私人无效loadTextures(){
    //生成纹理
    GLES20.glGenTextures(2,mTextures,0);

    //装载输入位
    点阵位图= BitmapFactory.de codeResource(getResources()
            R.drawable.puppy);
    mImageWidth = bitmap.getWidth();
    mImageHeight = bitmap.getHeight();
    mTexRenderer.updateTextureSize(mImageWidth,mImageHeight);

    //上传到纹理
    GLES20.glBindTexture(GLES20.GL_TEXTURE_2D,mTextures [0]);
    GLUtils.texImage2D(GLES20.GL_TEXTURE_2D,0,位图,0);

    //设置纹理参数
    GLToolbox.initTexParams();
}

私人无效initEffect(){
    EffectFactory effectFactory = mEffectContext.getFactory();
    如果(mEffect!= NULL){
        mEffect.release();
    }
    / **
     *初始化基于所选择的菜单/动作项正确的效果
     * /
    开关(mCurrentEffect){

    案例R.id.none:
        打破;

    案例R.id.autofix:
        mEffect = effectFactory.createEffect(EffectFactory.EFFECT_AUTOFIX);
        mEffect.setParameter(规模化,0.5F);
        打破;

    案例R.id.bw:
        mEffect = effectFactory
                .createEffect(EffectFactory.EFFECT_BLACKWHITE);
        mEffect.setParameter(黑,.1F);
        mEffect.setParameter(白,.7f);
        打破;

    案例R.id.brightness:
        mEffect = effectFactory
                .createEffect(EffectFactory.EFFECT_BRIGHTNESS);
        mEffect.setParameter(亮度,2.0f);
        打破;

    案例R.id.contrast:
        mEffect = effectFactory.createEffect(EffectFactory.EFFECT_CONTRAST);
        mEffect.setParameter(反差,1.4f);
        打破;

    案例R.id.crossprocess:
        mEffect = effectFactory
                .createEffect(EffectFactory.EFFECT_CROSSPROCESS);
        打破;

    案例R.id.documentary:
        mEffect = effectFactory
                .createEffect(EffectFactory.EFFECT_DOCUMENTARY);
        打破;

    案例R.id.duotone:
        mEffect = effectFactory.createEffect(EffectFactory.EFFECT_DUOTONE);
        mEffect.setParameter(first_color,Color.YELLOW);
        mEffect.setParameter(second_color,Color.DKGRAY);
        打破;

    案例R.id.filllight:
        mEffect = effectFactory
                .createEffect(EffectFactory.EFFECT_FILLLIGHT);
        mEffect.setParameter(实力,.8f);
        打破;

    案例R.id.fisheye:
        mEffect = effectFactory.createEffect(EffectFactory.EFFECT_FISHEYE);
        mEffect.setParameter(规模化,.5f);
        打破;

    案例R.id.flipvert:
        mEffect = effectFactory.createEffect(EffectFactory.EFFECT_FLIP);
        mEffect.setParameter(垂直,真正的);
        打破;

    案例R.id.fliphor:
        mEffect = effectFactory.createEffect(EffectFactory.EFFECT_FLIP);
        mEffect.setParameter(水平,真正的);
        打破;

    案例R.id.grain:
        mEffect = effectFactory.createEffect(EffectFactory.EFFECT_GRAIN);
        mEffect.setParameter(实力,1.0F);
        打破;

    案例R.id.grayscale:
        mEffect = effectFactory
                .createEffect(EffectFactory.EFFECT_GRAYSCALE);
        打破;

    案例R.id.lomoish:
        mEffect = effectFactory.createEffect(EffectFactory.EFFECT_LOMOISH);
        打破;

    案例R.id.negative:
        mEffect = effectFactory.createEffect(EffectFactory.EFFECT_NEGATIVE);
        打破;

    案例R.id.posterize:
        mEffect = effectFactory
                .createEffect(EffectFactory.EFFECT_POSTERIZE);
        打破;

    案例R.id.rotate:
        mEffect = effectFactory.createEffect(EffectFactory.EFFECT_ROTATE);
        mEffect.setParameter(角,180);
        打破;

    案例R.id.saturate:
        mEffect = effectFactory.createEffect(EffectFactory.EFFECT_SATURATE);
        mEffect.setParameter(规模化,.5f);
        打破;

    案例R.id.sepia:
        mEffect = effectFactory.createEffect(EffectFactory.EFFECT_SEPIA);
        打破;

    案例R.id.sharpen:
        mEffect = effectFactory.createEffect(EffectFactory.EFFECT_SHARPEN);
        打破;

    案例R.id.temperature:
        mEffect = effectFactory
                .createEffect(EffectFactory.EFFECT_TEMPERATURE);
        mEffect.setParameter(规模化,.9f);
        打破;

    案例R.id.tint:
        mEffect = effectFactory.createEffect(EffectFactory.EFFECT_TINT);
        mEffect.setParameter(色调,Color.MAGENTA);
        打破;

    案例R.id.vignette:
        mEffect = effectFactory.createEffect(EffectFactory.EFFECT_VIGNETTE);
        mEffect.setParameter(规模化,.5f);
        打破;

    默认:
        打破;

    }
}

私人无效applyEffect(){
    mEffect.apply(mTextures [0],mImageWidth,mImageHeight,mTextures [1]);
}

私人无效renderResult(){
    如果(mCurrentEffect!= R.id.none){
        //如果选择没有影响,只呈现的原始位图
        mTexRenderer.renderTexture(mTextures [1]);
    } 其他 {
        //渲染applyEffect的结果()
        mTexRenderer.renderTexture(mTextures [0]);
    }
}

@覆盖
公共无效onDrawFrame(GL10 GL){
    如果(!mInitialized){
        //只需要做一次
        mEffectContext = EffectContext.createWithCurrentGlContext();
        mTexRenderer.init();
        loadTextures();
        mInitialized = TRUE;
    }
    如果(mCurrentEffect!= R.id.none){
        //如果选择的效果初始化它,并将其应用到纹理
        initEffect();
        applyEffect();
    }
    renderResult();
}

@覆盖
公共无效onSurfaceChanged(GL10 GL,诠释的宽度,高度INT){
    如果(mTexRenderer!= NULL){
        mTexRenderer.updateViewSize(宽度,高度);
    }
}

@覆盖
公共无效onSurfaceCreated(GL10 GL,EGLConfig配置){
}

@覆盖
公共布尔onCreateOptionsMenu(功能菜单){
    MenuInflater充气= getMenuInflater();
    inflater.inflate(R.menu.main,菜单);
    返回true;
}

@覆盖
公共布尔onOptionsItemSelected(菜单项项){
    setCurrentEffect(item.getItemId());
    mEffectView.requestRender();
    返回true;
}

公共位图takeScreenshot(){

    mEffectView.getRootView();
    mEffectView.setDrawingCacheEnabled(真正的);
    mEffectView.buildDrawingCache();
    mEffectView.requestRender();
    返回mEffectView.getDrawingCache();
}

公共无效saveBitmap(位图位图){
    文件的ImagePath =新的文件(Environment.getExternalStorageDirectory()
            +/Piyush.png);
    FileOutputStream中FOS;
    尝试 {
        FOS =新的FileOutputStream(的ImagePath);
        bitmap.com preSS(比较pressFormat.JPEG,100,FOS);
        fos.flush();
        fos.close();
    }赶上(FileNotFoundException异常E){
        Log.e(GREC,e.getMessage(),E);
    }赶上(IOException异常E){
        Log.e(GREC,e.getMessage(),E);
    }
}
  }
 

GLToolbox.java

 公共类GLToolbox {

公共静态INT loadShader(INT shaderType,弦乐源){
    INT着色器= GLES20.glCreateShader(shaderType);
    如果(着色!= 0){
        GLES20.glShaderSource(着色器,源);
        GLES20.glCompileShader(着色);
        INT []编译=新INT [1];
        GLES20.glGetShaderiv(着色,GLES20.GL_COMPILE_STATUS,编译,0);
        如果(编译[0] == 0){
            字符串信息= GLES20.glGetShaderInfoLog(着色);
            GLES20.glDeleteShader(着色);
            着色器= 0;
            抛出新的RuntimeException(无法编译着色器
                    + shaderType +:+信息);
        }
    }
    返回着色器;
}

公共静态INT createProgram(字符串vertexSource,字符串fragmentSource){
    INT vertexShader = loadShader(GLES20.GL_VERTEX_SHADER,vertexSource);
    如果(vertexShader == 0){
        返回0;
    }
    INT pixelShader = loadShader(GLES20.GL_FRAGMENT_SHADER,fragmentSource);
    如果(pixelShader == 0){
        返回0;
    }

    INT程序= GLES20.glCreateProgram();
    如果(方案!= 0){
        GLES20.glAttachShader(程序,vertexShader);
        checkGlError(glAttachShader);
        GLES20.glAttachShader(程序,pixelShader);
        checkGlError(glAttachShader);
        GLES20.glLinkProgram(节目);
        INT [] linkStatus =新INT [1];
        GLES20.glGetProgramiv(程序,GLES20.GL_LINK_STATUS,linkStatus,0);
        如果(linkStatus [0]!= GLES20.GL_TRUE){
            字符串信息= GLES20.glGetProgramInfoLog(程序);
            GLES20.glDeleteProgram(节目);
            计划= 0;
            抛出新的RuntimeException(无法链接程序:+信息);
        }
    }
    返回程序;
}

公共静态无效checkGlError(字符串运算){
    INT错误;
    而((误差= GLES20.glGetError())!= GLES20.GL_NO_ERROR){
        抛出新的RuntimeException(OP +:glError+误差);
    }
}

公共静态无效initTexParams(){
    GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D,
            GLES20.GL_TEXTURE_MAG_FILTER,GLES20.GL_LINEAR);
    GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D,
            GLES20.GL_TEXTURE_MIN_FILTER,GLES20.GL_LINEAR);
    GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D,GLES20.GL_TEXTURE_WRAP_S,
            GLES20.GL_CLAMP_TO_EDGE);
    GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D,GLES20.GL_TEXTURE_WRAP_T,
            GLES20.GL_CLAMP_TO_EDGE);
}

   }
 

TextureRenderer.java

 公共类TextureRenderer {

私人诠释mProgram;
私人诠释mTexSamplerHandle;
私人诠释mTexCoordHandle;
私人诠释mPosCoordHandle;

私人FloatBuffer mTexVertices;
私人FloatBuffer mPosVertices;

私人诠释mViewWidth;
私人诠释mViewHeight;

私人诠释mTexWidth;
私人诠释mTexHeight;

私有静态最后弦乐VERTEX_SHADER =属性vec4 a_position; \ N
        +属性VEC 2 a_texcoord; \ N+不同的VEC 2 v_texcoord; \ N
        +无效的主要(){\ N+GL_POSITION = a_position; \ N
        +v_texcoord = a_texcoord; \ N+} \ N的;

私有静态最后弦乐FRAGMENT_SHADER =precision mediump浮动; \ N
        +制服sampler2D tex_sampler; \ N+不同的VEC 2 v_texcoord; \ N
        +无效的主要(){\ N
        +gl_FragColor =的Texture2D(tex_sampler,v_texcoord); \ N+} \ N的;

私有静态最终浮动[] TEX_VERTICES = {0.0,1.0F,1.0F,1.0F,0.0,
        0.0,1.0F,0.0};

私有静态最终浮动[] POS_VERTICES = {-1.0F,-1.0F,1.0F,-1.0F,
        -1.0F,1.0F,1.0F,1.0F};

私有静态最终诠释FLOAT_SIZE_BYTES = 4;

公共无效的init(){
    //创建程序
    mProgram = GLToolbox.createProgram(VERTEX_SHADER,FRAGMENT_SHADER);

    //绑定属性和制服
    mTexSamplerHandle = GLES20
            .glGetUniformLocation(mProgramtex_sampler);
    mTexCoordHandle = GLES20.glGetAttribLocation(mPrograma_texcoord);
    mPosCoordHandle = GLES20.glGetAttribLocation(mPrograma_position);

    //设置坐标缓冲器
    mTexVertices =的ByteBuffer
            .allocateDirect(TEX_VERTICES.length * FLOAT_SIZE_BYTES)
            。.order(ByteOrder.nativeOrder())asFloatBuffer();
    mTexVertices.put(TEX_VERTICES).position(0);
    mPosVertices =的ByteBuffer
            .allocateDirect(POS_VERTICES.length * FLOAT_SIZE_BYTES)
            。.order(ByteOrder.nativeOrder())asFloatBuffer();
    mPosVertices.put(POS_VERTICES).position(0);
}

公共无效的teardown(){
    GLES20.glDeleteProgram(mProgram);
}

公共无效updateTextureSize(INT texWidth,诠释texHeight){
    mTexWidth = texWidth;
    mTexHeight = texHeight;
    computeOutputVertices();
}

公共无效updateViewSize(INT viewWidth,诠释viewHeight){
    mViewWidth = viewWidth;
    mViewHeight = viewHeight;
    computeOutputVertices();
}

公共无效渲染纹理(INT texId){
    //默认绑定FBO
    GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER,0);

    //使用我们的着色器程序
    GLES20.glUseProgram(mProgram);
    GLToolbox.checkGlError(glUseProgram);

    //设置视
    GLES20.glViewport(0,0,mViewWidth,mViewHeight);
    GLToolbox.checkGlError(glViewport);

    //禁止混合
    GLES20.glDisable(GLES20.GL_BLEND);

    //设置顶点属性
    GLES20.glVertexAttribPointer(mTexCoordHandle,2,GLES20.GL_FLOAT,
            假,0,mTexVertices);
    GLES20.glEnableVertexAttribArray(mTexCoordHandle);
    GLES20.glVertexAttribPointer(mPosCoordHandle,2,GLES20.GL_FLOAT,
            假,0,mPosVertices);
    GLES20.glEnableVertexAttribArray(mPosCoordHandle);
    GLToolbox.checkGlError(顶点属性设置);

    //设置输入纹理
    GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
    GLToolbox.checkGlError(glActiveTexture);
    GLES20.glBindTexture(GLES20.GL_TEXTURE_2D,texId);
    GLToolbox.checkGlError(glBindTexture);
    GLES20.glUniform1i(mTexSamplerHandle,0);

    // 绘制
    GLES20.glClearColor(0.0,0.0,0.0,1.0F);
    GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);
    GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP,0,4);
}

私人无效computeOutputVertices(){
    如果(mPosVertices!= NULL){
        浮imgAspectRatio = mTexWidth /(浮点)mTexHeight;
        浮viewAspectRatio = mViewWidth /(浮点)mViewHeight;
        浮relativeAspectRatio = viewAspectRatio / imgAspectRatio;
        浮X0,Y0,X1,Y1;
        如果(relativeAspectRatio> 1.0F){
            X0 = -1.0F / relativeAspectRatio;
            Y0 = -1.0F;
            X1 = 1.0F / relativeAspectRatio;
            Y1 = 1.0F;
        } 其他 {
            X0 = -1.0F;
            Y0 = -relativeAspectRatio;
            X1 = 1.0F;
            Y1 = relativeAspectRatio;
        }
        浮[]的coords =新的浮动[] {X0,Y0,X1,Y0,X0,Y1,X1,Y1};
        mPosVertices.put(COORDS).position(0);
    }
}
  }
 

我的XML文件:

 < XML版本=1.0编码=UTF-8&GT?;
< LinearLayout中的xmlns:机器人=htt​​p://schemas.android.com/apk/res/android
的xmlns:工具=htt​​p://schemas.android.com/tool​​s
机器人:layout_width =FILL_PARENT
机器人:layout_height =FILL_PARENT
机器人:方向=垂直
工具:忽略=硬codedText>

 <按钮
    机器人:ID =@ + ID /按钮1
    机器人:layout_width =WRAP_CONTENT
    机器人:layout_height =0dp
    机器人:layout_weight =0.1
    机器人:文本=按钮/>

 < android.opengl.GLSurfaceView
    机器人:ID =@ + ID / effectsview
    机器人:layout_width =FILL_PARENT
    机器人:layout_height =0dp
    机器人:layout_weight =0.9/>

< / LinearLayout中>
 

解决方案

试试这个...

 私人挥发性布尔saveFrame;

//所谓的点击捕捉按钮时。
公共无效的onClick(视图查看){
    saveFrame = TRUE;
    mEffectView.requestRender();
}

@覆盖
公共无效onDrawFrame(GL10 GL){
    如果(!mInitialized){
        //只需要做一次
        mEffectContext = EffectContext.createWithCurrentGlContext();
        mTexRenderer.init();
        loadTextures();
        mInitialized = TRUE;
    }
    如果(mCurrentEffect!= NONE){
        //如果选择的效果初始化它,并将其应用到纹理
        initEffect();
        applyEffect();
    }
    renderResult();
    如果(saveFrame){
        saveBitmap(takeScreenshot(GL));
        saveFrame = FALSE;
    }
}

私人无效saveBitmap(位图位图){
    尝试 {
        的FileOutputStream流= openFileOutput(image.png,MODE_PRIVATE);
        bitmap.com preSS(比较pressFormat.PNG,100,流);
        stream.flush();
        stream.close();
        Log.i(TAG,拯救);
    }赶上(例外五){
        Log.e(TAG,e.toString(),E);
    }
}

公共位图takeScreenshot(GL10 MGL){
    最终诠释mWidth = mEffectView.getWidth();
    最终诠释mHeight = mEffectView.getHeight();
    IntBuffer IB = IntBuffer.allocate(mWidth * mHeight);
    IntBuffer IBT = IntBuffer.allocate(mWidth * mHeight);
    mGL.glReadPixels(0,0,mWidth,mHeight,GL10.GL_RGBA,GL10.GL_UNSIGNED_BYTE,IB);

    //转换倒挂镜像反转图像右侧朝上正常图像。
    的for(int i = 0; I< mHeight;我++){
        对于(INT J = 0; J< mWidth; J ++){
            ibt.put((mHeight  - 我 -  1)* mWidth + J,ib.get(I * mWidth + J));
        }
    }

    位图mBitmap = Bitmap.createBitmap(mWidth,mHeight,Bitmap.Config.ARGB_8888);
    mBitmap.copyPixelsFromBuffer(IBT);
    返回mBitmap;
}
 

I am wandering for seven hours for solving my issue. I have created project in which i m using GLSurfaceView on which i have set one image and after that i have implement different effects on it using EffectFactory class.

But my Problem is when i have taken a screen shot with effected image it always shows as a black screen instead of with image. I know that may be its because of SurFaceview. But If any suggestion which might be helpful for me.

Thanks in Advance.

Here is my code.

public class EffectsFilterActivity 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);
    requestWindowFeature(Window.FEATURE_NO_TITLE);
    setContentView(R.layout.main);

    Button b = (Button) findViewById(R.id.button1);
    b.setOnClickListener(new OnClickListener() {

        @Override
        public void onClick(View v) {
            // TODO Auto-generated method stub
            Bitmap b = takeScreenshot();
            saveBitmap(b);

        }
    });

    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.main, menu);
    return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    setCurrentEffect(item.getItemId());
    mEffectView.requestRender();
    return true;
}

public Bitmap takeScreenshot() {

    mEffectView.getRootView();
    mEffectView.setDrawingCacheEnabled(true);
    mEffectView.buildDrawingCache();
    mEffectView.requestRender();
    return mEffectView.getDrawingCache();
}

public void saveBitmap(Bitmap bitmap) {
    File imagePath = new File(Environment.getExternalStorageDirectory()
            + "/Piyush.png");
    FileOutputStream fos;
    try {
        fos = new FileOutputStream(imagePath);
        bitmap.compress(CompressFormat.JPEG, 100, fos);
        fos.flush();
        fos.close();
    } catch (FileNotFoundException e) {
        Log.e("GREC", e.getMessage(), e);
    } catch (IOException e) {
        Log.e("GREC", e.getMessage(), e);
    }
}
  }

GLToolbox.java

 public class GLToolbox {

public static int loadShader(int shaderType, String source) {
    int shader = GLES20.glCreateShader(shaderType);
    if (shader != 0) {
        GLES20.glShaderSource(shader, source);
        GLES20.glCompileShader(shader);
        int[] compiled = new int[1];
        GLES20.glGetShaderiv(shader, GLES20.GL_COMPILE_STATUS, compiled, 0);
        if (compiled[0] == 0) {
            String info = GLES20.glGetShaderInfoLog(shader);
            GLES20.glDeleteShader(shader);
            shader = 0;
            throw new RuntimeException("Could not compile shader "
                    + shaderType + ":" + info);
        }
    }
    return shader;
}

public static int createProgram(String vertexSource, String fragmentSource) {
    int vertexShader = loadShader(GLES20.GL_VERTEX_SHADER, vertexSource);
    if (vertexShader == 0) {
        return 0;
    }
    int pixelShader = loadShader(GLES20.GL_FRAGMENT_SHADER, fragmentSource);
    if (pixelShader == 0) {
        return 0;
    }

    int program = GLES20.glCreateProgram();
    if (program != 0) {
        GLES20.glAttachShader(program, vertexShader);
        checkGlError("glAttachShader");
        GLES20.glAttachShader(program, pixelShader);
        checkGlError("glAttachShader");
        GLES20.glLinkProgram(program);
        int[] linkStatus = new int[1];
        GLES20.glGetProgramiv(program, GLES20.GL_LINK_STATUS, linkStatus, 0);
        if (linkStatus[0] != GLES20.GL_TRUE) {
            String info = GLES20.glGetProgramInfoLog(program);
            GLES20.glDeleteProgram(program);
            program = 0;
            throw new RuntimeException("Could not link program: " + info);
        }
    }
    return program;
}

public static void checkGlError(String op) {
    int error;
    while ((error = GLES20.glGetError()) != GLES20.GL_NO_ERROR) {
        throw new RuntimeException(op + ": glError " + error);
    }
}

public static void initTexParams() {
    GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D,
            GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR);
    GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D,
            GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_LINEAR);
    GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S,
            GLES20.GL_CLAMP_TO_EDGE);
    GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T,
            GLES20.GL_CLAMP_TO_EDGE);
}

   }

TextureRenderer.java

public class TextureRenderer {

private int mProgram;
private int mTexSamplerHandle;
private int mTexCoordHandle;
private int mPosCoordHandle;

private FloatBuffer mTexVertices;
private FloatBuffer mPosVertices;

private int mViewWidth;
private int mViewHeight;

private int mTexWidth;
private int mTexHeight;

private static final String VERTEX_SHADER = "attribute vec4 a_position;\n"
        + "attribute vec2 a_texcoord;\n" + "varying vec2 v_texcoord;\n"
        + "void main() {\n" + "  gl_Position = a_position;\n"
        + "  v_texcoord = a_texcoord;\n" + "}\n";

private static final String FRAGMENT_SHADER = "precision mediump float;\n"
        + "uniform sampler2D tex_sampler;\n" + "varying vec2 v_texcoord;\n"
        + "void main() {\n"
        + "  gl_FragColor = texture2D(tex_sampler, v_texcoord);\n" + "}\n";

private static final float[] TEX_VERTICES = { 0.0f, 1.0f, 1.0f, 1.0f, 0.0f,
        0.0f, 1.0f, 0.0f };

private static final float[] POS_VERTICES = { -1.0f, -1.0f, 1.0f, -1.0f,
        -1.0f, 1.0f, 1.0f, 1.0f };

private static final int FLOAT_SIZE_BYTES = 4;

public void init() {
    // Create program
    mProgram = GLToolbox.createProgram(VERTEX_SHADER, FRAGMENT_SHADER);

    // Bind attributes and uniforms
    mTexSamplerHandle = GLES20
            .glGetUniformLocation(mProgram, "tex_sampler");
    mTexCoordHandle = GLES20.glGetAttribLocation(mProgram, "a_texcoord");
    mPosCoordHandle = GLES20.glGetAttribLocation(mProgram, "a_position");

    // Setup coordinate buffers
    mTexVertices = ByteBuffer
            .allocateDirect(TEX_VERTICES.length * FLOAT_SIZE_BYTES)
            .order(ByteOrder.nativeOrder()).asFloatBuffer();
    mTexVertices.put(TEX_VERTICES).position(0);
    mPosVertices = ByteBuffer
            .allocateDirect(POS_VERTICES.length * FLOAT_SIZE_BYTES)
            .order(ByteOrder.nativeOrder()).asFloatBuffer();
    mPosVertices.put(POS_VERTICES).position(0);
}

public void tearDown() {
    GLES20.glDeleteProgram(mProgram);
}

public void updateTextureSize(int texWidth, int texHeight) {
    mTexWidth = texWidth;
    mTexHeight = texHeight;
    computeOutputVertices();
}

public void updateViewSize(int viewWidth, int viewHeight) {
    mViewWidth = viewWidth;
    mViewHeight = viewHeight;
    computeOutputVertices();
}

public void renderTexture(int texId) {
    // Bind default FBO
    GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, 0);

    // Use our shader program
    GLES20.glUseProgram(mProgram);
    GLToolbox.checkGlError("glUseProgram");

    // Set viewport
    GLES20.glViewport(0, 0, mViewWidth, mViewHeight);
    GLToolbox.checkGlError("glViewport");

    // Disable blending
    GLES20.glDisable(GLES20.GL_BLEND);

    // Set the vertex attributes
    GLES20.glVertexAttribPointer(mTexCoordHandle, 2, GLES20.GL_FLOAT,
            false, 0, mTexVertices);
    GLES20.glEnableVertexAttribArray(mTexCoordHandle);
    GLES20.glVertexAttribPointer(mPosCoordHandle, 2, GLES20.GL_FLOAT,
            false, 0, mPosVertices);
    GLES20.glEnableVertexAttribArray(mPosCoordHandle);
    GLToolbox.checkGlError("vertex attribute setup");

    // Set the input texture
    GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
    GLToolbox.checkGlError("glActiveTexture");
    GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, texId);
    GLToolbox.checkGlError("glBindTexture");
    GLES20.glUniform1i(mTexSamplerHandle, 0);

    // Draw
    GLES20.glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
    GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);
    GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4);
}

private void computeOutputVertices() {
    if (mPosVertices != null) {
        float imgAspectRatio = mTexWidth / (float) mTexHeight;
        float viewAspectRatio = mViewWidth / (float) mViewHeight;
        float relativeAspectRatio = viewAspectRatio / imgAspectRatio;
        float x0, y0, x1, y1;
        if (relativeAspectRatio > 1.0f) {
            x0 = -1.0f / relativeAspectRatio;
            y0 = -1.0f;
            x1 = 1.0f / relativeAspectRatio;
            y1 = 1.0f;
        } else {
            x0 = -1.0f;
            y0 = -relativeAspectRatio;
            x1 = 1.0f;
            y1 = relativeAspectRatio;
        }
        float[] coords = new float[] { x0, y0, x1, y0, x0, y1, x1, y1 };
        mPosVertices.put(coords).position(0);
    }
}
  }

My Xml file:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical"
tools:ignore="HardcodedText" >

 <Button
    android:id="@+id/button1"
    android:layout_width="wrap_content"
    android:layout_height="0dp"
    android:layout_weight="0.1"
    android:text="Button" />

 <android.opengl.GLSurfaceView
    android:id="@+id/effectsview"
    android:layout_width="fill_parent"
    android:layout_height="0dp"
    android:layout_weight="0.9" />

</LinearLayout>
解决方案

try this...

private volatile boolean saveFrame;

// called when Capture button is clicked.
public void onClick(View view) {
    saveFrame = true;
    mEffectView.requestRender();
}

@Override
public void onDrawFrame(GL10 gl) {
    if (!mInitialized) {
        // Only need to do this once
        mEffectContext = EffectContext.createWithCurrentGlContext();
        mTexRenderer.init();
        loadTextures();
        mInitialized = true;
    }
    if (mCurrentEffect != NONE) {
        // if an effect is chosen initialize it and apply it to the texture
        initEffect();
        applyEffect();
    }
    renderResult();
    if (saveFrame) {
        saveBitmap(takeScreenshot(gl));
        saveFrame = false;
    }
}

private void saveBitmap(Bitmap bitmap) {
    try {
        FileOutputStream stream = openFileOutput("image.png", MODE_PRIVATE);
        bitmap.compress(CompressFormat.PNG, 100, stream);
        stream.flush();
        stream.close();
        Log.i("TAG", "SAVED");
    } catch (Exception e) {
        Log.e("TAG", e.toString(), e);
    }
}

public Bitmap takeScreenshot(GL10 mGL) {
    final int mWidth = mEffectView.getWidth();
    final int mHeight = mEffectView.getHeight();
    IntBuffer ib = IntBuffer.allocate(mWidth * mHeight);
    IntBuffer ibt = IntBuffer.allocate(mWidth * mHeight);
    mGL.glReadPixels(0, 0, mWidth, mHeight, GL10.GL_RGBA, GL10.GL_UNSIGNED_BYTE, ib);

    // Convert upside down mirror-reversed image to right-side up normal image.
    for (int i = 0; i < mHeight; i++) {
        for (int j = 0; j < mWidth; j++) {
            ibt.put((mHeight - i - 1) * mWidth + j, ib.get(i * mWidth + j));
        }
    }

    Bitmap mBitmap = Bitmap.createBitmap(mWidth, mHeight,Bitmap.Config.ARGB_8888);
    mBitmap.copyPixelsFromBuffer(ibt);
    return mBitmap;
}

这篇关于显示黑屏,同时GLSurfaceView捕获屏幕截图的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-16 05:37