📄 image.cpp
字号:
// Image.cpp: implementation of the CImage class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "Image.h"
// access()
#include "io.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CImage::CImage()
{
hBitmap = NULL;
hPal = NULL;
hDib = NULL;
nImgType = 0;
}
CImage::~CImage()
{
// 释放资源
if ( hBitmap ) {
DeleteObject( hBitmap );
hBitmap = NULL;
}
if ( hPal ) {
DeleteObject( hPal );
hPal = NULL;
}
if ( hDib ) {
GlobalFree( hDib );
hDib = NULL;
}
}
// 从文件中读取图像
BOOL CImage::LoadFile(HWND hwnd, LPCTSTR lpfilename)
{
CFile file;
if ( !file.Open(lpfilename, CFile::modeRead) ) {
MessageBox(hwnd, "打开文件错误!","警告", 0);
return FALSE;
}
// 得到文件头信息
memset( &bmfh, 0, sizeof(BITMAPFILEHEADER) );
file.Read( &bmfh, sizeof(BITMAPFILEHEADER) );
// 读取图像信息
BITMAPINFOHEADER bih;
file.Read( &bih, sizeof(BITMAPINFOHEADER) );
nBits = bih.biBitCount;
nWidth = bih.biWidth;
nHeight = bih.biHeight;
nWidthBytes = WIDTHBYTES(nBits*nWidth);
nColors = bih.biClrUsed ? bih.biClrUsed : (1<<nBits);
if( nBits==24 || nBits==32 )
nColors=0;
if( bmfh.bfOffBits != (DWORD)(sizeof(bmfh) + sizeof(bih) + nColors*sizeof(RGBQUAD)))
{
MessageBox(hwnd, "打开文件错误!", "警告", 0);
goto errProc;
}
DWORD dwImagesize;
dwImagesize = nWidthBytes*nHeight;
hDib = (HDIB)::GlobalAlloc(GHND, sizeof(BITMAPINFOHEADER)
+ nColors*sizeof(RGBQUAD) + dwImagesize);
if ( hDib == NULL )
{
MessageBox(hwnd, "分配内存错误!", "警告", 0);
goto errProc;
}
LPBYTE lptemp;
lptemp = (LPBYTE)::GlobalLock((HGLOBAL)hDib);
if ( lptemp == NULL )
{
MessageBox(hwnd, "分配内存错误!", "警告", 0);
goto errProc;
}
file.Seek(sizeof(BITMAPFILEHEADER), CFile::begin);
if(file.ReadHuge((LPVOID)lptemp,sizeof(bih)+nColors*sizeof(RGBQUAD)
+dwImagesize) != (sizeof(bih)+nColors*sizeof(RGBQUAD)
+dwImagesize))
{
MessageBox(hwnd,"打开文件错误!","警告",0);
goto errProc;
}
// 关闭文件
file.Close();
// 读取调色板信息
if ( nColors != 0 )
{
int nPalSize;
nPalSize = sizeof(LOGPALETTE)+nColors*sizeof(PALETTEENTRY);
LOGPALETTE *ppal;
ppal = (LOGPALETTE *)(new BYTE[nPalSize]);
if ( ppal == NULL )
{
MessageBox(hwnd,"分配内存错误!","警告",0);
goto errProc;
}
RGBQUAD * lprgb;
lprgb = (RGBQUAD *)((LPBYTE)lptemp + (DWORD)sizeof(bih));
ppal->palVersion = 0x030;
ppal->palNumEntries = nColors;
for (int i=0; i<nColors; i++)
{
ppal->palPalEntry[i].peBlue = lprgb->rgbBlue;
ppal->palPalEntry[i].peGreen = lprgb->rgbGreen;
ppal->palPalEntry[i].peRed = lprgb->rgbRed;
ppal->palPalEntry[i].peFlags = 0;
lprgb++;
}
hPal = CreatePalette( ppal );
delete [] ppal;
}
// 把调色板信息读入设备环境
{
HDC hdc = GetDC( hwnd );
HPALETTE prePal = NULL;
if ( hPal )
{
prePal = SelectPalette(hdc, hPal, FALSE);
RealizePalette( hdc );
}
// 创建BITMAP资源
hBitmap = CreateDIBitmap(hdc, &bih, (long)CBM_INIT,
(LPBYTE)lptemp+sizeof(bih)+sizeof(RGBQUAD)*nColors,
(LPBITMAPINFO)lptemp, DIB_RGB_COLORS);
//
if ( hPal && prePal )
{
hPal = SelectPalette(hdc, prePal, FALSE);
RealizePalette(hdc);
// ??? 这儿是否要释放资源
//DeleteObject( prePal );
}
ReleaseDC(hwnd, hdc);
}
return TRUE;
errProc:
if ( hBitmap ) {
DeleteObject( hBitmap );
hBitmap = NULL;
}
if ( hPal ) {
DeleteObject( hPal );
hPal = NULL;
}
if ( lptemp ) {
GlobalUnlock( hDib );
lptemp = NULL;
}
if ( hDib ) {
GlobalFree( hDib );
hDib = NULL;
}
file.Close();
return FALSE;
}
LPBYTE CImage::FindDibBits()
{
if ( hDib == NULL )
return NULL;
LPBYTE lptemp;
lptemp = (LPBYTE)GlobalLock( (HGLOBAL)hDib );
if ( lptemp == NULL )
return NULL;
LPBYTE lpret;
lpret = lptemp + sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD)*nColors;
GlobalUnlock( (HGLOBAL)hDib );
return lpret;
}
BOOL CImage::DrawDIB(HDC hdc, HDIB hdib, CPalette *pPal)
{
if( hDib == NULL )
return FALSE;
if ( pPal == NULL )
{
if ( hPal == NULL )
hPal = (HPALETTE)GetStockObject(DEFAULT_PALETTE);
SelectPalette(hdc, hPal, FALSE);
RealizePalette(hdc);
}
else
{
SelectPalette(hdc,(HPALETTE)(pPal->m_hObject),FALSE);
RealizePalette(hdc);
}
LPBYTE lptemp;
lptemp = (LPBYTE)GlobalLock( (HGLOBAL)hDib );
if ( lptemp == NULL )
return FALSE;
SetDIBitsToDevice(hdc, 0, 0, nWidth, nHeight, 0, 0, 0, nHeight,
(LPBYTE)lptemp+sizeof(BITMAPINFOHEADER)+sizeof(RGBQUAD)*nColors,
(LPBITMAPINFO)lptemp, DIB_RGB_COLORS);
GlobalUnlock( (HGLOBAL)hDib );
return TRUE;
}
BOOL CImage::DrawDDB(HDC hdc, HBITMAP bmp, HPALETTE hpal)
{
if ( hBitmap == NULL )
return FALSE;
if ( hpal == NULL )
hPal = (HPALETTE)GetStockObject(DEFAULT_PALETTE);
HDC hmemdc;
hmemdc = CreateCompatibleDC( hdc );
SelectPalette(hdc, hpal, FALSE);
SelectPalette(hmemdc, hpal, FALSE);
RealizePalette(hdc);
SelectObject(hmemdc, bmp);
BitBlt(hdc, 0, 0, nWidth, nHeight, hmemdc, 0, 0, SRCCOPY);
DeleteDC( hmemdc );
return TRUE;
}
// 从文件中读取图像
BOOL CImage::Load(LPCTSTR lpszPathName)
{
// 判断文件是否存在
if ( access(lpszPathName,0) != 0 )
return FALSE;
HWND hWnd = (HWND)AfxGetMainWnd()->m_hWnd;
// 读取文件信息及数据
HGLOBAL hGlobal = NULL;
nImgType = FileType( lpszPathName );
switch ( nImgType )
{
case 0: //NA
return FALSE;
break;
case 1: //BMP
GetBMPInfo( lpszPathName, &nWidth, &nHeight, &nPlanes, &nBits, &nColors);
nWidthBytes = WIDTHBYTES( nBits*nWidth );
hGlobal = LoadBMP( lpszPathName );
break;
case 2: //GIF
GetGIFInfo( lpszPathName, &nWidth, &nHeight, &nPlanes, &nBits, &nColors);
nWidthBytes = WIDTHBYTES( nBits*nWidth );
hGlobal = LoadGIF( lpszPathName );
break;
case 3: //PCX
GetPCXInfo( lpszPathName, &nWidth, &nHeight, &nPlanes, &nBits, &nColors);
nWidthBytes = WIDTHBYTES( nBits*nWidth );
hGlobal = LoadPCX( lpszPathName );
break;
case 4: //TGA
GetTGAInfo( lpszPathName, &nWidth, &nHeight, &nPlanes, &nBits, &nColors);
nWidthBytes = WIDTHBYTES( nBits*nWidth );
hGlobal = LoadTGA( lpszPathName );
break;
case 5: //JPG
GetJPGInfo( lpszPathName, &nWidth, &nHeight, &nPlanes, &nBits, &nColors);
nWidthBytes = WIDTHBYTES( nBits*nWidth );
hGlobal = LoadJPG( lpszPathName );
break;
case 6: //TIF
GetTIFInfo( lpszPathName, &nWidth, &nHeight, &nPlanes, &nBits, &nColors);
nWidthBytes = WIDTHBYTES( nBits*nWidth );
hGlobal = LoadTIF( lpszPathName );
break;
default:
return FALSE;
}
if( hGlobal == NULL )
{
MessageBox(hWnd, "读取文件错误!", "警告", 0);
return FALSE;
}
// 24位、32位真彩图像不需要调色板
if( nBits==24 || nBits==32 )
nColors=0;
LPBYTE lpGlobal;
lpGlobal = (LPBYTE)::GlobalLock( (HGLOBAL)hGlobal );
if ( lpGlobal == NULL )
{
MessageBox(hWnd, "分配内存错误!", "警告", 0);
goto errProc;
}
// 得到文件头信息
memset( &bmfh, 0, sizeof(BITMAPFILEHEADER) );
memcpy( &bmfh, lpGlobal, sizeof(BITMAPFILEHEADER) );
DWORD dwImagesize;
dwImagesize = nWidthBytes*nHeight;
dwImagesize += sizeof(BITMAPINFOHEADER);
dwImagesize += nColors*sizeof(RGBQUAD);
hDib = (HDIB)::GlobalAlloc(GHND, dwImagesize);
if ( hDib == NULL )
{
MessageBox(hWnd, "分配内存错误!", "警告", 0);
goto errProc;
}
LPBYTE lptemp;
lptemp = (LPBYTE)::GlobalLock((HGLOBAL)hDib);
if ( lptemp == NULL )
{
MessageBox(hWnd, "分配内存错误!", "警告", 0);
goto errProc;
}
// 拷贝图像数据(不包括文件头信息)
lpGlobal += sizeof(BITMAPFILEHEADER);
memcpy( lptemp, lpGlobal, dwImagesize);
// 释放资源
GlobalUnlock( hGlobal );
GlobalFree( hGlobal );
BITMAPINFOHEADER bih;
memcpy( &bih, lptemp, sizeof(BITMAPINFOHEADER) );
// 读取调色板信息
if ( nColors != 0 )
{
int nPalSize;
nPalSize = sizeof(LOGPALETTE)+nColors*sizeof(PALETTEENTRY);
LOGPALETTE *ppal;
ppal = (LOGPALETTE *)(new BYTE[nPalSize]);
if ( ppal == NULL )
{
MessageBox(hWnd,"分配内存错误!","警告",0);
goto errProc;
}
RGBQUAD * lprgb;
lprgb = (RGBQUAD *)((LPBYTE)lptemp + (DWORD)sizeof(BITMAPINFOHEADER));
ppal->palVersion = 0x030;
ppal->palNumEntries = nColors;
for (int i=0; i<nColors; i++)
{
ppal->palPalEntry[i].peBlue = lprgb->rgbBlue;
ppal->palPalEntry[i].peGreen = lprgb->rgbGreen;
ppal->palPalEntry[i].peRed = lprgb->rgbRed;
ppal->palPalEntry[i].peFlags = 0;
lprgb++;
}
hPal = CreatePalette( ppal );
delete [] ppal;
}
// 把调色板信息读入设备环境
{
HDC hdc = GetDC( hWnd );
HPALETTE prePal = NULL;
if ( hPal )
{
prePal = SelectPalette(hdc, hPal, FALSE);
RealizePalette( hdc );
}
// 创建BITMAP资源
hBitmap = CreateDIBitmap(hdc, &bih, (long)CBM_INIT,
(LPBYTE)lptemp+sizeof(bih)+sizeof(RGBQUAD)*nColors,
(LPBITMAPINFO)lptemp, DIB_RGB_COLORS);
//
if ( hPal && prePal )
{
hPal = SelectPalette(hdc, prePal, FALSE);
RealizePalette(hdc);
// ??? 这儿是否要释放资源
//DeleteObject( prePal );
}
ReleaseDC(hWnd, hdc);
}
return TRUE;
errProc:
if ( hBitmap ) {
DeleteObject( hBitmap );
hBitmap = NULL;
}
if ( hPal ) {
DeleteObject( hPal );
hPal = NULL;
}
if ( lptemp ) {
GlobalUnlock( hDib );
lptemp = NULL;
}
if ( hDib ) {
GlobalFree( hDib );
hDib = NULL;
}
if ( lpGlobal ) {
GlobalUnlock( hGlobal );
lpGlobal = NULL;
}
if ( hGlobal ) {
GlobalFree( hGlobal );
hGlobal = NULL;
}
return FALSE;
}
// 保存图像
BOOL CImage::Save(LPCTSTR lpszPathName, int nType)
{
HGLOBAL hGlobal = NULL;
LPBYTE lpNewBuffer = NULL;
LPBYTE lpOldBuffer = NULL;
HWND hWnd = (HWND)AfxGetMainWnd()->m_hWnd;
DWORD dwImagesize;
dwImagesize = nWidthBytes*nHeight;
dwImagesize += sizeof(BITMAPFILEHEADER);
dwImagesize += sizeof(BITMAPINFOHEADER);
dwImagesize += nColors*sizeof(RGBQUAD);
hGlobal = (HGLOBAL)::GlobalAlloc(GHND, dwImagesize);
if ( hGlobal == NULL )
{
MessageBox(hWnd, "内存分配错误!", "失败", 0);
return FALSE;
}
lpNewBuffer = (LPBYTE)::GlobalLock( hGlobal );
if ( lpNewBuffer == NULL )
{
MessageBox(hWnd, "内存分配错误!", "失败", 0);
::GlobalFree( hGlobal );
return FALSE;
}
lpOldBuffer = (LPBYTE)::GlobalLock( hDib );
if ( lpOldBuffer == NULL )
{
MessageBox(hWnd, "内存分配错误!", "失败", 0);
goto errProc;
}
// 拷贝文件头信息和图像数据至新分配内存
memcpy ( lpNewBuffer, &bmfh, sizeof(BITMAPFILEHEADER) );
dwImagesize =nWidthBytes*nHeight;// nWidthBytes*nHeight;
dwImagesize += sizeof(BITMAPINFOHEADER);
dwImagesize += nColors*sizeof(RGBQUAD);
memcpy (&lpNewBuffer[sizeof(BITMAPFILEHEADER)], lpOldBuffer, dwImagesize );
// 释放资源
GlobalUnlock( hDib );
lpOldBuffer = NULL;
GlobalUnlock( hGlobal );
lpNewBuffer = NULL;
switch ( nType )
{
case 0:
MessageBox(hWnd, "不支持此文件格式!", "提示", 0);
goto errProc;
break;
case 1:
if ( !SaveBMP(lpszPathName, hGlobal) )
{
MessageBox(hWnd, "保存BMP图像失败!", "提示", 0);
goto errProc;
}
break;
case 2:
if ( !SaveGIF(lpszPathName, hGlobal) )
{
MessageBox(hWnd, "保存GIF图像失败!", "提示", 0);
goto errProc;
}
break;
case 3:
if ( !SavePCX(lpszPathName, hGlobal) )
{
MessageBox(hWnd, "保存PCX图像失败!", "提示", 0);
goto errProc;
}
break;
case 4:
if ( !SaveTGA(lpszPathName, hGlobal) )
{
MessageBox(hWnd, "保存TGA图像失败!", "提示", 0);
goto errProc;
}
break;
case 5:
if ( !SaveJPG(lpszPathName, hGlobal, 50) )
{
MessageBox(hWnd, "保存JPEG图像失败!", "提示", 0);
goto errProc;
}
break;
case 6:
if ( !SaveTIF(lpszPathName, hGlobal) )
{
MessageBox(hWnd, "保存TIFF图像失败!", "提示", 0);
goto errProc;
}
break;
default:
MessageBox(hWnd, "不支持此文件格式!", "提示", 0);
goto errProc;
break;
}
// 释放资源
GlobalFree( hGlobal );
hGlobal = NULL;
return TRUE;
errProc:
if ( lpOldBuffer ) {
GlobalUnlock( hDib );
lpOldBuffer = NULL;
}
if ( lpNewBuffer ) {
GlobalUnlock( hGlobal );
lpNewBuffer = NULL;
}
if ( hGlobal ) {
GlobalFree( hGlobal );
hGlobal = NULL;
}
return FALSE;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -