《数字图像处理》老师非要用MFC做实验,所以我被迫接触了一些window api 。一开始看的很辛苦,不过本着不会就查,再不会再查的递归解决思想,我也解决了一些问题,
不过MFC的机制我还是一无所知,我的本心也不想知道,只能是要用多少就学多少吧。在这里我给DIB函数写了一些注释,或许能给那些和我一样刚刚接触Windows编程的人,
或是凑巧要做图像处理作业的人一些帮助。
// ************************************************************************
// 文件名:dibapi.cpp
//
// DIB(Independent Bitmap) API函数库:
//
// PaintDIB() - 绘制DIB对象
// CreateDIBPalette() - 创建DIB对象调色板
// FindDIBBits() - 返回DIB图像象素起始位置
// DIBWidth() - 返回DIB宽度
// DIBHeight() - 返回DIB高度
// PaletteSize() - 返回DIB调色板大小
// DIBNumColors() - 计算DIB调色板颜色数目
// CopyHandle() - 拷贝内存块
//
// SaveDIB() - 将DIB保存到指定文件中
// ReadDIBFile() - 重指定文件中读取DIB对象
//
// DIBToPCX256() - 将指定的256色DIB对象保存为256色PCX文件
// ReadPCX256() - 读取256色PCX文件
//
// ************************************************************************
#include "stdafx.h"
#include "dibapi.h"
#include <io.h>
#include <errno.h>
#include <math.h>
#include <direct.h>//目录
/*
* Dib文件头标志(字符串"BM",写DIB时用到该常数)
*/
#define DIB_HEADER_MARKER ((WORD) ('M' << 8) | 'B')//这是在构造“BM”在内存中的表示,
‘M’的ascii码是77,它的二进制是01001101,左移八位为 0100 1101 0000 0000
‘B’的ascii码是66,它的二进制是01000010,
0100 1101 0000 0000|0000 0000 0100 0010=0100 1101 0100 0010
结果就是BM在内存中的表示
/*************************************************************************
*
* 函数名称:
* PaintDIB()
*
* 参数:
* HDC hDC - 输出设备DC//HDC是一个结构体指针,结构体内只有一个名为unused的int变量
* LPRECT lpDCRect - 绘制矩形区域//LPRECT是一个指向tagRECT结构体的指针,
//struct tagRECT
// {
//LONG left;
//LONG top;
//LONG right;
//LONG bottom;
//}
//LONG是long的别名,为什么它要取一个这么没有用的别名??????
* HDIB hDIB - 指向DIB对象的指针//HDIB的类型同HDC,但是它不是//Windows内置的别名,要自己用DECLARE_HANDLE()宏定义
* LPRECT lpDIBRect - 要输出的DIB区域//同上
* CPalette* pPal - 指向DIB对象调色板的指针//CPalette是一个封装了Window
//调色板的类,Windows调色板是一个设备借口,应用程序利用这个接口,使用设备的颜
//色处理能力
*
* 返回值:
* BOOL - 绘制成功返回TRUE,否则返回FALSE。
*
* 说明:
* 该函数主要用来绘制DIB对象。其中调用了StretchDIBits()或者
* SetDIBitsToDevice()来绘制DIB对象。输出的设备由由参数hDC指
* 定;绘制的矩形区域由参数lpDCRect指定;输出DIB的区域由参数
* lpDIBRect指定。
*
************************************************************************/
BOOL WINAPI PaintDIB(HDC hDC,
LPRECT lpDCRect,
HDIB hDIB,
LPRECT lpDIBRect,//应该指在lpDCRect中的区域吧?
CPalette* pPal)
{
LPSTR lpDIBHdr; // BITMAPINFOHEADER指针,LPSTR是char*的别
//名
LPSTR lpDIBBits; // DIB象素指针
BOOL bSuccess=FALSE; // 成功标志
HPALETTE hPal=NULL; // DIB调色板,HPALETTE是一个结构体指针,结
//构体内只有一个int 名为unused
HPALETTE hOldPal=NULL; // 以前的调色板
// 判断DIB对象是否为空
if (hDIB == NULL)
{
// 返回
return FALSE;
}
// 锁定DIB
lpDIBHdr = (LPSTR) ::GlobalLock((HGLOBAL) hDIB);//HGLOBAL是一个void*,
只有锁定了一块内存才能操作它,其实这个语句,把位图的这块内存的地址放在了lpDIBHdr,这样每次移动刚好是一个字节
// 找到DIB图像象素起始位置
lpDIBBits = ::FindDIBBits(lpDIBHdr);//找到位图信息的开始地址
// 获取DIB调色板,并选中它
if (pPal != NULL)
{
hPal = (HPALETTE) pPal->m_hObject;//这个数据成员是一个句柄集包含很多绑定到对象的句柄
// 选中调色板
hOldPal = ::SelectPalette(hDC, hPal, TRUE);//该函数选择指定的逻辑调色板到一个设备环境中,并给这个逻辑调色板映射一个物理调色板
}
// 设置显示模式
::SetStretchBltMode(hDC, COLORONCOLOR);设置显示设备环境中的位图拉伸模式,COLORONCOLOR:删除像素。该模式删除所有消除的像素行,不保留其信息。
// 判断是调用StretchDIBits()还是SetDIBitsToDevice()来绘制DIB对象
if ((RECTWIDTH(lpDCRect) == RECTWIDTH(lpDIBRect)) &&
(RECTHEIGHT(lpDCRect) == RECTHEIGHT(lpDIBRect)))//#define RECTWIDTH(lpRect) ((lpRect)->right - (lpRect)->left),
//#define RECTHEIGHT(lpRect) ((lpRect)->bottom - (lpRect)->top),这是两个宏定义函数,获得矩形的宽度,获得矩形的高度。
//如果绘图区域大小和位图图像大小一样,则不用拉伸
{
// 原始大小,不用拉伸。
bSuccess = ::SetDIBitsToDevice(hDC, // hDC,输出的设备
lpDCRect->left, // DestX,绘图区域的坐标
lpDCRect->top, // DestY,同上
RECTWIDTH(lpDCRect), // nDestWidth,绘图区域的宽度,调用了一个宏函数
RECTHEIGHT(lpDCRect), // nDestHeight,绘图区域的高度,调用了一个宏函数
lpDIBRect->left, // SrcX,位图起始坐标,这个坐标在左下,这和位图在内存中是由左
//到右由下到上储存有关
(int)DIBHeight(lpDIBHdr) -
lpDIBRect->top -
RECTHEIGHT(lpDIBRect), // SrcY,y坐标不知道怎么来的?????
0, // nStartScan//绘图区域开始扫描的行
(WORD)DIBHeight(lpDIBHdr), // nNumScans//扫描位图的行数,从起始行开始扫描
lpDIBBits, // lpBits//位图内存的起始位置
(LPBITMAPINFO)lpDIBHdr, // lpBitsInfo//把位图文件的内存直接转换为指向位图信息头的指针,就可以获 //得想要的内存块?
//typedef struct tagBITMAPINFO {
// BITMAPINFOHEADER bmiHeader;
// RGBQUAD bmiColors[1];
}
DIB_RGB_COLORS); // wUsage表示颜色表包含原义的RGB值
//如何理解这个函数:以上都是个人看法
}
else
{
// 非原始大小,拉伸。
bSuccess = ::StretchDIBits(hDC, // hDC
lpDCRect->left, // DestX
lpDCRect->top, // DestY
RECTWIDTH(lpDCRect), // nDestWidth
RECTHEIGHT(lpDCRect), // nDestHeight
lpDIBRect->left, // SrcX
lpDIBRect->top, // SrcY
RECTWIDTH(lpDIBRect), // wSrcWidth
RECTHEIGHT(lpDIBRect), // wSrcHeight
lpDIBBits, // lpBits
(LPBITMAP
DIB函数注释
最新推荐文章于 2018-03-13 16:00:49 发布
![](https://img-home.csdnimg.cn/images/20240711042549.png)