概述
【1】使用DIB处理数字图像
DIB是外部的位图格式,存储为BMP后缀的位图文件。
DIB可以在不同的机器或系统中显示位图所固有的图像。
但是MFC不提供对DIB的支持,单纯使用DIB只能进行面向过程编程。
操作函数:
【2】使用自定义CDib类处理数字图像
设计一个设备无关类CDib,封装DIB位图处理所需要的基本成员变量和成员函数。
** Dib.h**
//======================================================================
// 文件: Dib.h
// 内容: 设备无关位图类-头文件
// 功能: (1)位图的加载与保存;
// (2)位图信息的获取;
// (3)位图数据的获取;
// (3)位图的显示;
// (4)位图的转换;
// (5)位图相关判断;
//======================================================================
#pragma once
#include "afx.h"
class CDib : public CObject
{
public:
// 构造函数,初始化数据成员
CDib(void);
// 析构函数,释放内存空间
~CDib(void);
// 从文件加载位图
BOOL LoadFromFile(LPCTSTR lpszPath);
// 将位图保存到文件
BOOL SaveToFile(LPCTSTR lpszPath);
// 获取位图文件名
LPCTSTR GetFileName();
// 获取位图宽度
LONG GetWidth();
// 获取位图高度
LONG GetHeight();
// 获取位图的宽度和高度
CSize GetDimension();
// 获取位图大小
DWORD GetSize();
// 获取单个像素所占位数
WORD GetBitCount();
// 获取每行像素所占字节数
UINT GetLineByte();
// 获取位图颜色数
DWORD GetNumOfColor();
// 获取位图颜色表
LPRGBQUAD GetRgbQuad();
// 获取位图数据
LPBYTE GetData();
// 显示位图
BOOL Draw(CDC *pDC, CPoint origin, CSize size);
// 24位彩色位图转8位灰度位图
BOOL RgbToGrade();
// 8位灰度位图转24位彩色位图
BOOL GradeToRgb();
// 判断是否含有颜色表
BOOL HasRgbQuad();
// 判断是否是灰度图
BOOL IsGrade();
// 判断位图是否有效
BOOL IsValid();
protected:
// 计算位图颜色表长度
DWORD CalcRgbQuadLength();
// 根据颜色表生成调色板
BOOL MakePalette();
// 清理空间
void Empty(BOOL bFlag = TRUE);
private:
// 位图文件名
char m_fileName[_MAX_PATH];
// 位图文件头指针
LPBITMAPFILEHEADER m_lpBmpFileHeader; // 需要动态分配和释放
// 位图指针(包含除位图文件头的所有内容)
LPBYTE m_lpDib; // 需要动态分配和释放
// 位图信息指针
LPBITMAPINFO m_lpBmpInfo;
// 位图信息头指针
LPBITMAPINFOHEADER m_lpBmpInfoHeader;
// 位图颜色表指针
LPRGBQUAD m_lpRgbQuad;
// 位图数据指针
LPBYTE m_lpData;
// 调色板句柄
HPALETTE m_hPalette;
// 是否有颜色表
BOOL m_bHasRgbQuad;
// 位图是否有效
BOOL m_bValid;
};
//======================================================================
// 文件: Dib.cpp
// 内容: 设备无关位图类-源文件
// 功能: (1)位图的加载与保存;
// (2)位图信息的获取;
// (3)位图数据的获取;
// (3)位图的显示;
// (4)位图的转换;
// (5)位图相关判断;
//======================================================================
#include "StdAfx.h"
#include "Dib.h"
//=======================================================
// 函数功能: 构造函数,初始化数据成员
// 输入参数: 无
// 返回值: 无
//=======================================================
CDib::CDib(void)
{
// 数据成员初始化
strcpy(m_fileName, "");
m_lpBmpFileHeader = NULL;
m_lpDib = NULL;
m_lpBmpInfo = NULL;
m_lpBmpInfoHeader = NULL;
m_lpRgbQuad = NULL;
m_lpData = NULL;
m_hPalette = NULL;
m_bHasRgbQuad = FALSE;
m_bValid = FALSE;
}
//=======================================================
// 函数功能: 析构函数,释放内存空间
// 输入参数: 无
// 返回值: 无
//=======================================================
CDib::~CDib(void)
{
// 清理空间
Empty();
}
//=======================================================
// 函数功能: 从文件加载位图
// 输入参数: LPCTSTR lpszPath-待加载位图文件路径
// 返回值: BOOL-TRUE 成功;FALSE 失败
//=======================================================
BOOL CDib::LoadFromFile(LPCTSTR lpszPath)
{
// 记录位图文件名
strcpy(m_fileName, lpszPath);
// 以读模式打开位图文件
CFile dibFile;
if(!dibFile.Open(m_fileName, CFile::modeRead | CFile::shareDenyWrite))
{
return FALSE;
}
// 清理空间
Empty(FALSE);
// 为位图文件头分配空间,并初始化为0
m_lpBmpFileHeader = (LPBITMAPFILEHEADER)new BYTE[sizeof(BITMAPFILEHEADER)];
memset(m_lpBmpFileHeader, 0, sizeof(BITMAPFILEHEADER));
// 读取位图文件头
int nCount = dibFile.Read((void *)m_lpBmpFileHeader, sizeof(BITMAPFILEHEADER));
if(nCount != sizeof(BITMAPFILEHEADER))
{
return FALSE;
}
// 判断此文件是不是位图文件(“0x4d42”代表“BM”)
if(m_lpBmpFileHeader->bfType == 0x4d42)
{
// 是位图文件
// 计算除位图文件头的空间大小,分配空间并初始化为0
DWORD dwDibSize = dibFile.GetLength() - sizeof(BITMAPFILEHEADER);
m_lpDib = new BYTE[dwDibSize];
memset(m_lpDib, 0, dwDibSize);
// 读取除位图文件头的所有数据
dibFile.Read(m_lpDib, dwDibSize);
// 关闭位图文件
dibFile.Close();
// 设置位图信息指针
m_lpBmpInfo = (LPBITMAPINFO)m_lpDib;
// 设置位图信息头指针
m_lpBmpInfoHeader = (LPBITMAPINFOHEADER)m_lpDib;
// 设置位图颜色表指针
m_lpRgbQuad = (LPRGBQUAD)(m_lpDib + m_lpBmpInfoHeader->biSize);
// 如果位图没有设置位图使用的颜色数,设置它
if(m_lpBmpInfoHeader->biClrUsed == 0)
{
m_lpBmpInfoHeader->biClrUsed = GetNumOfColor();
}
// 计算颜色表长度
DWORD dwRgbQuadLength = CalcRgbQuadLength();
// 设置位图数据指针
m_lpData = m_lpDib + m_lpBmpInfoHeader->biSize + dwRgbQuadLength;
// 判断是否有颜色表
if(m_lpRgbQuad == (LPRGBQUAD)m_lpData)
{
m_lpRgbQuad = NULL; // 将位图颜色表指针置空
m_bHasRgbQuad = FALSE; // 无颜色表
}
else
{
m_bHasRgbQuad = TRUE; // 有颜色表
MakePalette(); // 根据颜色表生成调色板
}
// 设置位图大小(因为很多位图文件都不设置此项)
m_lpBmpInfoHeader->biSizeImage = GetSize();
// 位图有效
m_bValid = TRUE;
return TRUE;
}
else
{
// 不是位图文件
m_bValid = FALSE;
return FALSE;
}
}
//=======================================================
// 函数功能: 将位图保存到文件
// 输入参数: LPCTSTR lpszPath-位图文件保存路径
// 返回值: BOOL-TRUE 成功;FALSE 失败
//=======================================================
BOOL CDib::SaveToFile(LPCTSTR lpszPath)
{
// 以写模式打开文件
CFile dibFile;
if(!dibFile.Open(lpszPath, CFile::modeCreate | CFile::modeReadWrite
| CFile::shareExclusive))
{
return FALSE;
}
// 记录位图文件名
strcpy(m_fileName, lpszPath);
// 将文件头结构写进文件
dibFile.Write(m_lpBmpFileHeader, sizeof(BITMAPFILEHEADER));
// 将文件信息头结构写进文件
dibFile.Write(m_lpBmpInfoHeader, sizeof(BITMAPINFOHEADER));
// 计算颜色表长度
DWORD dwRgbQuadlength = CalcRgbQuadLength();
// 如果有颜色表的话,将颜色表写进文件
if(dwRgbQuadlength != 0)
{
dibFile.Write(m_lpRgbQuad, dwRgbQuadlength);
}
// 将位图数据写进文件
DWORD dwDataSize = GetLineByte() * GetHeight();
dibFile.Write(m_lpData, dwDataSize);
// 关闭文件
dibFile.Close();
return TRUE;
}
//=======================================================
// 函数功能: 获取位图文件名
// 输入参数: 无
// 返回值: LPCTSTR-位图文件名
//=======================================================
LPCTSTR CDib::GetFileName()
{
return m_fileName;
}
//=======================================================
// 函数功能: 获取位图宽度
// 输入参数: 无
// 返回值: LONG-位图宽度
//=======================================================
LONG CDib::GetWidth()
{
return m_lpBmpInfoHeader->biWidth;
}
//=======================================================
// 函数功能: 获取位图高度
// 输入参数: 无
// 返回值: LONG-位图高度
//=======================================================
LONG CDib::GetHeight()
{
return m_lpBmpInfoHeader->biHeight;
}
//=======================================================
// 函数功能: 获取位图的宽度和高度
// 输入参数: 无
// 返回值: CSize-位图的宽度和高度
//=======================================================
CSize CDib::GetDimension()
{
return CSize(GetWidth(), GetHeight());
}
//=======================================================
// 函数功能: 获取位图大小
// 输入参数: 无
// 返回值: DWORD-位图大小
//=======================================================
DWORD CDib::GetSize()
{
if(m_lpBmpInfoHeader->biSizeImage != 0)
{
return m_lpBmpInfoHeader->biSizeImage;
}
else
{
return GetWidth() * GetHeight();
}
}
//=======================================================
// 函数功能: 获取单个像素所占位数
// 输入参数: 无
// 返回值: WORD-单个像素所占位数
//=======================================================
WORD CDib::GetBitCount()
{
return m_lpBmpInfoHeader->biBitCount;
}
//=======================================================
// 函数功能: 获取每行像素所占字节数
// 输入参数: 无
// 返回值: UINT-每行像素所占字节数
//=======================================================
UINT CDib::GetLineByte()
{
return (GetWidth() * GetBitCount() / 8 + 3) / 4 * 4;;
}
//=======================================================
// 函数功能: 获取位图颜色数
// 输入参数: 无
// 返回值: DWORD-位图颜色数
//=======================================================
DWORD CDib::GetNumOfColor()
{
UINT dwNumOfColor;
if ((m_lpBmpInfoHeader->biClrUsed == 0)
&& (m_lpBmpInfoHeader->biBitCount < 9))
{
switch (m_lpBmpInfoHeader->biBitCount)
{
case 1: dwNumOfColor = 2; break;
case 4: dwNumOfColor = 16; break;
case 8: dwNumOfColor = 256;
}
}
else
{
dwNumOfColor = m_lpBmpInfoHeader->biClrUsed;
}
return dwNumOfColor;
}
//=======================================================
// 函数功能: 计算位图颜色表长度
// 输入参数: 无
// 返回值: DWORD-位图颜色表长度
//=======================================================
DWORD CDib::CalcRgbQuadLength()
{
DWORD dwNumOfColor = GetNumOfColor();
if(dwNumOfColor > 256)
{
dwNumOfColor = 0;
}
return dwNumOfColor * sizeof(RGBQUAD);
}
//=======================================================
// 函数功能: 获取位图颜色表
// 输入参数: 无
// 返回值: LPRGBQUAD-位图颜色表指针
//=======================================================
LPRGBQUAD CDib::GetRgbQuad()
{
return m_lpRgbQuad;
}
//=======================================================
// 函数功能: 获取位图数据
// 输入参数: 无
// 返回值: LPBYTE-位图数据指针
//=======================================================
LPBYTE CDib::GetData()
{
return m_lpData;
}
//=======================================================
// 函数功能: 根据颜色表生成调色板
// 输入参数: 无
// 返回值: BOOL-TRUE 成功;FALSE 失败
//=======================================================
BOOL CDib::MakePalette()
{
// 计算颜色表长度
DWORD dwRgbQuadLength = CalcRgbQuadLength();
// 如果颜色表长度为0,则不生成逻辑调色板
if(dwRgbQuadLength == 0)
{
return FALSE;
}
//删除旧的调色板对象
if(m_hPalette != NULL)
{
DeleteObject(m_hPalette);
m_hPalette = NULL;
}
// 申请缓冲区,初始化为0
DWORD dwNumOfColor = GetNumOfColor();
DWORD dwSize = 2 * sizeof(WORD) + dwNumOfColor * sizeof(PALETTEENTRY);
LPLOGPALETTE lpLogPalette = (LPLOGPALETTE) new BYTE[dwSize];
memset(lpLogPalette, 0, dwSize);
// 生成逻辑调色板
lpLogPalette->palVersion = 0x300;
lpLogPalette->palNumEntries = dwNumOfColor;
LPRGBQUAD lpRgbQuad = (LPRGBQUAD) m_lpRgbQuad;
for(int i = 0; i < dwNumOfColor; i++)
{
lpLogPalette->palPalEntry[i].peRed = lpRgbQuad->rgbRed;
lpLogPalette->palPalEntry[i].peGreen = lpRgbQuad->rgbGreen;
lpLogPalette->palPalEntry[i].peBlue = lpRgbQuad->rgbBlue;
lpLogPalette->palPalEntry[i].peFlags = 0;
lpRgbQuad++;
}
// 创建逻辑调色板
m_hPalette = CreatePalette(lpLogPalette);
// 释放缓冲区
delete [] lpLogPalette;
return TRUE;
}
//=======================================================
// 函数功能: 显示位图
// 输入参数:
// CDC *pDC-设备环境指针
// CPoint origin-显示矩形区域的左上角
// CSize size-显示矩形区域的尺寸
// 返回值:
// BOOL-TRUE 成功;FALSE 失败
//=======================================================
BOOL CDib::Draw(CDC *pDC, CPoint origin, CSize size)
{
// 位图无效,无法绘制,返回错误
if(!IsValid())
{
return FALSE;
}
// 旧的调色板句柄
HPALETTE hOldPalette = NULL;
// 如果位图指针为空,则返回FALSE
if(m_lpDib == NULL)
{
return FALSE;
}
// 如果位图有调色板,则选进设备环境中
if(m_hPalette != NULL)
{
hOldPalette = SelectPalette(pDC->GetSafeHdc(), m_hPalette, TRUE);
}
// 设置位图伸缩模式
pDC->SetStretchBltMode(COLORONCOLOR);
// 将位图在pDC所指向的设备上进行显示
StretchDIBits(pDC->GetSafeHdc(), origin.x, origin.y, size.cx, size.cy,
0, 0, GetWidth(), GetHeight(), m_lpData, m_lpBmpInfo, DIB_RGB_COLORS, SRCCOPY);
// 恢复旧的调色板
if(hOldPalette != NULL)
{
SelectPalette(pDC->GetSafeHdc(), hOldPalette, TRUE);
}
return TRUE;
}
//=======================================================
// 函数功能: 24位彩色位图转8位灰度位图
// 输入参数: 无
// 返回值: BOOL-TRUE 成功;FALSE 失败
//=======================================================
BOOL CDib::RgbToGrade()
{
// 位图无效,失败返回
if(!IsValid())
{
return FALSE;
}
// 不是24位位图,失败返回
if(GetBitCount() != 24)
{
return FALSE;
}
// 是压缩位图,失败返回
if(m_lpBmpInfoHeader->biCompression != BI_RGB)
{
return FALSE;
}
// 如果不是灰度位图,才需要转换
if(!IsGrade())
{
// 获取原位图信息
LONG lHeight = GetHeight();
LONG lWidth = GetWidth();
UINT uLineByte = GetLineByte();
// 计算灰度位图数据所需空间
UINT uGradeBmpLineByte = (lWidth + 3) / 4 * 4;
DWORD dwGradeBmpDataSize = uGradeBmpLineByte * lHeight;
// 计算灰度位图所需空间
DWORD dwGradeBmpSize = sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * 256 + dwGradeBmpDataSize;
// 设置灰度位图文件头
LPBITMAPFILEHEADER lpGradeBmpFileHeader = (LPBITMAPFILEHEADER)new BYTE[sizeof(BITMAPFILEHEADER)];
memset(lpGradeBmpFileHeader, 0, sizeof(BITMAPFILEHEADER));
lpGradeBmpFileHeader->bfType = 0x4d42;
lpGradeBmpFileHeader->bfSize = sizeof(BITMAPFILEHEADER) + dwGradeBmpSize;
lpGradeBmpFileHeader->bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER)
+ sizeof(RGBQUAD) * 256;
lpGradeBmpFileHeader->bfReserved1 = 0;
lpGradeBmpFileHeader->bfReserved2 = 0;
// 为灰度位图分配空间,并初始化为0
LPBYTE lpGradeBmp = (LPBYTE)new BYTE[dwGradeBmpSize];
memset(lpGradeBmp, 0, dwGradeBmpSize);
// 设置灰度位图信息头
LPBITMAPINFOHEADER lpGradeBmpInfoHeader = (LPBITMAPINFOHEADER)(lpGradeBmp);
lpGradeBmpInfoHeader->biBitCount = 8;
lpGradeBmpInfoHeader->biClrImportant = 0;
lpGradeBmpInfoHeader->biClrUsed = 256;
lpGradeBmpInfoHeader->biCompression = BI_RGB;
lpGradeBmpInfoHeader->biHeight = lHeight;
lpGradeBmpInfoHeader->biPlanes = 1;
lpGradeBmpInfoHeader->biSize = sizeof(BITMAPINFOHEADER);
lpGradeBmpInfoHeader->biSizeImage = dwGradeBmpDataSize;
lpGradeBmpInfoHeader->biWidth = lWidth;
lpGradeBmpInfoHeader->biXPelsPerMeter = m_lpBmpInfoHeader->biXPelsPerMeter;
lpGradeBmpInfoHeader->biYPelsPerMeter = m_lpBmpInfoHeader->biYPelsPerMeter;
// 设置灰度位图颜色表
LPRGBQUAD lpGradeBmpRgbQuad = (LPRGBQUAD)(lpGradeBmp + sizeof(BITMAPINFOHEADER));
// 初始化8位灰度图的调色板信息
LPRGBQUAD lpRgbQuad;
for(int k = 0; k < 256; k++)
{
lpRgbQuad = (LPRGBQUAD)(lpGradeBmpRgbQuad + k);
lpRgbQuad->rgbBlue = k;
lpRgbQuad->rgbGreen = k;
lpRgbQuad->rgbRed = k;
lpRgbQuad->rgbReserved = 0;
}
// 灰度位图数据处理
BYTE r, g, b;
LPBYTE lpGradeBmpData = (LPBYTE)(lpGradeBmp + sizeof(BITMAPINFOHEADER)
+ sizeof(RGBQUAD) * 256);
// 进行颜色转换
for(int i = 0; i < lHeight; i++)
{
for(int j = 0; j < lWidth; j++)
{
b = m_lpData[i * uLineByte + 3 * j];
g = m_lpData[i * uLineByte + 3 * j + 1];
r = m_lpData[i * uLineByte + 3 * j + 2];
lpGradeBmpData[i * uGradeBmpLineByte + j] = (BYTE)(0.299 * r + 0.587 * g + 0.114 * b);
}
}
// 释放原有位图空间
Empty(FALSE);
// 重新设定原位图指针指向
m_lpBmpFileHeader = lpGradeBmpFileHeader;
m_lpDib = lpGradeBmp;
m_lpBmpInfo = (LPBITMAPINFO)(lpGradeBmp);
m_lpBmpInfoHeader = lpGradeBmpInfoHeader;
m_lpRgbQuad = lpGradeBmpRgbQuad;
m_lpData = lpGradeBmpData;
// 设置颜色表标志
m_bHasRgbQuad = TRUE;
// 设置位图有效标志
m_bValid = TRUE;
// 生成调色板
MakePalette();
}
return TRUE;
}
//=======================================================
// 函数功能: 8位灰度位图转24位彩色位图
// 输入参数: 无
// 返回值: BOOL-TRUE 成功;FALSE 失败
//=======================================================
BOOL CDib::GradeToRgb()
{
// 位图无效,失败退出
if(!IsValid())
{
return FALSE;
}
// 不是8位位图,失败退出
if(GetBitCount() != 8)
{
return FALSE;
}
// 是压缩位图,失败返回
if(m_lpBmpInfoHeader->biCompression != BI_RGB)
{
return FALSE;
}
// 是灰度图时,才需转换
if(IsGrade())
{
// 获取原位图信息
LONG lHeight = GetHeight();
LONG lWidth = GetWidth();
UINT uLineByte = GetLineByte();
// 计算彩色位图数据所需空间
UINT uColorBmpLineByte = (lWidth * 24 / 8 + 3) / 4 * 4;
DWORD dwColorBmpDataSize = uColorBmpLineByte * lHeight;
// 计算彩色位图所需空间
DWORD dwColorBmpSize = sizeof(BITMAPINFOHEADER) + dwColorBmpDataSize;
// 设置彩色位图文件头
LPBITMAPFILEHEADER lpColorBmpFileHeader = (LPBITMAPFILEHEADER)new BYTE[sizeof(BITMAPFILEHEADER)];
memset(lpColorBmpFileHeader, 0, sizeof(BITMAPFILEHEADER));
lpColorBmpFileHeader->bfType = 0x4d42;
lpColorBmpFileHeader->bfSize = sizeof(BITMAPFILEHEADER) + dwColorBmpSize;
lpColorBmpFileHeader->bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
lpColorBmpFileHeader->bfReserved1 = 0;
lpColorBmpFileHeader->bfReserved2 = 0;
// 为彩色位图分配空间,并初始化为0
LPBYTE lpColorBmp = (LPBYTE)new BYTE[dwColorBmpSize];
memset(lpColorBmp, 0, dwColorBmpSize);
// 设置彩色位图信息头
LPBITMAPINFOHEADER lpColorBmpInfoHeader = (LPBITMAPINFOHEADER)(lpColorBmp);
lpColorBmpInfoHeader->biBitCount = 24;
lpColorBmpInfoHeader->biClrImportant = 0;
lpColorBmpInfoHeader->biClrUsed = 0;
lpColorBmpInfoHeader->biCompression = BI_RGB;
lpColorBmpInfoHeader->biHeight = lHeight;
lpColorBmpInfoHeader->biPlanes = 1;
lpColorBmpInfoHeader->biSize = sizeof(BITMAPINFOHEADER);
lpColorBmpInfoHeader->biSizeImage = dwColorBmpDataSize;
lpColorBmpInfoHeader->biWidth = lWidth;
lpColorBmpInfoHeader->biXPelsPerMeter = m_lpBmpInfoHeader->biXPelsPerMeter;
lpColorBmpInfoHeader->biYPelsPerMeter = m_lpBmpInfoHeader->biYPelsPerMeter;
// 彩色位图数据处理
LPBYTE lpColorBmpData = (LPBYTE)(lpColorBmp + sizeof(BITMAPINFOHEADER));
// 进行颜色转换
for(int i = 0; i < lHeight; i++)
{
for(int j = 0; j < lWidth; j++)
{
BYTE btValue = m_lpData[i * uLineByte + j];
lpColorBmpData[i * uColorBmpLineByte + 3 * j] = btValue;
lpColorBmpData[i * uColorBmpLineByte + 3 * j + 1] = btValue;
lpColorBmpData[i * uColorBmpLineByte + 3 * j + 2] = btValue;
}
}
// 释放原有位图空间
Empty(FALSE);
// 重新设定原位图指针指向
m_lpBmpFileHeader = lpColorBmpFileHeader;
m_lpDib = lpColorBmp;
m_lpBmpInfo = (LPBITMAPINFO)(lpColorBmp);
m_lpBmpInfoHeader = lpColorBmpInfoHeader;
m_lpRgbQuad = NULL;
m_lpData = lpColorBmpData;
// 设置颜色表标志
m_bHasRgbQuad = FALSE;
// 设置位图有效标志
m_bValid = TRUE;
}
return TRUE;
}
//=======================================================
// 函数功能: 判断是否含有颜色表
// 输入参数: 无
// 返回值: 判断结果:TRUE-含有颜色表;FALSE-不含颜色表
//=======================================================
BOOL CDib::HasRgbQuad()
{
return m_bHasRgbQuad;
}
//=======================================================
// 函数功能: 判断是否是灰度图
// 输入参数: 无
// 返回值: 判断结果:TRUE-是灰度图;FALSE-是彩色图
//=======================================================
BOOL CDib::IsGrade()
{
return (GetBitCount() < 9 && GetBitCount() > 0);
}
//=======================================================
// 函数功能: 判断位图是否有效
// 输入参数: 无
// 返回值: 判断结果:TRUE-位图有效;FALSE-位图无效
//=======================================================
BOOL CDib::IsValid()
{
return m_bValid;
}
//=======================================================
// 函数功能: 清理空间
// 输入参数: BOOL bFlag-TRUE 全部清空;FALSE 部分清空
// 返回值: 无
//=======================================================
void CDib::Empty(BOOL bFlag)
{
// 文件名清空
if(bFlag)
{
strcpy(m_fileName, "");
}
// 释放位图文件头指针空间
if(m_lpBmpFileHeader != NULL)
{
delete [] m_lpBmpFileHeader;
m_lpBmpFileHeader = NULL;
}
// 释放位图指针空间
if(m_lpDib != NULL)
{
delete [] m_lpDib;
m_lpDib = NULL;
m_lpBmpInfo = NULL;
m_lpBmpInfoHeader = NULL;
m_lpRgbQuad = NULL;
m_lpData = NULL;
}
// 释放调色板
if(m_hPalette != NULL)
{
DeleteObject(m_hPalette);
m_hPalette = NULL;
}
// 设置不含颜色表
m_bHasRgbQuad = FALSE;
// 设置位图无效
m_bValid = FALSE;
}
【3】使用GDI+处理数字图像
GDI+接口时MS Whistler操作系统中的一部分,是GDI的一个新版本。
1.GDI+的新特性
与GDI相比,GDI+增加了下列的新特性:
(1)渐变画刷
(2)样条曲线
(3)持久的路径对象
(4)矩阵和矩阵变换
(5)Alpha混色
2.GDI+编程模块的变化
(1)不在使用设备环境或句柄
(2)绘图方式变化
3.Graphics绘图方法直接将Pen,Brush等对象作为自己的参数
4.不再使用“当前位置“
5.形状轮廓绘制和填充采用不同的方法
6.简化区域的创建
[例子】使用GDI+绘图
新建个mfc的单文档程序。
注意 我使用的vs2019,新建的MFC,没有stdafx.h,而是改成pch.h了
(1)添加包含文件gdiplus.h以及类库gdiplus.lib
在pch.h中添加gdiplus.h,
在链接器-输入-附加依赖项中添加gdiplus.lib,或者在pch.h中添加#pragma comment(lib,“gdiplus.lib”)
(2)app里添加变量 ULONG_PTR m_gdiplusToken;
保存GDI+被初始化后,在应用程序中的GDI+标识,以便引用该标识来调用Gdiplus::GdiplusShutdown以关闭GDI+
(3)app中添加ExitInstance的重载
Gdiplus::GdiplusShutdown(m_gdiplusToken);
return CWinApp::ExitInstance();
(4)在app的InitInstance中添加初始话GDI+的代码
CWinApp::InitInstance();
Gdiplus::GdiplusStartupInput gdiplusStartupInput;
Gdiplus::GdiplusStartup(&m_gdiplusToken,&gdiplusStartupInput,NULL);
(5)在需要绘图的窗口或者视图类中,添加GDI+的绘图代码
//添加GDI+的绘制代码
using namespace Gdiplus;
Graphics graphics(pDC->m_hDC);
Pen newPen(Color(0, 255, 0), 3);
//创建填充画刷,前景色为绿色,背景色为蓝色
HatchBrush newBrush(HatchStyleCross, Color(100, 0, 255, 0), Color(100, 0, 0, 255));
//绘制矩形
graphics.DrawRectangle(&newPen, 50, 50, 800, 600);//在(50,50)处绘制长100,高60的矩形
//填充矩形
graphics.FillRectangle(&newBrush, 50, 50, 800, 600);//在(50,50)处填充长100,高60的区域
GDI+绘制直线
void CMyView::OnDraw(CDCpDC)
{
CMyDocpDoc=GetDocument();
ASSWET_VALID(pDoc);
using namespace Gdiplus;
Graphics graphics(pDc->m_hDC);
Pen newPen(Color(255,0,0),3);//颜色,线宽度
graphics.DrawLine(&newPen,20,10,200,100);//起始点和终点坐标
}
最后
以上就是疯狂方盒为你收集整理的数字图像处理技术--学习笔记2--vc++处理数字图像的基本方法的全部内容,希望文章能够帮你解决数字图像处理技术--学习笔记2--vc++处理数字图像的基本方法所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复