因此,我正在实施一个屏幕,将效果(颗粒,负片等)应用于用户从相机拍摄的图像或从图库中拍摄的图像。我能够拍摄他们选择或拍摄的图像,并通过全分辨率使用OpenGL将其显示给他们(或按比例缩小,保持宽高比取决于他们的设备的最大纹理尺寸和图像的大小)。此外,选择效果并应用于纹理完全正常。就像拍摄图像并制作一堆小预览缩略图一样,特殊效果应用于60x60尺寸。我这样做的方法是使用FrameBuffer渲染图像并使用glReadPixels将其立即保存到Bitmap。
我遇到的问题是: 我想保存图像,并将选定的滤镜应用于它,与所显示的尺寸相同。因此,我使用与保存缩略图相同的算法但使用完整的图像大小而不是仅仅60x60。但是当我这样做时,保存的位图只是图像的左下角,其余的只是一个黑屏。但是,当我将尺寸从3072x4096更改为1080x1920时,将正确绘制并保存位图。我认为这与设备屏幕的尺寸有关,因为它比设备屏幕大,因此无法读取glReadPixels的全尺寸。
有没有人知道如何解决这个问题?或者可以向我解释为什么程序以这种方式运行。
感谢您的帮助。
int[] mTextures = new int[2];
//... I set the Effect I want, this all works fine so I've ommited it for clarity...///
GLES20.glBindFrameBuffer(GLES20.GL_FRAMEBUFFER, 0) // Bind Default Frame buffer
/// setup up program and everything works
GLES20.glViewPort(0,0,mTexWdith, mTexHeight) // should be something along 3160x4096, which is mImageHeight and mImageWdith
// COntinue with normal rendering///
GLES20.ActiveTextture(GLES20.GL_TEXTURE0)
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mTextures[1];
此步骤之后是我使用glesReadPixels的地方 此方法如下所示:
GLES20.glBindFrameBuffer(GLES20.GL_FRAMEBUFFER, 0) // is this the correct binding?
//allocate byte buffer here. Works fine
GLES20.glReadPixels(0,0,mImageWidth, mImageHeight, GLES20.GL_RGBA,GLES.INSIGNED, byteBuffer)
GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, 0);
GLToolBox.checkGlError("store Pixels");
pixelBuffer.rewind();
//set bitmap and use matrix to account for the image being vertically flipped
Bitmap bm = Bitmap.createBitmap(mImageWidth, mImageHeight, Bitmap.Config.ARGB_8888);
bm.copyPixelsFromBuffer(pixelBuffer);
Matrix m = new Matrix();
m.setScale(-1, 1);
m.preRotate(180);
bm = Bitmap.createBitmap(bm,0,0,mImageWidth, mImageHeight, m, false);
然后我继续将图像保存到文件///
答案 0 :(得分:0)
Derhass是正确的,我使用默认的FBO渲染到纹理而不是创建我自己的帧缓冲对象。当使用默认的FBO时,我永远无法读取比设备屏幕显示的像素更多的像素(这导致仅显示从坐标(0,0)到(mScreenWidth,mScreenHeight)的像素,而其余的图像显示为#39) ; s尺寸只是黑色)。
通过生成自己的FBO并将其视口设置为所需的宽度和高度,您可以使用与设备最大纹理大小一样大的glReadPixels读取绑定帧Buffer中的像素。