Windows DIB文件操作详解-1.DIB的读入、保存和显示
2020-11-28 10:28
标签:windows setdibitstodevice stretchdibits 位图 DIB(设备无关位图)是存储在磁盘上的位图文件,可以从磁盘读到内存中或从内存保存到磁盘上,它的磁盘文件结构是标准化的,在Linux、Unix及Windows上都可以以同样效果显示。位图是最接近硬件的图像格式,Windows显示的核心是位图,它的SDK API专门提供了一组用于操作DIB文件的函数。但是由于这样或那样的原因,高效合理的使用这些DIB API是需要了解不少历史和使用背景的,在这里我抽茧剥丝介绍和演示DIB的使用,相信对你更好的使用DIB文件有帮助,由于DIB函数比较多,这里分为三部分介绍,首先是DIB的读入、保存和显示。 关于DIB文件的组成很多地方有详细描述,这里不再详细赘述。主要分为如下几个部分: 其中 其中,信息表头和RGB调色板合称为位图信息。 我们要把DIB数据读入到内存中,那么就要分配相应的内存,把读入的数据写到对应的内存区中,这里SDK 提供的数据结构是各种结构体,结构体的各个字段对应磁盘文件中各个信息值。我们这里为了逻辑清楚,使用最常使用的DIB结构体。 如图,文件中的数据读到对应的内存结构中完成文件的读入,内存结构中的数据写到对应的文件中完成文件的保存。 其中 把BITMAPINFOHEADER和RGBQUAD[0]作为BITMAPINFO结构体成员,这样一方面是为了和磁盘文件对应,另一方面也是为了访问调色板数据方便。 这里的磁盘文件中各个段在磁盘上保存位置必须是连续的,但是对应的内存中文件信息头、位图信息和位图数据三大块不一定要是连续的。因此,在读入文件中你既可以一次性读入磁盘文件到连续的内存中,也可以分开读入到三个分别连续的内存中,后面会做相关演示。 Windows DIB文件操作详解-1.DIB的读入、保存和显示,搜素材,soscw.com Windows DIB文件操作详解-1.DIB的读入、保存和显示 标签:windows setdibitstodevice stretchdibits 位图 原文地址:http://blog.csdn.net/wenzhou1219/article/details/261628691.DIB文件的组成
2.Windows DIB内存数据结构
3.DIB显示
int SetDIBitsToDevice(
HDC hdc, // handle to DC
int XDest, // x-coord of destination upper-left corner
int YDest, // y-coord of destination upper-left corner
DWORD dwWidth, // source rectangle width
DWORD dwHeight, // source rectangle height
int XSrc, // x-coord of source lower-left corner
int YSrc, // y-coord of source lower-left corner
UINT uStartScan, // first scan line in array
UINT cScanLines, // number of scan lines
CONST VOID *lpvBits, // array of DIB bits
CONST BITMAPINFO *lpbmi, // bitmap information
UINT fuColorUse // RGB or palette indexes
);
int StretchDIBits(
HDC hdc, // handle to DC
int XDest, // x-coord of destination upper-left corner
int YDest, // y-coord of destination upper-left corner
int nDestWidth, // width of destination rectangle
int nDestHeight, // height of destination rectangle
int XSrc, // x-coord of source upper-left corner
int YSrc, // y-coord of source upper-left corner
int nSrcWidth, // width of source rectangle
int nSrcHeight, // height of source rectangle
CONST VOID *lpBits, // bitmap bits
CONST BITMAPINFO *lpBitsInfo, // bitmap data
UINT iUsage, // usage options
DWORD dwRop // raster operation code
);
4.代码演示
BOOL DibTotalLoad(PTSTR szBmpFile,
PBITMAPFILEHEADER *ppbmfh,
PBITMAPINFO *ppbmi,
PBYTE *ppBits,
PLONG pBmpWidth,
PLONG pBmpHeight)
{
HANDLE hFile;
DWORD dwFileSize, dwBytesRead;
BOOL bSuccess;
//打开文件
hFile = CreateFile( szBmpFile,
GENERIC_READ, FILE_SHARE_READ, NULL,
OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, NULL);
if (INVALID_HANDLE_VALUE == hFile)
{
return FALSE;
}
//判断BMP文件大小(所有部分)
dwFileSize = GetFileSize(hFile, NULL);
//分配对应大小内存用于保存磁盘BMP文件内容
*ppbmfh = malloc(dwFileSize);
if (!(*ppbmfh))
{
CloseHandle(hFile);
return FALSE;
}
//读入文件内容
bSuccess = ReadFile(hFile, *ppbmfh, dwFileSize, &dwBytesRead, NULL);
CloseHandle(hFile);
//校验读入是否正确和文件是否为BMP文件
if (!bSuccess ||
(dwBytesRead != dwFileSize) ||
(*ppbmfh)->bfType != *(WORD *)"BM")
{
free(*ppbmfh);
return FALSE;
}
//计算剩余的返回参数
*ppbmi = (PBITMAPINFO)(*ppbmfh+1);
*ppBits = (PBYTE)(*ppbmfh) + (*ppbmfh)->bfOffBits;
*pBmpWidth = (*ppbmi)->bmiHeader.biWidth;
*pBmpHeight = (*ppbmi)->bmiHeader.biHeight;
return TRUE;
}
BOOL DibTotalSave(PTSTR szBmpFile, PBITMAPFILEHEADER pbmfh)
{
BOOL bSuccess;
DWORD dwBytesWrite;
HANDLE hFile;
//打开要写入的文件
hFile = CreateFile(szBmpFile,
GENERIC_WRITE, 0, NULL,
CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if (INVALID_HANDLE_VALUE == hFile)
{
return FALSE;
}
//写入文件
bSuccess = WriteFile(hFile, pbmfh, pbmfh->bfSize, &dwBytesWrite, NULL);
CloseHandle(hFile);
if (!bSuccess || dwBytesWrite != pbmfh->bfSize)
{
DeleteFile(hFile);
return FALSE;
}
return TRUE;
}
void ShowDib(HDC hdc,
PBITMAPINFO pbmi, PBYTE pBits,
long nBmpWidth, long nBmpHeight,
long cxClient, long cyClient,
BOOL bFull)
{
if (FALSE == bFull)//居中显示
{
SetDIBitsToDevice( hdc,
(cxClient-nBmpWidth)/2, (cyClient-nBmpHeight)/2,
nBmpWidth, nBmpHeight,
0, 0,
0, nBmpHeight,
pBits, pbmi,
DIB_RGB_COLORS);
}
else//拉伸显示
{
SetStretchBltMode(hdc, COLORONCOLOR);
StretchDIBits(hdc,
0, 0,
cxClient, cyClient,
0, 0,
nBmpWidth, nBmpHeight,
pBits, pbmi,
DIB_RGB_COLORS,
SRCCOPY);
}
}
这里需要补充说明的是,为了保证逻辑清晰,本文没有考虑位图的OS/2兼容格式和自顶向下位图等特殊情况,错误处理可能也不是特别完善(没有考虑超大位图的情况),演示的代码在大部分情况下是适用的,只是为了起抛砖引玉的作用。关于DIB的详细描述当推Petzold的《Windows 程序设计》的“与设备无关的位图”一章,这一章描述非常详细,但是个别地方有些晦涩,结合本文来看可以加深理解。
文章标题:Windows DIB文件操作详解-1.DIB的读入、保存和显示
文章链接:http://soscw.com/essay/23106.html