![](/img/trans.png)
[英]How to load output of openGL glReadpixels() into bitmap memory
[英]Flipping RGBA output of glReadPixels (C++ OpenGL)
我想從 glReadPixel 翻轉輸出圖像。 我已經通過將 glReadPixels 保存到文件中來檢查它的輸出。 圖像是正確的,但是它顛倒了。
我試過的
int patchSize = 50;
std::vector<unsigned char> rgbdata(4*patchSize*patchSize);
glReadPixels(x-(patchSize/2), y-(patchSize/2)/2), patchSize,patchSize,GL_RGBA,GL_UNSIGNED_BYTE, &rgbdata[0]);
std::vector< unsigned char > temp_rgbdata = rgbdata; // Create a copy of the data
rgbdata.clear(); // Reset the array
for (int i=patchSize-1; i >= 0; i--) // Count backwards in order to flip
{
for( int j = 0; j < patchSize; j++) {
rgbdata.push_back(temp_rgbdata[i*patchSize+j*4]);
rgbdata.push_back(temp_rgbdata[i*patchSize+j*4+1]);
rgbdata.push_back(temp_rgbdata[i*patchSize+j*4+2]);
rgbdata.push_back(temp_rgbdata[i*patchSize+j*4+3]);
}
}
temp_rgbdata.clear(); // Clear the temporary array
怎么了
圖像結果都是錯誤的:
任何幫助和評論表示贊賞。 謝謝你。
解決方案(由鮑里斯)
int patchSize = 50;
std::vector<unsigned char> rgbdata(4*patchSize*patchSize);
glReadPixels(x-(patchSize/2), y-(patchSize/2)), patchSize,patchSize,GL_RGBA,GL_UNSIGNED_BYTE, &rgbdata[0]);
std::vector< unsigned char > temp_rgbdata = rgbdata; // Create a copy of the data
rgbdata.clear(); // Reset the array
for (int i=patchSize-1; i >= 0; i--) // Count backwards in order to flip
{
for( int j = 0; j < patchSize; j++) {
rgbdata.push_back(temp_rgbdata[(i*patchSize+j)*4]);
rgbdata.push_back(temp_rgbdata[(i*patchSize+j)*4+1]);
rgbdata.push_back(temp_rgbdata[(i*patchSize+j)*4+2]);
rgbdata.push_back(temp_rgbdata[(i*patchSize+j)*4+3]);
}
}
temp_rgbdata.clear(); // Clear the temporary array
您確定要從/向正確的坐標系讀取和寫入嗎? 以下內容來自OpenGL.org :
與具有左上角坐標系的 2D 渲染 API 相關的另一個常見缺陷是 2D 圖像文件格式從頂部掃描線而不是底部掃描線開始圖像。 默認情況下,OpenGL 假定圖像從底部掃描線開始。 如果在渲染時確實需要翻轉圖像,可以使用 glPixelZoom(1,-1)。
如果您保存的圖像總是上下顛倒,這可能是哪里出了問題。 確保您知道 (0,0) 像素的位置(左上角或左下角),然后相應地調整圖像算法。
所有這些行中都需要括號:
temp_rgbdata[ (i*patchSize+j)*4 ]
順便說一句,您可以通過以下方式提高效率:
將顛倒的圖像放入臨時數組(避免無用的副本)
初始化最終大小的 rgbdata 並一次復制整行:
這是你的方法:
int patchSize = 50;
std::vector<unsigned char> temp_rgbdata(4*patchSize*patchSize);
glReadPixels(x-(patchSize/2), y-(patchSize/2)),patchSize,patchSize,GL_RGBA,GL_UNSIGNED_BYTE, &temp_rgbdata[0]);
std::vector< unsigned char > rgbdata(4*patchSize*patchSize);
for (int i=0; i < patchSize; i++) // Doesn't matter the order now
memcpy(&rgbdata[i*patchSize*4], // address of destination
&temp_rgbdata[(patchSize-i-1)*patchSize*4], // address of source
patchSize*4*sizeof(unsigned char) ); // number of bytes to copy
temp_rgbdata.clear(); // Clear the temporary array
使用 C++17 swap_ranges
沒有臨時向量的情況下翻轉glReadPixels
輸出的更簡單方法。 下面的代碼並不特定於所詢問的內容,可以與x
、 y
、 w
和h
任何值一起使用。
std::vector<uint8_t> pixels(3 * w * h);
glReadPixels(x, y, w, h, GL_RGB, GL_UNSIGNED_BYTE, pixels.data());
for(int line = 0; line != h/2; ++line) {
std::swap_ranges(
pixels.begin() + 3 * w * line,
pixels.begin() + 3 * w * (line+1),
pixels.begin() + 3 * w * (h-line-1));
}
這是一個完整的例子,建立在 Stypox 的偉大片段之上 - 這也進行了實際的寫作。 當然,交換你的協調系統是另一種解決方法,但我發現左上角的 0,0 更自然。
// https://github.com/nothings/stb/blob/master/stb_image_write.h
#include "stb_image_write.h"
glPixelStorei(GL_PACK_ALIGNMENT, 1);
glReadBuffer(GL_BACK_LEFT);
std::vector<uint8_t> pixels(3 * w * h);
glReadPixels(0, 0, w, h, GL_RGB, GL_UNSIGNED_BYTE, pixels.data());
for(int line = 0; line != h/2; ++line) {
std::swap_ranges(pixels.begin() + 3 * w * line,
pixels.begin() + 3 * w * (line+1),
pixels.begin() + 3 * w * (h-line-1));
}
int components = 3;
stbi_write_png("out.png", w, h, components, pixels.data(), 3 * w);
stbi_write_tga("out.tga", w, h, components, pixels.data());
我用這句話來截屏,
glReadPixels(0,0,SCR_WIDTH,SCR_HEIGHT,GL_RGB,GL_UNSIGNED_BYTE,buf);
而 buf 的類型是 uint8_t*,
所以我這樣做
void flip(uint8_t** buf)
{
int totalLength = SCR_HEIGHT*SCR_WIDTH*3;
int oneLineLength = SCR_WIDTH*3;
uint8_t* tmp = (uint8_t*)malloc(SCR_HEIGHT*SCR_WIDTH*3);
memcpy(tmp,*buf,SCR_WIDTH*SCR_HEIGHT*3);
memset(*buf,0,sizeof(uint8_t)*SCR_HEIGHT*SCR_WIDTH*3);
for(int i = 0; i < SCR_HEIGHT;i++){
memcpy(*buf+oneLineLength*i,tmp+totalLength-oneLineLength*(i+1),oneLineLength);
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.