Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

how to capture full bitmap from after applied effect not draw to GLSurfaceView. #101

Open
monxarat opened this issue Nov 19, 2018 · 6 comments

Comments

@monxarat
Copy link

monxarat commented Nov 19, 2018

How to capture full bitmap after applied effect not draw on GLSurfaceView.

My code

public void getBitmapWithFilter(final Bitmap bitmap, final File outFile, final OnBitmapReceiveListener onBitmapReceiveListener){
        if (!mIsSaving) {
            mIsSaving = true;
            mGLSurfaceView.queueEvent(new Runnable() {
                @Override
                public void run() {
                    int width = 1024;//bitmap.getWidth();
                    int height = 910;//bitmap.getHeight();

                    if(mFilter != null) {
                        mFilter.onInputSizeChanged(width, height);
                        mFilter.onDisplaySizeChanged(width, height);
                    }

                    // init buffer for texture
                    int[] mFrameBuffers = new int[1];
                    int[] mFrameBufferTextures = new int[1];

                    // load texture
                    OpenGlUtils.loadTextureBufferFiltering(mFrameBuffers, mFrameBufferTextures, width, height);
                    GLES20.glViewport(0, 0, width, height);
                    int textureId = OpenGlUtils.loadTexture(bitmap, OpenGlUtils.NO_TEXTURE, true);

                    // draw frame to texture
                    if(mFilter != null){
                        mFilter.onDrawFrame(mFrameBufferTextures[0], gLCubeBuffer, gLTextureBuffer);
                    } else {
                        imageInput.onDrawFrame(textureId, gLCubeBuffer, gLTextureBuffer);
                    }

                    // copy pixel buffer from the current texture
                    Bitmap result = BitmapProcessor.createBitmap(width, height);

                    // delete texture
                    OpenGlUtils.deleteTextureBufferFiltering(textureId, mFrameBuffers, mFrameBufferTextures);

                    // rest getBitmapWithFilter display
                    if(mFilter != null) {
                        mFilter.onDisplaySizeChanged(mSurfaceWidth, mSurfaceHeight);
                        mFilter.onInputSizeChanged(mImageWidth, mImageHeight);
                    }

                    if (outFile != null) {
                        // save bitmap to disk
                        BitmapProcessor.saveBitmapToImage(result, outFile);
                    }

                    mIsSaving = false;
                    // reset viewport of the current texture.
                    GLES20.glViewport(0, 0, mSurfaceWidth, mSurfaceHeight);

                    // notice to activity
                    if (onBitmapReceiveListener != null) {
                        onBitmapReceiveListener.onBitmapReceive(result);
                    }
                }
            });
        }
    }
public static void loadTextureBufferFiltering(int[] mFrameBuffers, int[] mFrameBufferTextures, int width, int height) {
        GLES20.glGenFramebuffers(1, mFrameBuffers, 0);
        GLES20.glGenTextures(1, mFrameBufferTextures, 0);
        GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mFrameBufferTextures[0]);
        GLES20.glTexImage2D(GLES20.GL_TEXTURE_2D, 0, GLES20.GL_RGBA, width, height, 0, GLES20.GL_RGBA, GLES20.GL_UNSIGNED_BYTE, null);
        GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR);
        GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_LINEAR);
        GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_CLAMP_TO_EDGE);
        GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_CLAMP_TO_EDGE);
        GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, mFrameBuffers[0]);
        //Bind the texture to your FBO
        GLES20.glFramebufferTexture2D(GLES20.GL_FRAMEBUFFER, GLES20.GL_COLOR_ATTACHMENT0, GLES20.GL_TEXTURE_2D, mFrameBufferTextures[0], 0);
    }
```

public static Bitmap createBitmap(int width, int height) {
IntBuffer ib = IntBuffer.allocate(width * height);
GLES20.glReadPixels(0, 0, width, height, GLES20.GL_RGBA, GLES20.GL_UNSIGNED_BYTE, ib);
Bitmap result = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
result.copyPixelsFromBuffer(ib);

    return result;
}
@monxarat monxarat changed the title how to capture bitmap from GLSurfaceView how to capture full bitmap from after applied effect not draw to GLSurfaceView. Nov 19, 2018
@AimplainLeo
Copy link

And where this function is placed in project?

@monxarat
Copy link
Author

monxarat commented Dec 4, 2018

this function I put in the class Renderer.

@AimplainLeo
Copy link

Sorry, but i dont know where getBitmapWithFilter and createBitmap should be use! Could you show me that? Thank you very much!

@monxarat
Copy link
Author

monxarat commented Dec 5, 2018

Thank you for a reply.
Below code, I have implemented.

public abstract class EffectBaseViewRenderer implements GLSurfaceView.Renderer{

public void getBitmapWithFilter(final Bitmap bitmap, final File outFile, final OnBitmapReceiveListener onBitmapReceiveListener) {
        ......
    }

}


public abstract class EffectBase extends GLSurfaceBaseView {

   private EffectViewRenderer mEffectViewRenderer;
    ....
   public void getBitmapWithFilter(final Bitmap bitmap, final File outFile, final OnBitmapReceiveListener onBitmapReceiveListener) {
        mEffectViewRenderer.getBitmapWithFilter(bitmap, outFile, receiveListener);
        ....
    }
}

public class PlayerView extends EffectBase {

   .....
}

public class ExportImage extends AsyncTask<Void, Integer, Boolean> implements EffectBaseViewRenderer.OnBitmapReceiveListener {

private EffectBase mEffectBase;
...
@Override
    protected Boolean doInBackground(Void... voids) {
        while (index < count) {
            if (!isRunning) {
                isRunning = true;
                Bitmap bitmap = effectBase.getBitmap(index);
                final File outFile = new File(mFolderContaining, String.format(Locale.ENGLISH, Config.IN_FRAME_FORMAT, index));
                mEffectBase.getBitmapWithFilter(bitmap, outFile, this);
            }
        }
        return null;
    }
    ...
}

public class EditorViewBaseActivity extends BaseActivity {

private PlayerView mPlayerView;
 @Override
    public void onClick(final View v) {
    if (v == btnExport) {
          ExportImage exportImage = new ExportImage(EditorViewBaseActivity.this, mPlayerView);
          exportImage.setCount(mImageFolder.getCount());
          exportImage.execute();
          }
    }
               
}

@xuzhiyong017
Copy link

// draw frame to texture
if(mFilter != null){
mFilter.onDrawFrame(mFrameBufferTextures[0], gLCubeBuffer, gLTextureBuffer);
} else {
imageInput.onDrawFrame(textureId, gLCubeBuffer, gLTextureBuffer);
}
Can two filters be superimposed?
for example
__
if(filter == null){
beautyFilter.onDrawFrame(textureId, gLCubeBuffer, gLTextureBuffer);
}else{
beautyFilter.onDrawFrame(textureId);
filter.onDrawFrame(mFrameBufferTextures[0], gLCubeBuffer, gLTextureBuffer);
}

@AimplainLeo
Copy link

Thank you so much! brs, Nam.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants