這是我最後一個關於將截圖保存到SOIL的問題的延續。 here現在我想知道,如何製作屏幕截圖部分並消除奇怪行爲的原因。我的代碼:通過SOIL保存位圖時斷開BMP。截圖區
bool saveTexture(string path, glm::vec2 startPos, glm::vec2 endPos)
{
const char *charPath = path.c_str();
GLuint widthPart = abs(endPos.x - startPos.x);
GLuint heightPart = abs(endPos.y - startPos.y);
BITMAPINFO bmi;
auto& hdr = bmi.bmiHeader;
hdr.biSize = sizeof(bmi.bmiHeader);
hdr.biWidth = widthPart;
hdr.biHeight = -1.0 * heightPart;
hdr.biPlanes = 1;
hdr.biBitCount = 24;
hdr.biCompression = BI_RGB;
hdr.biSizeImage = 0;
hdr.biXPelsPerMeter = 0;
hdr.biYPelsPerMeter = 0;
hdr.biClrUsed = 0;
hdr.biClrImportant = 0;
unsigned char* bitmapBits = (unsigned char*)malloc(3 * widthPart * heightPart);
HDC hdc = GetDC(NULL);
HDC hBmpDc = CreateCompatibleDC(hdc);
HBITMAP hBmp = CreateDIBSection(hdc, &bmi, DIB_RGB_COLORS, (void**)&bitmapBits, nullptr, 0);
SelectObject(hBmpDc, hBmp);
BitBlt(hBmpDc, 0, 0, widthPart, heightPart, hdc, startPos.x, startPos.y, SRCCOPY);
//UPDATE:
- int bytes = widthPart * heightPart * 3;
- // invert R and B chanels
- for (unsigned i = 0; i< bytes - 2; i += 3)
- {
- int tmp = bitmapBits[i + 2];
- bitmapBits[i + 2] = bitmapBits[i];
- bitmapBits[i] = tmp;
- }
+ unsigned stride = (widthPart * (hdr.biBitCount/8) + 3) & ~3;
+ // invert R and B chanels
+ for (unsigned row = 0; row < heightPart; ++row) {
+ for (unsigned col = 0; col < widthPart; ++col) {
+ // Calculate the pixel index into the buffer, taking the
alignment into account
+ const size_t index{ row * stride + col * hdr.biBitCount/8 };
+ std::swap(bitmapBits[index], bitmapBits[index + 2]);
+ }
+ }
int texture = SOIL_save_image(charPath, SOIL_SAVE_TYPE_BMP, widthPart, heightPart, 3, bitmapBits);
return texture;
}
當我運行這個,如果widthPart和heightPart是偶數,那就很完美了。但是,如果從這個事情是奇數我得到這個BMP的:
我檢查任何轉換和代碼的兩倍,但在我看來,原因是我的錯塊傳輸功能。轉換RGB的功能不會影響問題。什麼可能是一個原因?這是BitBlt中區域的正確方法?
更新無偶數或奇數。當這個數字相等時,產生正確的圖像。我不知道哪裏出了問題((
UPDATE2
SOIL_save_image功能檢查參數錯誤併發送至stbi_write_bmp:
int stbi_write_bmp(char *filename, int x, int y, int comp, void *data)
{
int pad = (-x*3) & 3;
return outfile(filename,-1,-1,x,y,comp,data,0,pad,
"11 4 22 4" "4 44 22 444444",
'B', 'M', 14+40+(x*3+pad)*y, 0,0, 14+40, // file header
40, x,y, 1,24, 0,0,0,0,0,0); // bitmap header
}
OUTFILE功能:
static int outfile(char const *filename, int rgb_dir, int vdir, int x, int
y, int comp, void *data, int alpha, int pad, char *fmt, ...)
{
FILE *f = fopen(filename, "wb");
if (f) {
va_list v;
va_start(v, fmt);
writefv(f, fmt, v);
va_end(v);
write_pixels(f,rgb_dir,vdir,x,y,comp,data,alpha,pad);
fclose(f);
}
return f != NULL;
}
無論如何,謝謝你的幫助,但是我嘗試了不同的變體代碼(在編輯之前),它沒有任何改變。 :((每次當widthPart不能被4整除時(不管是什麼是heightPart)我得到的是BMP的上面,我用你的部分更新了這個問題 – hardCode
@hardCode:請不要接受一個不能解決你的問題的答案,並且不要編輯你的問題使它變成另外一個,而是發表評論來要求澄清。在猜測中,我會假設,這個問題仍然與位圖圖像中的掃描線對齊有關,也許'SOIL_save_image'沒有我們可以看到'SOIL_save_image'的文檔嗎? – IInspectable
我更新了這個問題。在SOIL文檔中沒有關於編寫BMP的內容:http://www.lonesock.net/soil.html – hardCode