📄 dib.cpp
字号:
#include "stdafx.h"
#include "Dib.h"
#include <io.h>
#include <math.h>
#include "fstream.h"
#pragma warning(disable:4244)
static DWORD dwDibOffset=0;
/////////////////////////////////////////////////////////////////////
// CDIB
//动态创建二维数组
template <class T>
void Make2DArray(T** &X,int rows,int cols)
{
X=new T*[rows];
for(int i=0;i<rows;i++)
X[i]=new T[cols];
}
//释放动态创建的二维数组
template <class T>
void Delete2DArray(T** &X,int rows)
{
for(int i=0;i<rows;i++)
delete []X[i];
delete []X;
X=0;
}
CDIB::CDIB()
{
m_hDIB=NULL;m_pPal=NULL;
m_nWidth=m_nHeight=1;
m_nWidthOfByte=1;
m_dwBitsSize=0;
}
CDIB::CDIB(CString csFileName)
{
ASSERT(!csFileName.IsEmpty());
m_hDIB=NULL;m_pPal=NULL;
m_nWidth=m_nHeight=1;
m_nWidthOfByte=1;
CFile file;
CFileException fe;
if (!file.Open(csFileName, CFile::modeRead | CFile::shareDenyNone , &fe))
{
// MessageBox(NULL,"无法读取文件!","错误",MB_ICONSTOP);
return;
}
m_strName=csFileName;
m_strFileExt=csFileName.Right(3);
m_strFileExt.MakeUpper();
if(m_strFileExt=="BMP")
{
TRY
{
if(!ReadDIBFile(file)) return ;
}
CATCH (CFileException, eLoad)
{
file.Abort(); // will not throw an exception
return ;
}
END_CATCH
}
else
LoadJPG(csFileName);
}
CDIB::CDIB(const CDIB& Dib)
{
m_hDIB=NULL;m_pPal=NULL;
m_nWidth=m_nHeight=1;
m_nWidthOfByte=1;
m_dwBitsSize=::GlobalSize(Dib.m_hDIB);
m_hDIB = (HDIB)::GlobalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT,m_dwBitsSize);
if(m_hDIB ==NULL)
{
// MessageBox(NULL,"无法分配内存空间!","错误",MB_ICONSTOP);
return;
}
LPSTR lpSour,lpDest;
lpSour=(LPSTR)::GlobalLock(Dib.m_hDIB);
lpDest=(LPSTR)::GlobalLock(m_hDIB);
memcpy(lpDest,lpSour,m_dwBitsSize);
m_nWidth=Dib.m_nWidth;
m_nHeight=Dib.m_nHeight;
m_nWidthOfByte=Dib.m_nWidthOfByte;
m_lpBitmapInfoHeader=(LPBITMAPINFOHEADER)lpDest;
m_lpDIB=(lpDest+ *(LPDWORD)lpDest+PaletteSize(lpDest));
m_pPal=NULL;
::GlobalUnlock(m_hDIB);
::GlobalUnlock(Dib.m_hDIB);
}
CDIB::CDIB(const CDIB* Dib)
{
m_hDIB=NULL;m_pPal=NULL;
m_nWidth=m_nHeight=1;
m_nWidthOfByte=1;
m_dwBitsSize=0;
m_dwBitsSize=::GlobalSize(Dib->m_hDIB);
m_hDIB = (HDIB)::GlobalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT,m_dwBitsSize);
LPSTR lpSour,lpDest;
lpSour=(LPSTR)::GlobalLock(Dib->m_hDIB);
lpDest=(LPSTR)::GlobalLock(m_hDIB);
memcpy(lpDest,lpSour,m_dwBitsSize);
m_nWidth=Dib->m_nWidth;
m_nHeight=Dib->m_nHeight;
m_nWidthOfByte=Dib->m_nWidthOfByte;
m_lpBitmapInfoHeader=(LPBITMAPINFOHEADER)lpDest;
m_lpDIB=(lpDest+ *(LPDWORD)lpDest+PaletteSize(lpDest));
m_pPal=NULL;
::GlobalUnlock(m_hDIB);
::GlobalUnlock(Dib->m_hDIB);
}
BOOL CDIB::Create(CString name)
{
m_strName=name;
// if(!ReadDIBFile()) return(FALSE);
m_nWidth=DIBWidth();
m_nHeight=DIBHeight();
return(TRUE);
}
CDIB::~CDIB()
{
DeleteObject();
}
void CDIB::DeleteObject()
{
if(m_hDIB!=NULL) GlobalFree(m_hDIB);m_hDIB=NULL;
if(m_pPal!=NULL) delete m_pPal;m_pPal=NULL;
m_nWidth=m_nHeight=1;
m_nWidthOfByte=1;
m_lpDIB=NULL;
m_lpbi=NULL;
}
/*************************************************************************\
* Function : ConvertTo24()
* Purpose : Convert bitmap to 24 RGB color.
* Returns : TRUE if successful.FALSE if an error occurs.
\*************************************************************************/
BOOL CDIB::Convert2TrueColor()
{
LPBITMAPINFOHEADER lpBMIH,lpOldHeader;
LPBITMAPINFO lpbmi;
LPSTR lpDib,lpTemp,lpIndex;
LPSTR lpRGB;
HDIB hDIB;
const RED=2;
const GREEN=1;
const BLUE=0;
int Width;
int Height;
int nBytesPerLine_Sour,nBytesPerLine_Dest;
int nColorUsed=0;
int nBitCount=0;
m_nWidth=DIBWidth();m_nHeight=DIBHeight();
Width=m_nWidth;
Height=m_nHeight;
lpDib =(LPSTR)::GlobalLock((HGLOBAL)m_hDIB);
lpbmi = (LPBITMAPINFO)lpDib;
nColorUsed=lpbmi->bmiHeader.biClrUsed;
nBitCount =lpbmi->bmiHeader.biBitCount;
nBytesPerLine_Sour=WIDTHBYTES(nBitCount*m_nWidth);
nBytesPerLine_Dest=WIDTHBYTES(24*m_nWidth);
//得到像素的字节大小
hDIB = (HDIB)::GlobalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT,
sizeof(BITMAPINFOHEADER)+nBytesPerLine_Dest*Height);
//If allocate memory error
if(hDIB==NULL) return FALSE;
//Go scratch...
lpTemp=(LPSTR)::GlobalLock((HGLOBAL)hDIB);
//Point to old BITMAPINFOHEADER structure
lpBMIH = (LPBITMAPINFOHEADER)lpTemp;
lpOldHeader = (LPBITMAPINFOHEADER)lpDib;
//Change flag to CHANGFLAG,such as 8 ,24 etc.
lpBMIH->biSize=sizeof(BITMAPINFOHEADER);
lpBMIH->biWidth=Width;
lpBMIH->biHeight=Height;
lpBMIH->biPlanes=1;
lpBMIH->biBitCount = 24;
lpBMIH->biCompression=BI_RGB;
lpBMIH->biSizeImage =0;
lpBMIH->biXPelsPerMeter=0;
lpBMIH->biYPelsPerMeter=0;
lpBMIH->biClrUsed=0;
lpBMIH->biClrImportant=0;
//Point to destination memory
lpRGB=LPSTR(lpTemp+*(LPDWORD)lpTemp);
//Let me point to the index of palatte table
// if(nColorUsed!=0 )//&& lpbmi->bmiHeader.biBitCount<16)
// lpIndex=(lpDib + *(LPDWORD)lpDib +(nColorUsed*4));
// else if(nBitCount==8)
// lpIndex=(lpDib + *(LPDWORD)lpDib + 256*4);
// else if(nBitCount==4)
// lpIndex=(lpDib + *(LPDWORD)lpDib + 16*4);
// else if(nBitCount==1)
// lpIndex=(lpDib + *(LPDWORD)lpDib + 2*4);
lpIndex=(lpDib+dwDibOffset-sizeof(BITMAPFILEHEADER));
//(2<<(lpbmi->bmiHeader.biBitCount-1))*4);
//Fill with R、G、B elements
DWORD wDestPos=0;
unsigned char byIndex=0;
try
{
if(nBitCount==8)
{
for(int i=0;i<Height;i++)
for(int j=0;j<Width;j++)
{
byIndex=*(LPBYTE)(lpIndex+i*nBytesPerLine_Sour+j);
wDestPos=i*nBytesPerLine_Dest+j*3;
*(lpRGB+wDestPos+RED)=lpbmi->bmiColors[byIndex].rgbRed;
*(lpRGB+wDestPos+GREEN)=lpbmi->bmiColors[byIndex].rgbGreen ;
*(lpRGB+wDestPos+BLUE)=lpbmi->bmiColors[byIndex].rgbBlue ;
}
}
else if(nBitCount==4)
{
for(int i=0;i<Height;i++)
for(int j=0;j<Width;j++)
{
byIndex=*(LPBYTE)((lpIndex+(i*nBytesPerLine_Sour+j)));
wDestPos=i*nBytesPerLine_Dest+j*3*2;
unsigned char Low,High;
High=(byIndex&0xF0)>>4;
Low =(byIndex&0x0F);
*(lpRGB+wDestPos+RED)=lpbmi->bmiColors[High].rgbRed;
*(lpRGB+wDestPos+GREEN)=lpbmi->bmiColors[High].rgbGreen ;
*(lpRGB+wDestPos+BLUE)=lpbmi->bmiColors[High].rgbBlue ;
wDestPos+=3;
*(lpRGB+wDestPos+RED)=lpbmi->bmiColors[Low].rgbRed;
*(lpRGB+wDestPos+GREEN)=lpbmi->bmiColors[Low].rgbGreen ;
*(lpRGB+wDestPos+BLUE)=lpbmi->bmiColors[Low].rgbBlue ;
}
}
else if(nBitCount==1)
{
for(int i=0;i<Height;i++)
for(int j=0;j<Width;j++)
{
byIndex=*(LPBYTE)((lpIndex+(i*nBytesPerLine_Sour+j)));
wDestPos=i*nBytesPerLine_Dest+j*12;
BOOL Bit;
for(int k=0;k<8;k++)
{
Bit=(byIndex>>k)&0X0001;
*(lpRGB+wDestPos+RED)=lpbmi->bmiColors[Bit].rgbRed;
*(lpRGB+wDestPos+GREEN)=lpbmi->bmiColors[Bit].rgbGreen ;
*(lpRGB+wDestPos+BLUE)=lpbmi->bmiColors[Bit].rgbBlue ;
wDestPos+=3;
}
}
}
}
catch(...)
{
//e->ReportError();
::GlobalUnlock((HGLOBAL)hDIB);
::GlobalFree((HGLOBAL)hDIB);
return false;
};
::GlobalUnlock((HGLOBAL)m_hDIB);
::GlobalFree((HGLOBAL)m_hDIB);
m_hDIB=hDIB;
::GlobalUnlock((HGLOBAL)hDIB);
return TRUE;
}
/*************************************************************************
* Function: ReadDIBFile()
* Purpose: Reads in the specified DIB file into a global chunk of memory.
* Returns: TRUE if successful.FALSE if an error occurs.
* Comments: BITMAPFILEHEADER is stripped off of the DIB. Everything
* from the end of the BITMAPFILEHEADER structure on is
* read into the global memory handle.
*************************************************************************/
BOOL CDIB::ReadDIBFile(CFile& file)
{
BITMAPFILEHEADER bmfHeader;
LPBITMAPINFOHEADER lpbmi; // pointer to a Win 3.0-style DIB
LPBITMAPINFO lpbmifo;
BITMAPINFO BitmapInfo;
LPSTR pDIB;
// Get length of DIB in bytes for use when reading
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 FALSE;
if (bmfHeader.bfType != DIB_HEADER_MARKER)
return FALSE;
if(file.Read((LPSTR)&BitmapInfo, sizeof(BitmapInfo)) != sizeof(BitmapInfo))
return FALSE;
if(BitmapInfo.bmiHeader.biBitCount!=24)
{
MessageBox(NULL,"读取图像文件错误,目前只支持24位真彩色图像。","读取图像文件错误",MB_OK|MB_ICONERROR);
return FALSE;
}
m_nWidth=BitmapInfo.bmiHeader.biWidth;
m_nHeight=BitmapInfo.bmiHeader.biHeight;
m_nWidthOfByte=WIDTHBYTES(m_nWidth*24);
DWORD dwTemp=m_nWidthOfByte*m_nHeight+sizeof(BITMAPINFOHEADER);
if(dwTemp>m_dwBitsSize)
m_dwBitsSize=dwTemp;
dwDibOffset=bmfHeader.bfOffBits;
// Allocate memory for DIB
m_hDIB = (HDIB)::GlobalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT,m_dwBitsSize );
//Allocate memory error
if (m_hDIB == NULL) return FALSE;
pDIB =(LPSTR)::GlobalLock((HGLOBAL)m_hDIB);
//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)
{
::GlobalUnlock((HGLOBAL)m_hDIB);
::GlobalFree((HGLOBAL)m_hDIB);
return FALSE;
}
if(lpbmi->biCompression!=BI_RGB)
{
::GlobalUnlock((HGLOBAL)m_hDIB);
::GlobalFree((HGLOBAL)m_hDIB);
return FALSE;
}
m_lpDIB=(pDIB+ sizeof(BITMAPINFOHEADER));
::GlobalUnlock((HGLOBAL)m_hDIB);
return TRUE;
}
BOOL CDIB::ReadDIBFile(CString csFileName)
{
ASSERT(!csFileName.IsEmpty());
m_hDIB=NULL;m_pPal=NULL;
m_nWidth=m_nHeight=1;
m_nWidthOfByte=1;
CFile file;
CFileException fe;
if (!file.Open(csFileName, CFile::modeRead | CFile::shareDenyNone , &fe))
{
// AfxMessageBox("无法读取文件!"+csFileName);
return FALSE;
}
m_strName=csFileName;
m_strFileExt=csFileName.Right(3);
m_strFileExt.MakeUpper();
if(m_strFileExt=="BMP")
{
TRY
{
if(!ReadDIBFile(file))
return FALSE;
}
CATCH (CFileException, eLoad)
{
file.Abort(); // will not throw an exception
return FALSE;
}
END_CATCH
}
else
LoadJPG(csFileName);
return TRUE;
}
/*************************************************************************
* Function: CreateDIBPalette()
* Description: This function creates a palette from the DIB by allocating
* memory for the logical palette, reading and storing the
* colors from the DIB's color table into the logical palette,
* creating a palette from this logical palette, and then
* returning the palette's handle. This allows the DIB to be
* displayed using the best possible colors (important for
* DIBs with 256 or more colors).
*************************************************************************/
//DEL BOOL CDIB::CreateDIBPalette()
//DEL {
//DEL HANDLE hLogPal; // handle to a logical palette
//DEL int i; // loop index
//DEL WORD wNumColors; // number of colors in color table
//DEL LPSTR lpbi; // pointer to packed-DIB
//DEL LPBITMAPINFO lpbmi; // pointer to BITMAPINFO structure (Win3.0)
//DEL LPBITMAPCOREINFO lpbmc; // pointer to BITMAPCOREINFO structure (old)
//DEL BOOL bWinStyleDIB; // flag which signifies whether this is a Win3.0 DIB
//DEL BOOL bResult = FALSE;
//DEL
//DEL if(m_pPal!=NULL) delete m_pPal;m_pPal=NULL;
//DEL // if handle to DIB is invalid, return FALSE
//DEL if(m_hDIB == NULL) return FALSE;
//DEL
//DEL lpbi = (LPSTR) ::GlobalLock((HGLOBAL) m_hDIB);
//DEL // get pointer to BITMAPINFO (Win 3.0)
//DEL lpbmi = (LPBITMAPINFO)lpbi;
//DEL // get pointer to BITMAPCOREINFO (old 1.x)
//DEL lpbmc = (LPBITMAPCOREINFO)lpbi;
//DEL // get the number of colors in the DIB
//DEL wNumColors =DIBNumColors(lpbi);
//DEL
//DEL if (wNumColors != 0)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -