【问题标题】:how to get only bitmap image from opengl surfaceview not background in android?如何仅从opengl surfaceview获取位图图像而不是android中的背景?
【发布时间】:2014-08-12 09:08:32
【问题描述】:

请任何人帮助我从表面视图获取位图这是我的 GlSurface View Render 类,我正在获取位图图像,但它有黑色背景,所以我只想要图像并删除背景黑色。

public class GLLayer implements GLSurfaceView.Renderer{
/**
 * This class implements our custom renderer. Note that the GL10 parameter
 * passed in is unused for OpenGL ES 2.0 renderers -- the static class
 * GLES20 is used instead.
 */
public Context mActivityContext;

/**
 * Store the model matrix. This matrix is used to move models from object
 * space (where each model can be thought of being located at the center of
 * the universe) to world space.
 */
private float[] mModelMatrix = new float[16];

/**
 * Store the view matrix. This can be thought of as our camera. This matrix
 * transforms world space to eye space; it positions things relative to our
 * eye.
 */
private float[] mViewMatrix = new float[16];

/**
 * Store the projection matrix. This is used to project the scene onto a 2D
 * viewport.
 */
private float[] mProject![enter image description here][1]ionMatrix = new float[16];

/**
 * Allocate storage for the final combined matrix. This will be passed into
 * the shader program.
 */
private float[] mMVPMatrix = new float[16];

/** Store our model data in a float buffer. */
private final FloatBuffer mCubePositions;
private final FloatBuffer mCubeColors;
private final FloatBuffer mCubeTextureCoordinates;

/** This will be used to pass in the transformation matrix. */
private int mMVPMatrixHandle;

/** This will be used to pass in the texture. */
private int mTextureUniformHandle0;
private int mTextureUniformHandle1;
private int mTextureUniformHandle2;
private int mTextureUniformHandle3;
private int mTextureUniformHandle4;

/** This will be used to pass in model position information. */
private int mPositionHandle;

/** This will be used to pass in model color information. */
// private int mColorHandle;

/** This will be used to pass in model texture coordinate information. */
private int mTextureCoordinateHandle;

/** How many bytes per float. */
private final int mBytesPerFloat = 4;

/** Size of the position data in elements. */
private final int mPositionDataSize = 3;

/** Size of the color data in elements. */
// private final int mColorDataSize = 4;

/** Size of the texture coordinate data in elements. */
private final int mTextureCoordinateDataSize = 2;

/** This is a handle to our cube shading program. */
private int mProgramHandle;

/** This is a handle to our texture data. */
private int mTextureDataHandle0;
private int mTextureDataHandle1;
private int mTextureDataHandle2;
private int mTextureDataHandle3;
private int mTextureDataHandle4;

/**
 * Shader Titles
 */
static public int shader_selection = 0;
static public final int AMARO = 1;
static public final int EARLYBIRD = 2;
static public final int HEFE = 3;
static public final int HUDSON = 4;
static public final int MAYFAIR = 5;
static public final int RISE = 6;
static public final int TOASTER = 7;
static public final int VALENCIA = 8;
static public final int WILLOW = 9;
static public final int XPRO = 10;

private Bitmap mBitmap;
public static int width_surface ;

public static int height_surface;

public int width_bitmap =0;
public int height_bitmap=0;

public static boolean printOptionEnable = false;
// and more ...

/**
 * Initialize the model data.
 */
public GLLayer(final Context activityContext, Bitmap mBitmap) {
    mActivityContext = activityContext;
    this.mBitmap = mBitmap;
    this.width_bitmap = mBitmap.getWidth();
    this.height_bitmap = mBitmap.getHeight();
    // Define points for a cube.

    final float[] cubePositionData = {

            // Front face
            -1.0f, 1.0f, 1.0f, -1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, -1.0f,
            -1.0f, 1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f };

    // R, G, B, A
    final float[] cubeColorData = {
            // Front face (red)
            1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f,
            0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f,
            1.0f, 0.0f, 0.0f, 1.0f };

    final float[] cubeTextureCoordinateData = {
            // Front face
            0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f,
            1.0f, 0.0f };

    // Initialize the buffers.
    mCubePositions = ByteBuffer.allocateDirect(cubePositionData.length * mBytesPerFloat)
            .order(ByteOrder.nativeOrder()).asFloatBuffer();
    mCubePositions.put(cubePositionData).position(0);

    mCubeColors = ByteBuffer.allocateDirect(cubeColorData.length * mBytesPerFloat)
            .order(ByteOrder.nativeOrder()).asFloatBuffer();
    mCubeColors.put(cubeColorData).position(0);

    mCubeTextureCoordinates = ByteBuffer.allocateDirect(cubeTextureCoordinateData.length * mBytesPerFloat)
            .order(ByteOrder.nativeOrder()).asFloatBuffer();
    mCubeTextureCoordinates.put(cubeTextureCoordinateData).position(0);
}

protected String getVertexShader() {
    return RawResourceReader.readTextFileFromRawResource(mActivityContext,R.raw._vertex_shader);
}

protected String getFragmentShader() {
    int id;
    switch (shader_selection) {
    case AMARO:
        id = R.raw.amaro_filter_shader;
        break;
    case EARLYBIRD:
        id = R.raw.earlybird_filter_shader;
        break;
    case HEFE:
        id = R.raw.hefe_filter_shader;
        break;
    case HUDSON:
        id = R.raw.hudson_filter_shader;
        break;
    case MAYFAIR:
        id = R.raw.mayfair_filter_shader;
        break;
    case RISE:
        id = R.raw.rise_filter_shader;
        break;
    case TOASTER:
        id = R.raw.toaster_filter_shader;
        break;
    case WILLOW:
        id = R.raw.willow_filter_shader;
        break;
    case XPRO:
        id = R.raw.xpro_filter_shader;
        break;

    default:
        id = R.raw._fragment_shader;
        break;
    }

    return RawResourceReader.readTextFileFromRawResource(mActivityContext,id);

}

@Override
public void onSurfaceCreated(GL10 glUnused, EGLConfig config) {
    // Set the background clear color to black.
    GLES20.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
    // Use culling to remove back faces.
    GLES20.glEnable(GLES20.GL_CULL_FACE);

    // Enable depth testing
    GLES20.glEnable(GLES20.GL_DEPTH_TEST);

    final float eyeX = 0.0f;
    final float eyeY = 0.0f;
    final float eyeZ = -0.5f;

    // We are looking toward the distance
    final float lookX = 0.0f;
    final float lookY = 0.0f;
    final float lookZ = -5.0f;

    // Set our up vector. This is where our head would be pointing were we
    // holding the camera.
    final float upX = 0.0f;
    final float upY = 1.0f;
    final float upZ = 0.0f;

    Matrix.setLookAtM(mViewMatrix, 0, eyeX, eyeY, eyeZ, lookX, lookY,lookZ, upX, upY, upZ);

    // // Load the texture
    mTextureDataHandle0 = TextureHelper.loadTexture(mBitmap);

    // Load the texture
    mTextureDataHandle1 = TextureHelper.loadTexture(mActivityContext,R.drawable.filter2);

    // Load the texture
    mTextureDataHandle2 = TextureHelper.loadTexture(mActivityContext,R.drawable.hefe);

    // Load the texture
    mTextureDataHandle3 = TextureHelper.loadTexture(mActivityContext,R.drawable.hudson);

    // Load the texture
    mTextureDataHandle4 = TextureHelper.loadTexture(mActivityContext,R.drawable.toaster);

}

@Override
public void onSurfaceChanged(GL10 glUnused, int width, int height) {
    GLES20.glViewport(0, 0, width, height);

    final float ratio = (float) width / height;
    final float left = -ratio;
    final float right = ratio;
    final float bottom = -1.0f;
    final float top = 1.0f;
    final float near = 1.0f;
    final float far = 10.0f;

    width_surface =  width ;
    height_surface = height ;

            Matrix.frustumM(mProjectionMatrix, 0, left, right, bottom, top, near,far);
}

@Override
public void onDrawFrame(GL10 glUnused) {
    GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT | GLES20.GL_DEPTH_BUFFER_BIT);
    final String vertexShader = getVertexShader();
    final String fragmentShader = getFragmentShader();
    final int vertexShaderHandle = ShaderHelper.compileShader(GLES20.GL_VERTEX_SHADER, vertexShader);
    final int fragmentShaderHandle = ShaderHelper.compileShader(GLES20.GL_FRAGMENT_SHADER, fragmentShader);

    mProgramHandle = ShaderHelper.createAndLinkProgram(vertexShaderHandle,
            fragmentShaderHandle, new String[] { "a_Position","a_TexCoordinate" });

    // Set our per-vertex lighting program.
    GLES20.glUseProgram(mProgramHandle);

    // Set program handles for cube drawing.
    mMVPMatrixHandle = GLES20.glGetUniformLocation(mProgramHandle,"u_MVPMatrix");
    mTextureUniformHandle0 = GLES20.glGetUniformLocation(mProgramHandle,"u_Texture0");
    mTextureUniformHandle1 = GLES20.glGetUniformLocation(mProgramHandle,"u_Texture1");
    mTextureUniformHandle2 = GLES20.glGetUniformLocation(mProgramHandle,"u_Texture2");
    mTextureUniformHandle3 = GLES20.glGetUniformLocation(mProgramHandle,"u_Texture3");
    mTextureUniformHandle4 = GLES20.glGetUniformLocation(mProgramHandle,"u_Texture4");
    mPositionHandle = GLES20.glGetAttribLocation(mProgramHandle,"a_Position");
    mTextureCoordinateHandle = GLES20.glGetAttribLocation(mProgramHandle,"a_TexCoordinate");

    /**
     * First texture map
     */
    // Set the active texture0 unit to texture unit 0.
    GLES20.glActiveTexture(GLES20.GL_TEXTURE0);

    // Bind the texture to this unit.
    GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mTextureDataHandle0);

    // Tell the texture uniform sampler to use this texture in the shader by
    // binding to texture unit 0.
    GLES20.glUniform1i(mTextureUniformHandle0, 0);

    /**
     * Second texture map filter
     */
    // Set the active texture1 unit to texture unit 1.
    GLES20.glActiveTexture(GLES20.GL_TEXTURE1);

    // Bind the texture to this unit.
    GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mTextureDataHandle1);

    // Tell the texture uniform sampler to use this texture in the shader by
    // binding to texture unit 1.
    GLES20.glUniform1i(mTextureUniformHandle1, 1);

    /**
     * Third texture map filter hefe
     */
    // Set the active texture1 unit to texture unit 1.
    GLES20.glActiveTexture(GLES20.GL_TEXTURE2);

    // Bind the texture to this unit.
    GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mTextureDataHandle2);

    // Tell the texture uniform sampler to use this texture in the shader by
    // binding to texture unit 1.
    GLES20.glUniform1i(mTextureUniformHandle2, 2);

    /**
     * Fouth texture map filter hudson
     */
    // Set the active texture1 unit to texture unit 1.
    GLES20.glActiveTexture(GLES20.GL_TEXTURE3);

    // Bind the texture to this unit.
    GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mTextureDataHandle3);

    // Tell the texture uniform sampler to use this texture in the shader by
    // binding to texture unit 1.
    GLES20.glUniform1i(mTextureUniformHandle3, 3);

    /**
     * Fifth texture map filter toaster
     */
    // Set the active texture1 unit to texture unit 1.
    GLES20.glActiveTexture(GLES20.GL_TEXTURE4);

    // Bind the texture to this unit.
    GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mTextureDataHandle4);

    // Tell the texture uniform sampler to use this texture in the shader by
    // binding to texture unit 1.
    GLES20.glUniform1i(mTextureUniformHandle4, 4);

    // Draw some cubes.
    Matrix.setIdentityM(mModelMatrix, 0);
    Matrix.translateM(mModelMatrix, 0, 0.0f, 0.0f, -3.2f);
    Matrix.rotateM(mModelMatrix, 0, 0.0f, 1.0f, 1.0f, 0.0f);
    drawCube();

    createBitmap();
}

/**
 * Draws a cube.
 */
private void drawCube() {
    // Pass in the position information
    mCubePositions.position(0);
    GLES20.glVertexAttribPointer(mPositionHandle, mPositionDataSize,
            GLES20.GL_FLOAT, false, 0, mCubePositions);

    GLES20.glEnableVertexAttribArray(mPositionHandle);

    // Pass in the texture coordinate information
    mCubeTextureCoordinates.position(0);
    GLES20.glVertexAttribPointer(mTextureCoordinateHandle,
            mTextureCoordinateDataSize, GLES20.GL_FLOAT, false, 0,
            mCubeTextureCoordinates);

    GLES20.glEnableVertexAttribArray(mTextureCoordinateHandle);

    Matrix.multiplyMM(mMVPMatrix, 0, mViewMatrix, 0, mModelMatrix, 0);

    Matrix.multiplyMM(mMVPMatrix, 0, mProjectionMatrix, 0, mMVPMatrix, 0);

    // Pass in the combined matrix.
    GLES20.glUniformMatrix4fv(mMVPMatrixHandle, 1, false, mMVPMatrix, 0);

    // Draw the cube.
    GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, 6);
}

public void createBitmap(){
    try {

        if (printOptionEnable) {
            printOptionEnable = false ;
            int w = width_surface ;
            int h = height_surface  ;


            int b[]=new int[(int) (w*h)];
            int bt[]=new int[(int) (w*h)];
            IntBuffer buffer=IntBuffer.wrap(b);
            buffer.position(0);
            GLES20.glReadPixels(0,0,w,h,GLES20.GL_RGBA,GLES20.GL_UNSIGNED_BYTE, buffer);
            for(int i=0; i<h; i++){
                //remember, that OpenGL bitmap is incompatible with Android bitmap
                //and so, some correction need.        
                for(int j=0; j<w; j++){
                    int pix=b[i*w+j];
                    int pb=(pix>>16)&0xff;
                    int pr=(pix<<16)&0x00ff0000;
                    int pix1=(pix&0xff00ff00) | pr | pb;
                    bt[(h-i-1)*w+j]=pix1;
                }
            }           
            Bitmap inBitmap = null ;
            if (inBitmap == null || !inBitmap.isMutable()
                    || inBitmap.getWidth() != w || inBitmap.getHeight() != h) {
                inBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
            }
            //Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
            inBitmap.copyPixelsFromBuffer(buffer);
            //return inBitmap ;
            // return Bitmap.createBitmap(bt, w, h, Bitmap.Config.ARGB_8888);
            inBitmap = Bitmap.createBitmap(bt, w, h, Bitmap.Config.ARGB_8888);

            ByteArrayOutputStream bos = new ByteArrayOutputStream(); 
            inBitmap.compress(CompressFormat.JPEG, 90, bos); 
            byte[] bitmapdata = bos.toByteArray();
            ByteArrayInputStream fis = new ByteArrayInputStream(bitmapdata);

            final Calendar c=Calendar.getInstance();
            long mytimestamp=c.getTimeInMillis();
            String timeStamp=String.valueOf(mytimestamp);
            String myfile="vijay"+timeStamp+".jpeg";

            File dir_image=new File(Environment.getExternalStorageDirectory().toString());
            dir_image.mkdirs();

            try {
                File tmpFile = new File(dir_image,myfile); 
                FileOutputStream fos = new FileOutputStream(tmpFile);

                byte[] buf = new byte[1024];
                int len;
                while ((len = fis.read(buf)) > 0) {
                    fos.write(buf, 0, len);
                }
                fis.close();
                fos.close();
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }catch(Exception e) {
        e.printStackTrace() ;
    }
}

}

【问题讨论】:

  • 你找到解决办法了吗?

标签: opengl-es surfaceview


【解决方案1】:

让你的glSurfaceView 像这个example 一样半透明

来自同一示例的代码 sn-p

    // Create our Preview view and set it as the content of our
    // Activity
    mGLSurfaceView = new GLSurfaceView(this);
    // We want an 8888 pixel format because that's required for
    // a translucent window.
    // And we want a depth buffer.
    mGLSurfaceView.setEGLConfigChooser(8, 8, 8, 8, 16, 0);
    // Tell the cube renderer that we want to render a translucent version
    // of the cube:
    mGLSurfaceView.setRenderer(new CubeRenderer(true));
    // Use a surface format with an Alpha channel:
    mGLSurfaceView.getHolder().setFormat(PixelFormat.TRANSLUCENT);

然后将图像保存为.png 而不是.jpeg 以保持透明度。

【讨论】:

    猜你喜欢
    • 2011-10-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-04
    • 1970-01-01
    • 1970-01-01
    • 2013-08-11
    相关资源
    最近更新 更多