opengl显示结果保存为图片

#include<fstream>

bool writeBMP(const char filename[], unsigned char* data, unsigned int w, unsigned int h)
{
std::ofstream out_file;


/** 检查data */
if (!data)
{
std::cerr << "data corrupted! " << std::endl;
out_file.close();
return false;
}


/** 创建位图文件信息和位图文件头结构 */
BITMAPFILEHEADER header;
BITMAPINFOHEADER bitmapInfoHeader;


//unsigned char textureColors = 0;/**< 用于将图像颜色从BGR变换到RGB */


/** 打开文件,并检查错误 */
out_file.open(filename, std::ios::out | std::ios::binary);
if (!out_file)
{
std::cerr << "Unable to open file " << filename << std::endl;
return false;
}


/** 填充BITMAPFILEHEADER */
header.bfType = (WORD)0x4d42;// 3;// BITMAP_ID;
header.bfSize = w*h * 3 + sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
header.bfReserved1 = 0;
header.bfReserved2 = 0;
header.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
/** 写入位图文件头信息 */
out_file.write((char*)&header, sizeof(BITMAPFILEHEADER));


/** 填充BITMAPINFOHEADER */
bitmapInfoHeader.biSize = sizeof(BITMAPINFOHEADER);
bitmapInfoHeader.biWidth = w;
bitmapInfoHeader.biHeight = h;
bitmapInfoHeader.biPlanes = 1;
bitmapInfoHeader.biBitCount = 24;
bitmapInfoHeader.biCompression = BI_RGB; // BI_RLE4 BI_RLE8
bitmapInfoHeader.biSizeImage = w * h * 3; // 当压缩类型为BI_RGB是也可以设置为0
bitmapInfoHeader.biXPelsPerMeter = 0;
bitmapInfoHeader.biYPelsPerMeter = 0;
bitmapInfoHeader.biClrUsed = 0;
bitmapInfoHeader.biClrImportant = 0;
/** 写入位图文件信息 */
out_file.write((char*)&bitmapInfoHeader, sizeof(BITMAPINFOHEADER));


/** 将指针移到数据开始位置 */
out_file.seekp(header.bfOffBits, std::ios::beg);


/** 写入图像数据 */
out_file.write((char*)data, bitmapInfoHeader.biSizeImage);


out_file.close();
return true;
}
void saveDisPlayResToBmp(const char filename[])
{
GLbyte* pBits = 0; // data
static FILE *fp = NULL;
GLenum lastBuffer;


unsigned long lImageSize;
GLint iViewport[4]; // view


glGetIntegerv(GL_VIEWPORT, iViewport);
lImageSize = iViewport[2] * iViewport[3] * 3;


pBits = (GLbyte*)new unsigned char[lImageSize];
if (!pBits)return;


// 从color buffer中读取数据
glPixelStorei(GL_PACK_ALIGNMENT, 1);
glPixelStorei(GL_PACK_ROW_LENGTH, 0);
glPixelStorei(GL_PACK_SKIP_ROWS, 0);
glPixelStorei(GL_PACK_SKIP_PIXELS, 0);
//
glGetIntegerv(GL_READ_BUFFER, (GLint*)&lastBuffer);
glReadBuffer(GL_FRONT);
glReadPixels(0, 0, iViewport[2], iViewport[3], GL_BGR_EXT, GL_UNSIGNED_BYTE, pBits);
glReadBuffer(lastBuffer);


writeBMP(filename, (unsigned char*)pBits, iViewport[2], iViewport[3]);


}

调用方法:saveDisPlayResToBmp("D:\\test.bmp");

  • 4
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
好的,以下是一个简单的 Android OpenGL 实现代码,用于将预览图片数据保存到 Texture ID 中并在屏幕上显示。 首先,您需要创建一个 GLSurfaceView,并在其 Renderer 中实现预览图片的渲染逻辑。在下面的代码中,我们使用 Camera2 API 获取摄像头预览数据并将其渲染到屏幕上。 ``` public class MyGLSurfaceView extends GLSurfaceView { private MyGLRenderer mRenderer; public MyGLSurfaceView(Context context) { super(context); setEGLContextClientVersion(2); mRenderer = new MyGLRenderer(); setRenderer(mRenderer); } public class MyGLRenderer implements GLSurfaceView.Renderer { private int mTextureId = -1; private SurfaceTexture mSurfaceTexture; private CameraDevice mCameraDevice; private CameraCaptureSession mCaptureSession; @Override public void onSurfaceCreated(GL10 gl, EGLConfig config) { // 创建 OpenGL 纹理对象 int[] textureIds = new int[1]; GLES20.glGenTextures(1, textureIds, 0); mTextureId = textureIds[0]; // 将纹理对象绑定到 GL_TEXTURE_2D 目标上 GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mTextureId); // 设置纹理参数 GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_LINEAR); GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR); GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_CLAMP_TO_EDGE); GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_CLAMP_TO_EDGE); // 创建 SurfaceTexture 对象,并将其与纹理对象关联 mSurfaceTexture = new SurfaceTexture(mTextureId); mSurfaceTexture.setOnFrameAvailableListener(new SurfaceTexture.OnFrameAvailableListener() { @Override public void onFrameAvailable(SurfaceTexture surfaceTexture) { requestRender(); } }); // 打开摄像头 CameraManager cameraManager = (CameraManager) getContext().getSystemService(Context.CAMERA_SERVICE); try { String cameraId = cameraManager.getCameraIdList()[0]; cameraManager.openCamera(cameraId, new CameraDevice.StateCallback() { @Override public void onOpened(CameraDevice camera) { mCameraDevice = camera; try { // 创建预览请求 Surface surface = new Surface(mSurfaceTexture); CaptureRequest.Builder builder = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW); builder.addTarget(surface); CaptureRequest request = builder.build(); // 创建预览会话 mCameraDevice.createCaptureSession(Arrays.asList(surface), new CameraCaptureSession.StateCallback() { @Override public void onConfigured(CameraCaptureSession session) { mCaptureSession = session; try { // 启动预览 mCaptureSession.setRepeatingRequest(request, null, null); } catch (CameraAccessException e) { e.printStackTrace(); } } @Override public void onConfigureFailed(CameraCaptureSession session) { session.close(); mCaptureSession = null; } }, null); } catch (CameraAccessException e) { e.printStackTrace(); } } @Override public void onDisconnected(CameraDevice camera) { camera.close(); mCameraDevice = null; } @Override public void onError(CameraDevice camera, int error) { camera.close(); mCameraDevice = null; } }, null); } catch (CameraAccessException e) { e.printStackTrace(); } } @Override public void onSurfaceChanged(GL10 gl, int width, int height) { GLES20.glViewport(0, 0, width, height); } @Override public void onDrawFrame(GL10 gl) { // 更新纹理数据 mSurfaceTexture.updateTexImage(); // 渲染预览画面 GLES20.glClearColor(0.0f, 0.0f, 0.0f, 1.0f); GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT); GLES20.glUseProgram(mProgram); GLES20.glActiveTexture(GLES20.GL_TEXTURE0); GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mTextureId); int positionHandle = GLES20.glGetAttribLocation(mProgram, "aPosition"); GLES20.glEnableVertexAttribArray(positionHandle); GLES20.glVertexAttribPointer(positionHandle, 2, GLES20.GL_FLOAT, false, 0, mVertexBuffer); int texCoordHandle = GLES20.glGetAttribLocation(mProgram, "aTexCoord"); GLES20.glEnableVertexAttribArray(texCoordHandle); GLES20.glVertexAttribPointer(texCoordHandle, 2, GLES20.GL_FLOAT, false, 0, mTexCoordBuffer); GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4); GLES20.glDisableVertexAttribArray(positionHandle); GLES20.glDisableVertexAttribArray(texCoordHandle); } } } ``` 上述代码中,我们创建了一个 GLSurfaceView,并在它的 Renderer 中实现了预览图片的渲染逻辑。在 onSurfaceCreated 方法中,我们创建了一个 OpenGL 纹理对象,并将其与一个 SurfaceTexture 对象关联。然后,我们打开摄像头并创建了一个预览会话,将摄像头预览数据传递给 SurfaceTexture 对象,从而更新纹理数据。在 onDrawFrame 方法中,我们使用该纹理对象渲染预览画面,并将其显示在屏幕上。 请注意,上述代码中的部分变量和方法实现并未展示,您需要自行完成它们的实现。同时,如果您需要保存预览图片数据到文件中,可以使用 glReadPixels 函数将屏幕上的像素数据读取到内存中,然后将其保存到文件中。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值