本文介绍了OpenGL ES ReadPixels从大于屏幕的Texture到位图的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

因此,我正在实现一个屏幕,以将效果(纹理,负片等)应用于用户从其相机拍摄的图像或从其画廊拍摄的图像.我能够拍摄他们选择或拍摄的图像,并通过使用OpenGL以全分辨率(或按比例缩小以保持纵横比,具体取决于其设备的最大纹理尺寸和图像尺寸)显示给他们.同样,选择效果并将其应用于纹理也可以很好地工作.就像拍摄图像并制作一堆小预览缩略图一样,并以60x60的尺寸对其应用特殊效果.我这样做的方法是使用FrameBuffer渲染图像,并使用glReadPixels立即将其保存到Bitmap中.

So, I am implementing a screen to apply Effects (grain, negative, etc) to an image a user has taken from their camera or an image taken from their gallery. I am able to take the image that they have selected or taken and display it to them through the use of OpenGL at full resolution ( or scaled down maintaining aspect ratio depending on the max texture size of their device and the size of the image). Also, selecting the effect and applying to the texture works completely fine. As does taking the image and making a bunch of little preview thumbnails with that particular effect applied to it at 60x60 size. The way I do this is by using a FrameBuffer to render the image and saving it immediately to a Bitmap using glReadPixels.

我遇到的问题是: 我要保存应用了所选滤镜的图像,其尺寸与显示的尺寸相同.因此,我使用与保存缩略图相同的算法,但使用的是完整图像尺寸,而不是60x60.但是,当我这样做时,保存的位图只是图像的左下角,其余的只是黑屏.但是,当我将尺寸从3072x4096更改为1080x1920时,将正确绘制并保存位图.我认为这与设备屏幕的尺寸有关,因为glReadPixels比设备屏幕大,因此它无法读取完整尺寸.

The problem I am having is this: I want to save the image with the selected filter applied to it as at the same dimensions as what is being display. So I use the same algorithm I use with saving the thumbnails but with the full image size instead of just 60x60. But when i do this, the bitmap that is saved is just the lower left corner of the image, and the rest is just a black screen. However, when I change the dimensions from say 3072x4096 to 1080x1920, the bitmap is drawn and saved correctly. I believe that this has to do with the dimensions of the device screen preventing glReadPixels from reading the full size since it is bigger then the device screen.

对如何准确解决此问题有任何见解吗?或可以向我解释为什么程序以这种方式运行.

Does any have any insight into how to resolve this exactly? Or can explain to me why it is that the program behaves in this way.

谢谢您的帮助.

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此方法如下所示:

After this step is where I use the glesReadPixelsThis method looks like this:

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

然后我继续将此处的图像保存到文件中///

Then I continue to save the image here into a file///

推荐答案

Derhass是正确的,因为我使用默认的FBO渲染到纹理而不是创建自己的帧缓冲区对象.当使用默认的FBO时,我读取的像素数永远不会超过设备屏幕显示的像素数.(这导致仅显示从坐标(0,0)到(mScreenWidth,mScreenHeight)的像素,而其余图像大小为只是黑色).

Derhass was correct that I was using the default FBO to render to a texture instead of creating my own Frame Buffer Object. When using the default FBO I could never read more pixels than what the device screen could display.(which resulted in just the pixels starting from coords (0,0) to (mScreenWidth,mScreenHeight) being displayed while the rest of the image's size was just black).

通过生成自己的FBO并将其视口设置为所需的宽度和高度,您可以使用与设备最大纹理大小一样大的glReadPixels从绑定的帧缓冲区中读取像素.

By generating your own FBO and settings its viewport to the desired width and height you can read pixels from the bound frame Buffer with glReadPixels as large as the devices maximum texture size.

这篇关于OpenGL ES ReadPixels从大于屏幕的Texture到位图的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-23 09:55