?? myimage.cpp
字號:
// MyImage.cpp: implementation of the CMyImage class.
/********************************************************************************
//圖像處理類--主要是圖像讀取顯示保存
---沒有處理調色板-對256以下圖像繪制存在問題
// Written by: YiJian Feng
// Email: netfyee@hotmail.com
// Last Edit: 2003-9-5
**********************************************************************************/
#include "stdafx.h"
#include "MyImage.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CMyImage::CMyImage()
{
hImage = NULL;
memset(&m_bih, 0, 40);
}
//根據HBITMAP(DDB位圖)產生Image
CMyImage::CMyImage(HBITMAP hBitmap)
{
memset(&m_bih, 0, 40);
IMAGE_ERROR err = LoadDDB(hBitmap);
}
//根據HDIB(DIB位圖)產生Image
CMyImage::CMyImage(HDIB hDib)
{
memset(&m_bih, 0, 40);
IMAGE_ERROR err = LoadDIB(hDib);
}
//根據 圖像字節流 產生Image/
//其中iMode有三種方式 =0 包括BITMAPFILEHEADER+BITMAPINFOHEADER+圖像字節;
//1包括BITMAPINFOHEADER+圖像字節;
//2圖像字節;但這時必須調用SetDibInfo()來設置位圖信息;
CMyImage::CMyImage(PBYTE pImage, DWORD dwSize, int iMode)
{
memset(&m_bih, 0, 40);
IMAGE_ERROR err = LoadBuf(pImage, dwSize, iMode);
}
//根據 文件來 產生 Image
CMyImage::CMyImage(CString FileName)
{
memset(&m_bih, 0, 40);
IMAGE_ERROR err = LoadFile(FileName);
}
CMyImage::~CMyImage()
{
DeleteObject();
}
//刪除圖像Image對象
IMAGE_ERROR CMyImage::DeleteObject()
{
if(hImage)
{
GlobalFree(hImage);
hImage = NULL;
}
return IMAGE_OK;
}
//是否是空對象
BOOL CMyImage::IsEmpty()
{
if(hImage)
return TRUE;
else
return FALSE;
}
IMAGE_ERROR CMyImage::CreateObject(DWORD dwSize)
{
IMAGE_ERROR err = DeleteObject();
if (err!=IMAGE_OK)
return err;
hImage = ::GlobalAlloc(GHND/*GMEM_FIXED*/, dwSize);
if(hImage)
return IMAGE_OK;
else
return IMAGE_ERR_CREATE;
}
//加載DDB位圖
IMAGE_ERROR CMyImage::LoadDDB(HBITMAP hBitmap)
{
BITMAP bitmap;
WORD biBits; // 象素位數
UINT wLineLen; // 行長度
DWORD wColSize; // 調色板大小
DWORD dwSize; // 文件長度 --=&&=--
DWORD wImageSize; // 圖像大小
PBYTE p1 = NULL;
// 計算位圖文件每個像素所占字節數
::GetObject(hBitmap, sizeof(BITMAP), &bitmap);
biBits = (WORD)(bitmap.bmPlanes * bitmap.bmBitsPixel);
wLineLen = WIDTHBYTES(bitmap.bmWidth * biBits);//(bitmap.bmWidth * biBits + 31 ) / 32 * 4;
wColSize = sizeof(RGBQUAD) * (( biBits <= 8 ) ? 1 << biBits : 0 );
dwSize = sizeof(BITMAPINFOHEADER) + wColSize +
(DWORD)(UINT)wLineLen * (DWORD)(UINT)bitmap.bmHeight;
wImageSize = dwSize - sizeof(BITMAPINFOHEADER) - wColSize;
if (biBits <= 1)
{
biBits = 1;
}
else if (biBits <= 4)
{
biBits = 4;
}
else if (biBits <= 8)
{
biBits = 8;
}
else
{
biBits = 24;
}
// 初始分配
IMAGE_ERROR err = CreateObject(dwSize + sizeof(BITMAPFILEHEADER));
if(err != IMAGE_OK)
return err;
// hglobal = ::GlobalAlloc(GHND, dwSize + 14);
// m_hglobal = (HGLOBAL)::GlobalLock(hglobal);
BITMAPINFOHEADER bih;
BITMAPFILEHEADER bfh;
// 建立文件頭信息
::memset(&bfh, 0, sizeof(BITMAPFILEHEADER));
bfh.bfType = 'MB';
bfh.bfSize = dwSize + sizeof(BITMAPFILEHEADER);
bfh.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
p1 = (PBYTE)::GlobalLock(hImage);
if (!p1)
return IMAGE_ERR_LOCK;
::memcpy(p1, &bfh, sizeof(BITMAPFILEHEADER));
// 建立位圖頭信息
::memset(&bih, 0, sizeof(BITMAPINFOHEADER));
bih.biSize = sizeof(BITMAPINFOHEADER);
bih.biWidth = bitmap.bmWidth;
bih.biHeight = bitmap.bmHeight;
bih.biPlanes = 1;
bih.biBitCount = biBits;
bih.biCompression = BI_RGB;
bih.biSizeImage = wImageSize;
bih.biXPelsPerMeter = 0;
bih.biYPelsPerMeter = 0;
bih.biClrUsed = ( biBits <= 8 ) ? 1 << biBits : 0;
bih.biClrImportant = 0;
::memcpy(p1 + sizeof(BITMAPINFOHEADER), &bih, sizeof(BITMAPINFOHEADER));
//set dib
memcpy(&m_bih, &bih, sizeof(BITMAPINFOHEADER));
// 建立位圖體信息
::memcpy(p1 + bfh.bfOffBits, bitmap.bmBits, wImageSize);
BOOL a = GlobalUnlock(hImage);
/*win98下不需要判斷
if(!a)
return IMAGE_ERR_UNLOCK;
*/
return IMAGE_OK;
}
//加載DDB位圖
IMAGE_ERROR CMyImage::LoadDDB(CBitmap *pBitmap)
{
return LoadDDB( (HBITMAP)(pBitmap->GetSafeHandle()) );
}
IMAGE_ERROR CMyImage::LoadDIB(HDIB hDib)
{
LPBYTE lpdib;
LPBITMAPINFOHEADER lpbih;
BITMAPFILEHEADER bfh;
// 計算位圖信息
lpdib =(LPBYTE)::GlobalLock(hDib);
if( !lpdib )
return IMAGE_ERR_LOCK;
lpbih = (LPBITMAPINFOHEADER)lpdib;
DWORD dwImageSize = lpbih->biSizeImage;
// 建立文件頭信息
::memset(&bfh, 0, 14);
bfh.bfType = 'MB';
bfh.bfSize = dwImageSize + 54; // dwSize + 14;
bfh.bfOffBits = 54;
IMAGE_ERROR err = CreateObject(dwImageSize + 54);
if(err != IMAGE_OK)
{
BOOL b = ::GlobalUnlock(hDib);
/*win98下必須去除
if(!b)
return IMAGE_ERR_UNLOCK;
*/
return err;
}
PBYTE p1 = NULL;
p1 = (PBYTE)::GlobalLock(hImage);
if(!p1)
{
BOOL b = ::GlobalUnlock(hDib);
/*win98下必須去除
if(!b)
return IMAGE_ERR_UNLOCK;
*/
return IMAGE_ERR_LOCK;
}
memcpy(p1, &bfh, 14);
// 建立位圖頭并位圖體信息
memcpy(p1 + 14, lpdib, dwImageSize + 40);
//set dib
memcpy(&m_bih, lpbih, sizeof(BITMAPINFOHEADER));
BOOL b = ::GlobalUnlock(hDib);
/*win98下必須去除
if(!b)
return IMAGE_ERR_UNLOCK;
*/
// 解鎖
b = ::GlobalUnlock(hImage);
/*win98下必須去除
if(!b)
return IMAGE_ERR_UNLOCK;
*/
return IMAGE_OK;
}
//獲得圖像尺寸
IMAGE_ERROR CMyImage::ImageSize(int& dwWidth, int &dwHeight)
{
dwWidth = 0; dwHeight = 0;
if(!hImage)
return IMAGE_NULL;
else
{
LPSTR lpDIBHdr; // Pointer to BITMAPINFOHEADER
LPBYTE lpImage = NULL;
LPBITMAPINFOHEADER lpbmi; // pointer to a Win 3.0-style DIB
LPBITMAPCOREHEADER lpbmc; // pointer to an other-style DIB
// point to the header (whether old or Win 3.0
lpImage = (LPBYTE) ::GlobalLock(hImage);
if (!lpImage)
return IMAGE_ERR_LOCK;
lpDIBHdr = LPSTR(lpImage + 14);
lpbmi = (LPBITMAPINFOHEADER)lpDIBHdr;
lpbmc = (LPBITMAPCOREHEADER)lpDIBHdr;
// return the DIB height if it is a Win 3.0 DIB
if (IS_WIN30_DIB(lpDIBHdr))
{
dwHeight = lpbmi->biHeight;
dwWidth = lpbmi->biWidth;
}
else // it is an other-style DIB, so return its height
{
dwHeight = lpbmc->bcHeight;
dwWidth = lpbmc->bcWidth;
}
BOOL b = ::GlobalUnlock(hImage);
/*win98下必須去除
if(!b)
return IMAGE_ERR_UNLOCK;
*/
}
return IMAGE_OK;
}
//從文件加載圖像
IMAGE_ERROR CMyImage::LoadFile(CString FileName)
{
ASSERT(!FileName.IsEmpty());
IMAGE_ERROR err = IMAGE_OK;
CFile file;
CFileException fe;
if (!file.Open(FileName, CFile::modeRead | CFile::shareDenyNone , &fe))
{
// MessageBox(NULL,"無法讀取文件!","錯誤",MB_ICONSTOP);
return IMAGE_ERR_FILENOTEXIST;
}
CString m_strName=FileName;
CString m_strFileExt=FileName.Right(3);
m_strFileExt.MakeUpper();
if(m_strFileExt=="BMP")
{
TRY
{
err = LoadFile(file);
if( err != IMAGE_OK )
{
file.Close();
return err;
}
}
CATCH (CFileException, eLoad)
{
file.Abort(); // will not throw an exception
return IMAGE_ERR_READFILE;
}
END_CATCH
}
else if(m_strFileExt=="JPG")
{
// file.Close();
err = LoadJPG(FileName);
if(err != IMAGE_OK)
return err;
}
else
{
file.Close();
return IMAGE_ERR_FILENOTEXIST;
}
file.Close();
return IMAGE_OK;
}
//讀位圖BMP文件
IMAGE_ERROR CMyImage::LoadFile(CFile &file)
{
BITMAPFILEHEADER bmfHeader;
LPBITMAPINFOHEADER lpbmi=NULL; // pointer to a Win 3.0-style DIB
LPBITMAPINFO lpbmifo=NULL;
BITMAPINFO BitmapInfo;
LPBYTE pDIB=NULL;
// Get length of DIB in bytes for use when reading
DWORD m_dwBitsSize = file.GetLength()-sizeof(BITMAPFILEHEADER);
// Go read the DIB file header and check if it's valid.
if(file.Read((LPSTR)&bmfHeader, sizeof(bmfHeader)) != sizeof(bmfHeader))
return IMAGE_ERR_READFILE;
if (bmfHeader.bfType != DIB_HEADER_MARKER)
return IMAGE_ERR_READFILE;
if(file.Read((LPSTR)&BitmapInfo, sizeof(BitmapInfo)) != sizeof(BitmapInfo))
return IMAGE_ERR_READFILE;
//set dib
memcpy(&m_bih, &(BitmapInfo.bmiHeader), sizeof(BITMAPINFOHEADER));
if(BitmapInfo.bmiHeader.biBitCount!=24)
{
// MessageBox(NULL,"讀取圖像文件錯誤,目前只支持24位真彩色圖像。","讀取圖像文件錯誤",MB_OK|MB_ICONERROR);
return IMAGE_ERR_RGB;
}
DWORD dwWidth=BitmapInfo.bmiHeader.biWidth;
DWORD dwHeight=BitmapInfo.bmiHeader.biHeight;
DWORD dwWidthOfByte=WIDTHBYTES(dwWidth*24);
DWORD dwTemp=dwWidthOfByte*dwHeight+sizeof(BITMAPINFOHEADER);
if(dwTemp>m_dwBitsSize)
m_dwBitsSize=dwTemp;
DWORD dwDibOffset=bmfHeader.bfOffBits;
IMAGE_ERROR err = CreateObject(m_dwBitsSize + 14);
if(err != IMAGE_OK)
return err;
}
// Allocate memory for DIB
// m_hDIB = (HDIB)::GlobalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT,m_dwBitsSize );
//Allocate memory error
// if (m_hDIB == NULL) return FALSE;
PBYTE aa = NULL;
aa =(PBYTE)::GlobalLock(hImage);
if(!aa)
return IMAGE_ERR_LOCK;
memcpy(aa, &bmfHeader, 14);
// memcpy(aa + 14, &(BitmapInfo->bmiHeader), 40);
pDIB = aa + 14;
//Point to BITMAPINFOHEADER structure
lpbmi=(LPBITMAPINFOHEADER)pDIB;
lpbmifo=(LPBITMAPINFO)pDIB;
// m_lpBitmapInfoHeader=(LPBITMAPINFOHEADER)pDIB;
file.Seek(sizeof(BITMAPFILEHEADER),CFile::begin);
// Go read the bits.
if(file.ReadHuge(pDIB, m_dwBitsSize)!=m_dwBitsSize)
{
BOOL b = ::GlobalUnlock(hImage);
/*win98下不能使用
if(!b)
return IMAGE_ERR_UNLOCK;
*/
err = DeleteObject();
if(err != IMAGE_OK)
return err;
return IMAGE_ERR_READFILE;
}
if(lpbmi->biCompression!=BI_RGB)
{
BOOL b = ::GlobalUnlock(hImage);
/*win98下不能使用
if(!b)
return IMAGE_ERR_UNLOCK;
*/
err = DeleteObject();
if(err != IMAGE_OK)
return err;
return IMAGE_ERR_RGB;
// return FALSE;
}
BOOL b = ::GlobalUnlock(hImage);
/*win98下不能使用
if(!b)
return IMAGE_ERR_UNLOCK;
*/
return IMAGE_OK;
}
//讀JPG圖像文件
IMAGE_ERROR CMyImage::LoadJPG(CString FileName)
{
IMAGE_ERROR err = DeleteObject();
if( err!= IMAGE_OK)
return err;
hImage=::LoadJPG(LPCTSTR(FileName));
if(hImage==NULL)
return IMAGE_ERR_IMAGELOAD_READ;
PBYTE lp = NULL;
lp = (LPBYTE)::GlobalLock(hImage);
if(!lp)
{
return IMAGE_ERR_LOCK;
}
//set dib
memcpy(&m_bih, lp + 14, sizeof(BITMAPINFOHEADER));
BOOL b = ::GlobalUnlock(hImage);
/*win98下不能使用
if(!b)
return IMAGE_ERR_UNLOCK;
*/
return IMAGE_OK;
}
IMAGE_ERROR CMyImage::LoadBuf(PBYTE pImage, DWORD dwSize, int iMode)
{
if(!pImage)
return IMAGE_NULL;
IMAGE_ERROR err = DeleteObject();
if (err != IMAGE_OK)
return err;
BOOL b = FALSE;
PBYTE p = NULL;
BITMAPFILEHEADER bfh;
switch(iMode) {
case 0:
err = CreateObject(dwSize);
if( err != IMAGE_OK)
return err;
p = (LPBYTE)::GlobalLock(hImage);
if(!p)
return IMAGE_ERR_LOCK;
memcpy(p, pImage, dwSize);
//set dib
memcpy(&m_bih, pImage + 14, sizeof(BITMAPINFOHEADER));
b = ::GlobalUnlock(hImage);
/*win98下禁止使用
if(!b)
return IMAGE_ERR_UNLOCK;*/
break;
case 1:
err = CreateObject(dwSize + 14);
if( err != IMAGE_OK)
return err;
memset(&bfh, 0, sizeof(bfh));
bfh.bfType = 'MB';
bfh.bfOffBits = 54;
bfh.bfSize = dwSize + 14;
p = (PBYTE)::GlobalLock(hImage);
if(!p)
return IMAGE_ERR_LOCK;
memcpy(p, &bfh, sizeof(bfh));
memcpy(p + 14, pImage, dwSize);
//set dib
memcpy(&m_bih, pImage, sizeof(BITMAPINFOHEADER));
b = ::GlobalUnlock(hImage);
/*win98下禁止使用
if(!b)
return IMAGE_ERR_UNLOCK;*/
break;
default:
if (m_bih.biWidth == 0 )
return IMAGE_ERR_INFOHEADER;
err = CreateObject(dwSize + 54);
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -