我正在尝试获得一张16色位图的图像。
我在网上发帖找不到解决方案。
这里的实现很简单。
#include "stdafx.h"
#include <windows.h>
#include <stdio.h>
LPBITMAPINFO ConstructBitmapInfo(int nBits, int nX, int nY);
VOID RocketBuffer(LPVOID lpData);
int _tmain(int argc, _TCHAR* argv[])
{
HWND hDesktop = NULL;
HDC hCurrenDC = NULL;
INT nX, nY;
LPBITMAPINFO lpBmpInfo;
HBITMAP hBmpScreen;
LPVOID lpBmpBuffer = NULL;
if(NULL == (hDesktop = GetDesktopWindow()))
return GetLastError();
if (NULL == (hCurrenDC = GetDC(hDesktop)))
return GetLastError();
nX = GetSystemMetrics(SM_CXSCREEN);
nY = GetSystemMetrics(SM_CYSCREEN);
HDC hOrgMemDC = NULL;
hOrgMemDC = CreateCompatibleDC(hCurrenDC);
lpBmpInfo = ConstructBitmapInfo(4, nX, nY);
hBmpScreen = CreateDIBSection(hCurrenDC, lpBmpInfo, DIB_RGB_COLORS, &lpBmpBuffer, NULL, 0);
SelectObject(hOrgMemDC, hBmpScreen);
if(!BitBlt(hOrgMemDC, 0, 0, nX, nY, hCurrenDC, 0, 0, SRCCOPY))
{
return GetLastError();
}
LPBYTE lpWriteData = new BYTE[lpBmpInfo->bmiHeader.biSizeImage * 2];
memcpy(lpWriteData, lpBmpBuffer, lpBmpInfo->bmiHeader.biSizeImage);
RocketBuffer(lpBmpBuffer);
delete[] lpWriteData;
return 0;
}
LPBITMAPINFO ConstructBitmapInfo(int nBits, int nX, int nY)
{
int color_num = nBits <= 8 ? 1 << nBits : 0;
int nBISize = sizeof(BITMAPINFOHEADER) + (color_num * sizeof(RGBQUAD));
BITMAPINFO *lpbmi = (BITMAPINFO *) new BYTE[nBISize];
BITMAPINFOHEADER *lpbmih = &(lpbmi->bmiHeader);
lpbmih->biSize = sizeof(BITMAPINFOHEADER);
lpbmih->biWidth = nX;
lpbmih->biHeight = nY;
lpbmih->biPlanes = 1;
lpbmih->biBitCount = nBits;
lpbmih->biCompression = BI_RGB;
lpbmih->biXPelsPerMeter = 0;
lpbmih->biYPelsPerMeter = 0;
lpbmih->biClrUsed = 0;
lpbmih->biClrImportant = 0;
lpbmih->biSizeImage = (((lpbmih->biWidth * lpbmih->biBitCount + 31) & ~31) >> 3) * lpbmih->biHeight;
if (nBits >= 16)
return lpbmi;
HDC hDC = GetDC(NULL);
HBITMAP hBmp = CreateCompatibleBitmap(hDC, 1, 1);
GetDIBits(hDC, hBmp, 0, 0, NULL, lpbmi, DIB_RGB_COLORS);
ReleaseDC(NULL, hDC);
DeleteObject(hBmp);
return lpbmi;
}
VOID RocketBuffer(LPVOID lpData)
{
// ...
}
我无法将lpWriteData
输出为* .bmp
文件。它不是BMP格式。
因此,函数RocketBuffer (LPVOID lpData)
将无法正确执行其功能。
问题是如何在内存中获得16色位图的屏幕截图输出。
32位彩色图像
我想像这样的4位图像。
4位彩色图像
发布于 2018-06-12 00:09:56
16色4位图像包括具有16种颜色的颜色表。颜色表大小为16 *4字节。通过GetDIBits
接收调色板时,BITMAPINFO
应足够大
下面的代码适用于以下位图:
//bpp = 1
//bpp = 4
//bpp = 8
。
#include <iostream>
#include <fstream>
#include <vector>
#include <windows.h>
int main()
{
//4-bit bitmap: bpp = 4
//valid values with this method bpp = 1, 4, 8
WORD bpp = 4;
//color table:
int colorsize = (1 << bpp) * sizeof(RGBQUAD);
int width = GetSystemMetrics(SM_CXFULLSCREEN);
int height = GetSystemMetrics(SM_CYFULLSCREEN);
HDC hdc = GetDC(HWND_DESKTOP);
HBITMAP hbitmap = CreateCompatibleBitmap(hdc, width, height);
HDC memdc = CreateCompatibleDC(hdc);
HGDIOBJ oldbmp = SelectObject(memdc, hbitmap);
BitBlt(memdc, 0, 0, width, height, hdc, 0, 0, CAPTUREBLT | SRCCOPY);
SelectObject(memdc, oldbmp);
//size in bytes for pixel data:
DWORD size = ((width * bpp + 31) / 32) * 4 * height;
std::vector<BYTE> bi_memory;
bi_memory.resize(sizeof(BITMAPINFOHEADER) + colorsize, 0);
BITMAPINFO* bi = (BITMAPINFO*)&bi_memory[0];
bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
bi->bmiHeader.biWidth = width;
bi->bmiHeader.biHeight = height;
bi->bmiHeader.biPlanes = 1;
bi->bmiHeader.biBitCount = bpp;
bi->bmiHeader.biCompression = BI_RGB;
bi->bmiHeader.biClrUsed = 16;
std::vector<BYTE> pixels(size + colorsize);
GetDIBits(hdc, hbitmap, 0, height, &pixels[0], bi, DIB_RGB_COLORS);
std::ofstream fout(TEXT("c:\\test\\_4bit.bmp"), std::ios::binary);
if(fout)
{
//bitmap file header
//(54 = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER))
BITMAPFILEHEADER filehdr = { 'MB', 54 + colorsize + size, 0, 0, 54 };
fout.write((char*)&filehdr, sizeof(BITMAPFILEHEADER));
//bitmap info header
fout.write((char*)&bi->bmiHeader, sizeof(BITMAPINFOHEADER));
//color table
fout.write((char*)bi->bmiColors, colorsize);
//pixel data
fout.write((char*)pixels.data(), pixels.size());
}
//cleanup:
DeleteObject(memdc);
DeleteObject(hbitmap);
ReleaseDC(HWND_DESKTOP, hdc);
return 0;
}
https://stackoverflow.com/questions/50794015
复制相似问题