wuhaoyu1990 / MagicCamera

Real-time Filter Camera&VideoRecorder And ImageEditor With Face Beauty For Android---包含美颜等40余种实时滤镜相机,可拍照、录像、图片修改

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

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

monxarat opened this issue · comments

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;
}

And where this function is placed in project?

this function I put in the class Renderer.

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

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();
          }
    }
               
}

// 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);
}

Thank you so much! brs, Nam.