求C++图像处理的程序

求C++图像处理的程序,第1张

在MFC下自己构造一个DIB类实现上述功能还是有很多现成的代码~

下面就是一个构造的DIB类,但是仅仅提供了最基本的一些 *** 作,代码来自《Visual C++数字图像处理典型算法及实现》。// DibImage.h: interface for the CDibImage class.

//

///////////////////////////////////////////////////////////银配///////////

#if !defined(AFX_DIBIMAGE_H__254F3D1E_BB20_40DA_AE07_E8E0219DFA8C__INCLUDED_)

#define AFX_DIBIMAGE_H__254F3D1E_BB20_40DA_AE07_E8E0219DFA8C__INCLUDED_

#if _MSC_VER >1000

#pragma once

#endif // _MSC_VER >1000

DECLARE_HANDLE(HDIB) // DIB句柄

#define PALVERSION 0x300 // DIB常量

/* DIB宏 */

// 判断是否是Win 3.0的DIB

#define IS_WIN30_DIB(lpbi) ((*(LPDWORD)(lpbi)) == sizeof(BITMAPINFOHEADER))

// 计算矩形区域的宽度

#define RECTWIDTH(lpRect) ((lpRect)->right - (lpRect)->left)

// 计算矩形区域的高度

#define RECTHEIGHT(lpRect)((lpRect)->bottom - (lpRect)->top)

// 在计算图像大小时,采用公式:biSizeImage = biWidth' × biHeight。

// 是biWidth',而不是biWidth,这里的biWidth'必须是4的整倍数,表示

// 大于或等于biWidth的,离4最近的整倍数。WIDTHBYTES就是用来段铅计算

// biWidth'

#define WIDTHBYTES(bits)(((bits) + 31) / 32 * 4)

// Dib文件头标志(字符串"BM",写DIB时用到该常数)

#define DIB_HEADER_MARKER ((WORD) ('M' <<8) | 'B')

class CDibImage

{

// Constructor and Destructor ///////////////////////////////

public:

CDibImage()

virtual ~CDibImage()

// function /////////////////////////////////////////////////

public:

BOOLPaintDIB (HDC, LPRECT, HDIB, LPRECT, CPalette* pPal)

BOOLCreateDIBPalette(HDIB hDIB, CPalette* cPal)

LPSTR FindDIBBits (LPSTR lpbi)

DWORD DIBWidth (LPSTR lpDIB)

DWORD DIBHeight (LPSTR lpDIB)

WORDPaletteSize (LPSTR lpbi)

WORDDIBNumColors (LPSTR lpbi)

HGLOBAL CopyHandle (HGLOBAL h)

BOOLSaveDIB (HDIB hDib, CFile&file)

HDIBReadDIBFile(CFile&file)

}

#endif // !defined(AFX_DIBIMAGE_H__254F3D1E_BB20_40DA_AE07_E8E0219DFA8C__INCLUDED_)

///////////////////////////锋燃指////////////////////////////////////////////

// DibImage.cpp: implementation of the CDibImage class.

// DIB(Independent Bitmap) 函数:

//

// PaintDIB() - 绘制DIB对象

// CreateDIBPalette() - 创建DIB对象调色板

// FindDIBBits() - 返回DIB图像象素起始位置

// DIBWidth() - 返回DIB宽度

// DIBHeight() - 返回DIB高度

// PaletteSize() - 返回DIB调色板大小

// DIBNumColors() - 计算DIB调色板颜色数目

// CopyHandle()- 拷贝内存块

//

// SaveDIB() - 将DIB保存到指定文件中

// ReadDIBFile() - 重指定文件中读取DIB对象

//////////////////////////////////////////////////////////////////////

#include "stdafx.h"

#include "DIBDisplay.h"

#include "DibImage.h"

#ifdef _DEBUG

#undef THIS_FILE

static char THIS_FILE[]=__FILE__

#define new DEBUG_NEW

#endif

//////////////////////////////////////////////////////////////////////

// Construction/Destruction

//////////////////////////////////////////////////////////////////////

CDibImage::CDibImage()

{

}

CDibImage::~CDibImage()

{

}

//////////////////////////////////////////////////////////////////////

// function

//////////////////////////////////////////////////////////////////////

/*************************************************************************

* 函数名称:

* PaintDIB()

* 参数:

* HDC hDC- 输出设备DC

* LPRECT lpDCRect- 绘制矩形区域

* HDIB hDIB - 指向DIB对象的指针

* LPRECT lpDIBRect - 要输出的DIB区域

* CPalette* pPal - 指向DIB对象调色板的指针

* 返回值:

* BOOL - 绘制成功返回TRUE,否则返回FALSE。

* 说明:

* 该函数主要用来绘制DIB对象。其中调用了StretchDIBits()或者

* SetDIBitsToDevice()来绘制DIB对象。输出的设备由由参数hDC指

* 定;绘制的矩形区域由参数lpDCRect指定;输出DIB的区域由参数

* lpDIBRect指定。

************************************************************************/

BOOL CDibImage::PaintDIB(HDC hDC,

LPRECT lpDCRect,

HDIBhDIB,

LPRECT lpDIBRect,

CPalette* pPal)

{

LPSTRlpDIBHdr // BITMAPINFOHEADER指针

LPSTRlpDIBBits // DIB象素指针

BOOL bSuccess=FALSE // 成功标志

HPALETTE hPal=NULL // DIB调色板

HPALETTE hOldPal=NULL // 以前的调色板

if (hDIB == NULL)

{

return FALSE

}

lpDIBHdr = (LPSTR)::GlobalLock((HGLOBAL) hDIB)// 锁定DIB

lpDIBBits = FindDIBBits(lpDIBHdr)// 找到DIB图像象素起始位置

if (pPal != NULL) // 获取DIB调色板,并选中它

{

hPal = (HPALETTE) pPal->m_hObject

hOldPal = ::SelectPalette(hDC, hPal, TRUE)// 选中调色板

}

::SetStretchBltMode(hDC, COLORONCOLOR) // 设置显示模式

// 判断是调用StretchDIBits()还是SetDIBitsToDevice()来绘制DIB对象

if ((RECTWIDTH(lpDCRect) == RECTWIDTH(lpDIBRect)) &&

(RECTHEIGHT(lpDCRect) == RECTHEIGHT(lpDIBRect)))

{

// 原始大小,不用拉伸。

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

0, // nStartScan

(WORD)DIBHeight(lpDIBHdr), // nNumScans

lpDIBBits, // lpBits

(LPBITMAPINFO)lpDIBHdr, // lpBitsInfo

DIB_RGB_COLORS) // wUsage

}

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

(LPBITMAPINFO)lpDIBHdr, // lpBitsInfo

DIB_RGB_COLORS, // wUsage

SRCCOPY) // dwROP

}

::GlobalUnlock((HGLOBAL) hDIB) // 解除锁定

if (hOldPal != NULL)

{

::SelectPalette(hDC, hOldPal, TRUE)// 恢复以前的调色板

}

return bSuccess

}

/*************************************************************************

* 函数名称:

* CreateDIBPalette()

* 参数:

* HDIB hDIB - 指向DIB对象的指针

* CPalette* pPal - 指向DIB对象调色板的指针

* 返回值:

* BOOL - 创建成功返回TRUE,否则返回FALSE。

* 说明:

* 该函数按照DIB创建一个逻辑调色板,从DIB中读取颜色表并存到调色板中,

* 最后按照该逻辑调色板创建一个新的调色板,并返回该调色板的句柄。这样

* 可以用最好的颜色来显示DIB图像。

************************************************************************/

BOOL CDibImage::CreateDIBPalette(HDIB hDIB, CPalette* pPal)

{

LPLOGPALETTE lpPal // 指向逻辑调色板的指针

HANDLE hLogPal // 逻辑调色板的句柄

HPALETTE hPal = NULL// 调色板的句柄

int i// 循环变量

WORD wNumColors // 颜色表中的颜色数目

LPSTR lpbi // 指向DIB的指针

LPBITMAPINFO lpbmi // 指向BITMAPINFO结构的指针(Win3.0)

LPBITMAPCOREINFO lpbmc// 指向BITMAPCOREINFO结构的指针

BOOL bWinStyleDIB // 表明是否是Win3.0 DIB的标记

BOOL bResult = FALSE// 创建结果

if (hDIB == NULL)

{

return FALSE

}

lpbi = (LPSTR) ::GlobalLock((HGLOBAL) hDIB)// 锁定DIB

lpbmi = (LPBITMAPINFO)lpbi // 获取指向BITMAPINFO结构的指针(Win3.0)

lpbmc = (LPBITMAPCOREINFO)lpbi// 获取指向BITMAPCOREINFO结构的指针

wNumColors = DIBNumColors(lpbi)// 获取DIB中颜色表中的颜色数目

if (wNumColors != 0)

{

// 分配为逻辑调色板内存

hLogPal = ::GlobalAlloc(GHND, sizeof(LOGPALETTE)

+ sizeof(PALETTEENTRY)

* wNumColors)

// 如果内存不足,退出

if (hLogPal == 0)

{

::GlobalUnlock((HGLOBAL) hDIB)// 解除锁定

return FALSE

}

lpPal = (LPLOGPALETTE) ::GlobalLock((HGLOBAL) hLogPal)

lpPal->palVersion = PALVERSION // 设置版本号

lpPal->palNumEntries = (WORD)wNumColors// 设置颜色数目

bWinStyleDIB = IS_WIN30_DIB(lpbi) // 判断是否是WIN3.0的DIB

// 读取调色板

for (i = 0i <(int)wNumColorsi++)

{

if (bWinStyleDIB)

{

// 读取红色绿色蓝色分量

lpPal->palPalEntry[i].peRed = lpbmi->bmiColors[i].rgbRed

lpPal->palPalEntry[i].peGreen = lpbmi->bmiColors[i].rgbGreen

lpPal->palPalEntry[i].peBlue = lpbmi->bmiColors[i].rgbBlue

// 保留位

lpPal->palPalEntry[i].peFlags = 0

}

else

{

// 读取红色绿色蓝色分量

lpPal->palPalEntry[i].peRed = lpbmc->bmciColors[i].rgbtRed

lpPal->palPalEntry[i].peGreen = lpbmc->bmciColors[i].rgbtGreen

lpPal->palPalEntry[i].peBlue = lpbmc->bmciColors[i].rgbtBlue

// 保留位

lpPal->palPalEntry[i].peFlags = 0

}

}

bResult = pPal->CreatePalette(lpPal)// 按照逻辑调色板创建调色板,并返回指针

::GlobalUnlock((HGLOBAL) hLogPal)// 解除锁定

::GlobalFree((HGLOBAL) hLogPal)// 释放逻辑调色板

}

::GlobalUnlock((HGLOBAL) hDIB) // 解除锁定

return bResult

}

/*************************************************************************

* 函数名称:

* FindDIBBits()

* 参数:

* LPSTR lpbi - 指向DIB对象的指针

* 返回值:

* LPSTR - 指向DIB图像象素起始位置

* 说明:

* 该函数计算DIB中图像象素的起始位置,并返回指向它的指针。

************************************************************************/

LPSTR CDibImage::FindDIBBits(LPSTR lpbi)

{

return (lpbi + *(LPDWORD)lpbi + PaletteSize(lpbi))

}

/*************************************************************************

* 函数名称:

* DIBWidth()

* 参数:

* LPSTR lpbi - 指向DIB对象的指针

* 返回值:

* DWORD - DIB中图像的宽度

* 说明:

* 该函数返回DIB中图像的宽度。对于Windows 3.0 DIB,返回BITMAPINFOHEADER

* 中的biWidth值;对于其它返回BITMAPCOREHEADER中的bcWidth值。

************************************************************************/

DWORD CDibImage::DIBWidth(LPSTR lpDIB)

{

LPBITMAPINFOHEADER lpbmi// 指向BITMAPINFO结构的指针(Win3.0)

LPBITMAPCOREHEADER lpbmc// 指向BITMAPCOREINFO结构的指针

lpbmi = (LPBITMAPINFOHEADER)lpDIB

lpbmc = (LPBITMAPCOREHEADER)lpDIB

// 返回DIB中图像的宽度

if (IS_WIN30_DIB(lpDIB))

{

return lpbmi->biWidth // 对于Windows 3.0 DIB,返回lpbmi->biWidth

}

else

{

return (DWORD)lpbmc->bcWidth// 对于其它格式的DIB,返回lpbmc->bcWidth

}

}

/*************************************************************************

* 函数名称:

* DIBHeight()

* 参数:

* LPSTR lpDIB- 指向DIB对象的指针

* 返回值:

* DWORD - DIB中图像的高度

* 说明:

* 该函数返回DIB中图像的高度。对于Windows 3.0 DIB,返回BITMAPINFOHEADER

* 中的biHeight值;对于其它返回BITMAPCOREHEADER中的bcHeight值。

************************************************************************/

DWORD CDibImage::DIBHeight(LPSTR lpDIB)

{

LPBITMAPINFOHEADER lpbmi// 指向BITMAPINFO结构的指针(Win3.0)

LPBITMAPCOREHEADER lpbmc// 指向BITMAPCOREINFO结构的指针

lpbmi = (LPBITMAPINFOHEADER)lpDIB

lpbmc = (LPBITMAPCOREHEADER)lpDIB

// 返回DIB中图像的宽度

if (IS_WIN30_DIB(lpDIB))

{

return lpbmi->biHeight // 对于Windows 3.0 DIB,返回lpbmi->biHeight

}

else

{

return (DWORD)lpbmc->bcHeight// 对于其它格式的DIB,返回lpbmc->bcHeight

}

}

/*************************************************************************

* 函数名称:

* PaletteSize()

* 参数:

* LPSTR lpbi - 指向DIB对象的指针

* 返回值:

* WORD - DIB中调色板的大小

* 说明:

* 该函数返回DIB中调色板的大小。对于Windows 3.0 DIB,返回颜色数目×

* RGBQUAD的大小;对于其它返回颜色数目×RGBTRIPLE的大小。

************************************************************************/

WORD CDibImage::PaletteSize(LPSTR lpbi)

{

// 计算DIB中调色板的大小

if (IS_WIN30_DIB (lpbi))

{

//返回颜色数目×RGBQUAD的大小

return (WORD)(DIBNumColors(lpbi) * sizeof(RGBQUAD))

}

else

{

//返回颜色数目×RGBTRIPLE的大小

return (WORD)(DIBNumColors(lpbi) * sizeof(RGBTRIPLE))

}

}

/*************************************************************************

* 函数名称:

* DIBNumColors()

* 参数:

* LPSTR lpbi - 指向DIB对象的指针

* 返回值:

* WORD - 返回调色板中颜色的种数

* 说明:

* 该函数返回DIB中调色板的颜色的种数。对于单色位图,返回2,

* 对于16色位图,返回16,对于256色位图,返回256;对于真彩色

* 位图(24位),没有调色板,返回0。

************************************************************************/

WORD CDibImage::DIBNumColors(LPSTR lpbi)

{

WORD wBitCount

// 对于Windows的DIB, 实际颜色的数目可以比象素的位数要少。

// 对于这种情况,则返回一个近似的数值。

// 判断是否是WIN3.0 DIB

if (IS_WIN30_DIB(lpbi))

{

DWORD dwClrUsed

dwClrUsed = ((LPBITMAPINFOHEADER)lpbi)->biClrUsed// 读取dwClrUsed值

if (dwClrUsed != 0)

{

// 如果dwClrUsed(实际用到的颜色数)不为0,直接返回该值

return (WORD)dwClrUsed

}

}

// 读取象素的位数

if (IS_WIN30_DIB(lpbi))

{

wBitCount = ((LPBITMAPINFOHEADER)lpbi)->biBitCount// 读取biBitCount值

}

else

{

wBitCount = ((LPBITMAPCOREHEADER)lpbi)->bcBitCount// 读取biBitCount值

}

// 按照象素的位数计算颜色数目

switch (wBitCount)

{

case 1:

return 2

break

case 4:

return 16

break

case 8:

return 256

break

default:

return 0

break

}

}

/*************************************************************************

* 函数名称:

* CopyHandle()

* 参数:

* HGLOBAL h - 要复制的内存区域

* 返回值:

* HGLOBAL- 复制后的新内存区域

* 说明:

* 该函数复制指定的内存区域。返回复制后的新内存区域,出错时返回0。

************************************************************************/

HGLOBAL CDibImage::CopyHandle (HGLOBAL h)

{

if (h == NULL)

{

return NULL

}

DWORD dwLen = ::GlobalSize((HGLOBAL) h)// 获取指定内存区域大小

HGLOBAL hCopy = ::GlobalAlloc(GHND, dwLen)// 分配新内存空间

if (hCopy != NULL) // 判断分配是否成功

{

void* lpCopy = ::GlobalLock((HGLOBAL) hCopy)

void* lp = ::GlobalLock((HGLOBAL) h)

memcpy(lpCopy, lp, dwLen)

::GlobalUnlock(hCopy)

::GlobalUnlock(h)

}

return hCopy

}

/*************************************************************************

* 函数名称:

* SaveDIB()

* 参数:

* HDIB hDib - 要保存的DIB

* CFile&file- 保存文件CFile

* 返回值:

* BOOL - 成功返回TRUE,否则返回FALSE或者CFileException

* 说明:

* 该函数将指定的DIB对象保存到指定的CFile中。该CFile由调用程序打开和关闭。

*************************************************************************/

BOOL CDibImage::SaveDIB(HDIB hDib, CFile&file)

{

BITMAPFILEHEADER bmfHdr// Bitmap文件头

LPBITMAPINFOHEADER lpBI// 指向BITMAPINFOHEADER的指针

DWORD dwDIBSize // DIB大小

if (hDib == NULL)

{

return FALSE

}

// 读取BITMAPINFO结构,并锁定

lpBI = (LPBITMAPINFOHEADER) ::GlobalLock((HGLOBAL) hDib)

if (lpBI == NULL)

{

return FALSE

}

// 判断是否是WIN3.0 DIB

if (!IS_WIN30_DIB(lpBI))

{

// 不支持其它类型的DIB保存

::GlobalUnlock((HGLOBAL) hDib)

return FALSE

}

////////////////////////////////////////////////////////////////////////

// 填充文件头///////////////////////////////////////////////////////////

bmfHdr.bfType = DIB_HEADER_MARKER // 文件类型"BM"

// 计算DIB大小时,最简单的方法是调用GlobalSize()函数。但是全局内存大小并

// 不是DIB真正的大小,它总是多几个字节。这样就需要计算一下DIB的真实大小。

// 文件头大小+颜色表大小

// (BITMAPINFOHEADER和BITMAPCOREHEADER结构的第一个DWORD都是该结构的大小)

dwDIBSize = *(LPDWORD)lpBI + PaletteSize((LPSTR)lpBI)

// 计算图像大小

if ((lpBI->biCompression == BI_RLE8) || (lpBI->biCompression == BI_RLE4))

{

// 对于RLE位图,没法计算大小,只能信任biSizeImage内的值

dwDIBSize += lpBI->biSizeImage

}

else

{

DWORD dwBmBitsSize // 象素的大小

dwBmBitsSize = WIDTHBYTES((lpBI->biWidth)*((DWORD)lpBI->biBitCount))

* lpBI->biHeight // 大小为Width * Height

dwDIBSize += dwBmBitsSize// 计算出DIB真正的大小

// 更新biSizeImage(很多BMP文件头中biSizeImage的值是错误的)

lpBI->biSizeImage = dwBmBitsSize

}

// 计算文件大小:DIB大小+BITMAPFILEHEADER结构大小

bmfHdr.bfSize = dwDIBSize + sizeof(BITMAPFILEHEADER)

// 两个保留字

bmfHdr.bfReserved1 = 0

bmfHdr.bfReserved2 = 0

// 计算偏移量bfOffBits,它的大小为Bitmap文件头大小+DIB头大小+颜色表大小

bmfHdr.bfOffBits = (DWORD)sizeof(BITMAPFILEHEADER) + lpBI->biSize

+ PaletteSize((LPSTR)lpBI)

/////////////////////////////////////////////////////////////////////////

// 尝试写文件////////////////////////////////////////////////////////////

TRY

{

file.Write((LPSTR)&bmfHdr, sizeof(BITMAPFILEHEADER))// 写文件头

file.WriteHuge(lpBI, dwDIBSize)// 写DIB头和象素

}

CATCH (CFileException, e)

{

::GlobalUnlock((HGLOBAL) hDib)

THROW_LAST()

}

END_CATCH

::GlobalUnlock((HGLOBAL) hDib)

return TRUE

}

/*************************************************************************

* 函数名称:

* ReadDIBFile()

* 参数:

* CFile&file- 要读取得文件文件CFile

* 返回值:

* HDIB - 成功返回DIB的句柄,否则返回NULL。

* 说明:

* 该函数将指定的文件中的DIB对象读到指定的内存区域中。除BITMAPFILEHEADER

* 外的内容都将被读入内存。

*************************************************************************/

HDIB CDibImage::ReadDIBFile(CFile&file)

{

BITMAPFILEHEADER bmfHeader

HDIB hDIB

LPSTR pDIB

DWORD dwBitsSize

dwBitsSize = file.GetLength() // 获取DIB(文件)长度(字节)

// 尝试读取DIB文件头

if (file.Read((LPSTR)&bmfHeader, sizeof(bmfHeader)) != sizeof(bmfHeader))

{

return NULL

}

// 判断是否是DIB对象,检查头两个字节是否是"BM"

if (bmfHeader.bfType != DIB_HEADER_MARKER)

{

return NULL

}

// 为DIB分配内存

hDIB = (HDIB) ::GlobalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT, dwBitsSize)

if (hDIB == 0)

{

return NULL

}

pDIB = (LPSTR) ::GlobalLock((HGLOBAL) hDIB)

if (file.ReadHuge(pDIB, dwBitsSize - sizeof(BITMAPFILEHEADER)) !=

dwBitsSize - sizeof(BITMAPFILEHEADER) ) // 读象素

{

::GlobalUnlock((HGLOBAL) hDIB)

::GlobalFree((HGLOBAL) hDIB)

return NULL

}

::GlobalUnlock((HGLOBAL) hDIB)

return hDIB

}

.旋转图像(含对话框 这里对话框需要自己建立) void CCimageProcessingView::OnGeomRota() { //获取指向文档的指针 CCimageProcessingDoc* pDoc = GetDocument()//指向DIB的指针 LPSTR lpDIB//锁定DIB lpDIB = (LPSTR) ::GlobalLock((HGLOBAL) pDoc->GetHDIB())// 缩放比率兆册含 int iRotaAngle// 创建对话框 CDlgGeoRota dlgPara// 初始化变量值 dlgPara.m_iRotaAngle = 90/姿李/ 显示对话框,提示用户设定旋转角度 if (dlgPara.DoModal() != IDOK) { // 返回 return} // 获取用户设定的平移量 iRotaAngle = dlgPara.m_iRotaAngle// 删除对话框 delete dlgPara//创建新DIB HDIB hNewDIB=NULL//设置光标状态为等待状态 BeginWaitCursor()//调用RotateDIB函数旋转族笑DIB图象 hNewDIB=(HDIB)::RotateDIB(lpDIB,iRotaAngle)//旋转成功 if (hNewDIB) { //替换原来的DIB图象为新的DIB pDoc->ReplaceHDIB(hNewDIB)//更新DIB图象的大小和调色板 pDoc->InitDIBData()//设置文档修改标记 pDoc->SetModifiedFlag(TRUE)//调节滚动视图大小 SetScrollSizes(MM_TEXT,pDoc->GetDocSize())//更新所有视图 pDoc->UpdateAllViews(NULL)} else { //提示信息 MessageBox("实现图象旋转失败!")} //解除锁定 ::GlobalUnlock((HGLOBAL) pDoc->GetHDIB())//结束光标等待状态 EndWaitCursor()} /************************************************************************* * * 函数名称: * * RotateDIB () * * 参数: * * LPSTR lpDIB //指向源DIB图像指针 * * int iAngle * 说明: * * 该函数用来实现DIB图像的旋转。 * ************************************************************************/ HGLOBAL WINAPI RotateDIB(LPSTR lpDIB,int iAngle) { //原图象宽度 LONG lWidth//原图象高度 LONG lHeight//旋转后图象宽度 LONG lNewWidth//旋转后图象高度 LONG lNewHeight//原图象的颜色数 WORD wNumColors//原图象的信息头结构指针 LPBITMAPINFOHEADER lpbmi,lpbmi0//指向原图象和目的图象的像素的指针 LPBYTE lpSrc,lpDst//指向原图像像素的指针 LPBYTE lpDIBBits//指向旋转后图像(像素)的指针 LPBYTE lpNewDIBBitsLPSTR lpNewDIB//旋转后新的DIB句柄 HDIB hDIB

#include <windows.h>

//读bmp图片需要两个结构

#pragma pack(push, enter_defBM, 1) //指定内存对齐单位为1。

typedef struct tagBmpFileHeader

{

WORD  bfType      // 文件类型  BM

DWORD bfSize      // 文件大小

WORD  bfReserved1 // 保留字

WORD  bfReserved2 // 保留字

DWORD bfOffBits   // 位图的数据信息离文件头的偏移量枣郑

} BFH

typedef struct tagBmpImgHeader

{

DWORD biSize          // 表示本结构的大小,0X28

LONG  biWidth         // 位图的宽度

LONG  biHeight        // 位图的高度

WORD  biPlanes      行烂  // 位面数永远为1

WORD  biBitCount      // 位图的位数

DWORD biCompression   // 压缩类型

DWORD biSizeImage     // 表示位图数据区域的大小

LONG  biXPelsPerMeter // 表示显示设备的水平分辨率

LONG  biYPelsPerMeter // 表示显示设备的垂直分辨率

DWORD biClrUsed       // 实际使用的颜色数目

DWORD biClrImportant  // 重要的颜色数量

} BIH

#pragma pack(pop, enter_defBM) //恢复默认内存对齐单位。

#define HDIB HANDLE // 位图句柄

DWORD WINAPI DIBNumColors(BYTE * data)

{

WORD wBitCount

DWORD dwClrUsed = ((BIH *)data)->biClrUsed

if (dwClrUsed != 0) return (WORD)dwClrUsed

wBitCount = ((BIH *)data)->biBitCount

return 1 << wBitCount

}

WORD WINAPI PaletteSize(BYTE * data)

{

return (WORD)(::DIBNumColors(data) * sizeof(RGBQUAD))

BYTE *  WINAPI FindDIBBits(BYTE * data)

{

return (data + *(DWORD *)data + ::PaletteSize(data))

}

// 获取Bmp的宽档岩漏度

DWORD FAR DIBWidth(const BYTE * data)   

{   

BIH * pbmi

pbmi = (BIH *)data 

if(pbmi->biSize == sizeof(BIH)) return pbmi->biWidth

else return -1

}   

// 获取Bmp的高度

DWORD FAR DIBHeight(const BYTE * data)   

{   

BIH * pbmi

pbmi = (BIH *)data 

if(pbmi->biSize == sizeof(BIH)) return pbmi->biHeight

else return -1

}   

// 从文件读取Bmp图像数据

HDIB WINAPI ReadDIBFile(FILE * fp)

{

BFH    bmf

HDIB   hDIB

BYTE * pData

rewind(fp)

if(fread(&bmf, sizeof(BFH), 1, fp) != 1) return NULL // 文件读取错误

if(bmf.bfType != 19778) return NULL                  // 文件类型错误

hDIB = (HDIB) ::GlobalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT, bmf.bfSize) // 为DIB分配内存

if (hDIB == 0) return NULL                           // 内存分配失败。

pData = (BYTE *)::GlobalLock((HGLOBAL) hDIB)         // 锁定

if(fread(pData, 1, bmf.bfSize - sizeof(BFH), fp) != (bmf.bfSize - sizeof(BFH))) // 文件读取错误

{

::GlobalUnlock((HGLOBAL) hDIB) // 解除锁定

::GlobalFree((HGLOBAL) hDIB)   // 释放内存

return NULL

}

::GlobalUnlock((HGLOBAL) hDIB)     // 解除锁定

return hDIB                        // 返回DIB句柄

}

BOOL WINAPI PaintDIB(HDC hDC, int posX, int posY, HDIB hDIB)

{

BYTE *   pDIBHd             // BITMAPINFOHEADER指针

BYTE *   pDIBBits           // DIB象素指针

BOOL     bSuccess = FALSE   // 成功标志

HPALETTE hPal     = NULL    // DIB调色板

//HPALETTE hOldPal  = NULL    // 以前的调色板

if (hDIB == NULL) return FALSE                    // 判断DIB对象是否为空

pDIBHd    = (BYTE *) ::GlobalLock((HGLOBAL) hDIB) // 锁定DIB

pDIBBits  = ::FindDIBBits(pDIBHd)                 // 找到DIB图像象素起始位置

::SetStretchBltMode(hDC, COLORONCOLOR)            // 设置显示模式

    // 调用SetDIBitsToDevice()来绘制DIB对象

bSuccess = ::SetDIBitsToDevice(hDC, // hDC

           posX, posY, 

   ((BIH *)pDIBHd)->biWidth,    // nDestWidth

   ((BIH *)pDIBHd)->biHeight,   // nDestHeight

           0,                           // SrcX

           0,                           // SrcY

           0,                           // nStartScan

           (WORD)DIBHeight(pDIBHd),     // nNumScans

           pDIBBits,                    // lpBits

           (LPBITMAPINFO)pDIBHd,        // lpBitsInfo

           DIB_RGB_COLORS)             // wUsage

::GlobalUnlock((HGLOBAL) hDIB)     // 解除锁定

return bSuccess

}

// 打印位图信息

VOID WINAPI PrintDIBInfo(HDIB hDIB)

{

BYTE *   pDIBHd = (BYTE *)::GlobalLock((HGLOBAL) hDIB)

BIH *    pbmi   = (BIH *)pDIBHd

const char *lp[] = 

{

"位图信息长度: %d\n",

"位图图像大小: %dx%d\n",

"位面数:%d\n",

"位图颜色深度: %d\n",

"位图数据压缩类型: %d\n",

"位图数据区域大小: %d\n",

"位图分辨率: 水平 %d dpi, 垂直 %d dpi\n",

}

printf("Windows V3 cBitmapInfoHeader 信息\n\n")

printf(lp[0], pbmi->biSize)

printf(lp[1], pbmi->biWidth, pbmi->biHeight)

printf(lp[2], pbmi->biPlanes)

printf(lp[3], pbmi->biBitCount)

printf(lp[4], pbmi->biCompression)

printf(lp[5], pbmi->biSizeImage)

printf(lp[6], (LONG)(pbmi->biXPelsPerMeter * 0.0254f + 0.5f), (LONG)(pbmi->biYPelsPerMeter * 0.0254f + 0.5f))

::GlobalUnlock((HGLOBAL) hDIB)     // 解除锁定

}

int main(int argc, char* argv[])

{

HDIB x

FILE * fp = fopen("1.bmp", "rb")

if(fp==NULL) return -1

x = ReadDIBFile(fp)

printf("DIB handle %u", x)

PaintDIB(GetDC(NULL), 0, 0, x)

PrintDIBInfo(x)

return 0

}


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/yw/12468595.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-25
下一篇 2023-05-25

发表评论

登录后才能评论

评论列表(0条)

保存