📄 image.cpp
字号:
long biWidth;
long biHeight;
ASSERT(m_dwLength == 0L); // DIB must be empty
if ((pFile->Read((BYTE*)&bmfHdr, sizeof(bmfHdr)) !=
sizeof(bmfHdr))) {
//AfxMessageBox("Read error");
return FALSE;
}
if (bmfHdr.bfType != 0x4d42)
{
//AfxMessageBox("Invalid bitmap file");
return FALSE;
}
//1999.4.9 added
if ((pFile->Read((BYTE*)&bmhdr, sizeof(bmhdr)) !=
sizeof(bmhdr))) {
//AfxMessageBox("Read error");
return FALSE;
}
if(bmhdr.biSize != sizeof(bmhdr))
{
//AfxMessageBox("Invalid bitmap file");
return FALSE;
}
if(bmhdr.biBitCount == 16 && bmhdr.biBitCount == 32)
{
//AfxMessageBox("Sorry! Current version only support\n 8bpp and 24bpp BMP!");
return FALSE;
}
if(bmhdr.biCompression != BI_RGB )
{
//AfxMessageBox("Sorry! Current version do NOT support\n compressed BMP!");
return FALSE;
}
biWidth = bmhdr.biWidth;
biHeight= abs(bmhdr.biHeight);
DWORD dwBytes = ByteNumForOneLine(WORD(biWidth), bmhdr.biBitCount);
//->|
m_dwLength = pFile->GetLength();
m_dwLength -= sizeof(BITMAPFILEHEADER);
/*1999.4.9 added the following line*/
//add the needed extent memory!!!
m_dwLength += (dwBytes - (bmhdr.biBitCount / 8) * bmhdr.biWidth) * bmhdr.biHeight;
if (!AllocateMemory()) {
return FALSE;
}
pFile->Seek(sizeof(BITMAPFILEHEADER), CFile::begin);
TRY {
pFile->Read(m_pDib, m_dwLength);
}
CATCH (CFileException, e) {
AfxMessageBox("Read error");
delete []m_pDib; // free the DIB memory
return FALSE;
}
END_CATCH
m_pData = (BYTE*) m_pDib + sizeof(BITMAPINFOHEADER) +
sizeof(RGBQUAD) * NumColors();
CreateDIBPalette();
SetDIB();
return TRUE;
}
BOOL CImage::ReadFromPGM(CFile * pFile)
{
// file assumed to be open
LPBITMAPINFOHEADER pBMIH;
char ch;
WORD w, h, i=0, j=0;
char str[10];
CString sfilehead;
ASSERT(m_dwLength == 0);
DWORD dwFileLength = pFile->GetLength();
DWORD dwDataPos=0;
pFile->Seek(0,CFile::begin);
TRY {
pFile->Read(sfilehead.GetBuffer(100), 100);
}
CATCH (CFileException, e) {
AfxMessageBox("Read error");
return FALSE;
}
END_CATCH
sfilehead.ReleaseBuffer();
if(sfilehead == "") {
AfxMessageBox("Invalid PGM image file");
return false;
}
if(sfilehead.GetAt(0) != 'P'||sfilehead.GetAt(1) != '5') {
AfxMessageBox("Invalid PGM image file");
return false;
}
int tt = 0; dwDataPos = 0;
while(tt != 4)//4: for YaleFaceBaseB, 3: for others
{
if(sfilehead.GetAt(dwDataPos) == '\n')
tt++;
dwDataPos++;
if(dwDataPos > 100)
{
AfxMessageBox("The format is wrong!");
return false;
}
}
dwFileLength -= dwDataPos;
i=0; ch=sfilehead.GetAt(i++);
while(ch!='\n') ch=sfilehead.GetAt(i++);
//for Yale FaceBaseB only
ch=sfilehead.GetAt(i++);
while(ch!='\n') ch=sfilehead.GetAt(i++);
j=0; ch=sfilehead.GetAt(i++);
while(ch!=' ')
{ str[j++]=ch; ch=sfilehead.GetAt(i++);}
str[j]='\0'; w=atoi(str);
j=0; ch=sfilehead.GetAt(i++);
while(ch!='\n')
{str[j++]=ch; ch=sfilehead.GetAt(i++);}
str[j]='\0'; h=atoi(str);
if( DWORD(w*h) > dwFileLength)
{
AfxMessageBox("w*h != DataLength, The image data is wrong!");
return false;
}
//make the number of bytes in one line can be divided exactly by 4
DWORD dwBytes = Transform(w);//bytes per line
m_dwLength = DWORD(dwBytes * h) + sizeof(BITMAPINFOHEADER)
+ sizeof(RGBQUAD) * 256;
if (!AllocateMemory()) {
AfxMessageBox("Allocmemory Error");
return FALSE;}
pBMIH=BMInfoHdPtr();
pBMIH->biSize = sizeof(BITMAPINFOHEADER);
pBMIH->biWidth = w;
pBMIH->biHeight = h;
pBMIH->biPlanes = 1;
pBMIH->biBitCount = 8;
pBMIH->biCompression = BI_RGB;
pBMIH->biSizeImage = 0;
pBMIH->biXPelsPerMeter = 0;
pBMIH->biYPelsPerMeter = 0;
pBMIH->biClrUsed = 0;
pBMIH->biClrImportant = 0;
m_pData = (BYTE*) m_pDib + sizeof(BITMAPINFOHEADER) +
sizeof(RGBQUAD) * NumColors();
pFile->Seek(dwDataPos/*+1 980518 modified!!*/,CFile::begin);
long dd;
TRY {
dd = pFile->Read(m_pData, DWORD(w * h));
//pFile->Read(m_pData, dwFileLength);
}
CATCH (CFileException, e) {
AfxMessageBox("Read error");
delete []m_pDib; // free the DIB memory
return FALSE; }
END_CATCH
CreateGreyPalette();
SetDIB(FALSE);
Dib();
return TRUE;
}
BOOL CImage::WriteAsPGM(CFile * pFile)
{
WORD w, h;
char cWidth[5];
char cHeight[5];
char* PgmHead = new char[30];
Data();
strcpy(PgmHead, "P5\n");
if (m_pDib == NULL)
return FALSE;
if(Bits() != 8)
{
AfxMessageBox("It is not 8-greylevel image!");
return false; }
w = Width(); h = Height();
itoa(w,cWidth,10); itoa(h,cHeight,10);
strcat(PgmHead,cWidth); strcat(PgmHead," ");
strcat(PgmHead,cHeight); strcat(PgmHead,"\n255\n");
// Calculate the file size by adding the DIB size to sizeof(BITMAPFILEHEADER)
WORD hdLength = sizeof(BITMAPINFOHEADER)
+ NumColors()*sizeof(RGBQUAD);
TRY {
pFile->Write(PgmHead,strlen(PgmHead));
pFile->Write(m_pData, (long)w*h);
}
CATCH (CFileException, e) {
AfxMessageBox("Write error--possible disk full condition");
return FALSE;
}
END_CATCH
Dib();
delete PgmHead;
return TRUE;
}
BOOL CImage::WriteAsData(CFile* pFile)
{
WORD w = Width();
WORD h = Height();
BYTE* pData = Data();
TRY
{
pFile->Write(pData, (long)w*h);
}
CATCH (CFileException, e)
{
AfxMessageBox("Write error--possible disk full condition");
return FALSE;
}
END_CATCH
Dib();
return TRUE;
}
BOOL CImage::ReadFromFile(CFile * pFile)
{
//if(ReadFromDAT(pFile))
// return TRUE;
BOOL bReturn;
CString FileName=pFile->GetFilePath();
int nPointPos=FileName.Find(".");
FileName.MakeLower();
FileName=FileName.Mid(nPointPos+1);
bReturn = FALSE;
if(FileName=="bmp")
return ReadFromBMP(pFile);
if(FileName=="pgm")
return ReadFromPGM(pFile);
if(FileName == "img")
return ReadFromIMG(pFile);
if(FileName == "dat")
return ReadFromDAT(pFile);
if(FileName == "raw")
return ReadFromDAT(pFile);
if(ReadFromBMP(pFile))
return TRUE;
return FALSE;
}
BOOL CImage::ReadFromFile(CString filename)
{
CString ext = filename;
int nPointPos=ext.Find(".");
ext.MakeLower();
ext=ext.Mid(nPointPos+1);
if(ext == "jpg" || ext == "gif" )
return ReadFromJPG(filename);
CFile* pFile = new CFile;
if(!pFile->Open(filename,CFile::modeRead))
{
AfxMessageBox("In CImage::ReadFromFile(),Can not opent the file!");
return false;
}
BOOL b = ReadFromFile(pFile);
pFile->Close();
delete pFile;
return b;
}
BOOL CImage::ReadFromJPG(CString filename)
{
//Use the IJL to load up the jpeg
JPEG_CORE_PROPERTIES image;
memset(&image, 0, sizeof(image));
//Init the IJL
if (ijlInit(&image) != IJL_OK)
{
TRACE(_T("Cannot initialize Intel JPEG library!\n"));
return FALSE;
}
//Read in the Jpeg file parameters
image.JPGFile = filename;
if (ijlRead(&image, IJL_JFILE_READPARAMS) != IJL_OK)
{
TRACE(_T("Cannot read JPEG file header from %s file!\n"), image.JPGFile);
ijlFree(&image);
return FALSE;
}
// Set the JPG color space ... this will always be
// somewhat of an educated guess at best because JPEG
// is "color blind" (i.e., nothing in the bit stream
// tells you what color space the data was encoded from).
// However, in this example we assume that we are
// reading JFIF files which means that 3 channel images
// are in the YCbCr color space and 1 channel images are
// in the Y color space.
switch(image.JPGChannels)
{
case 1:
image.JPGColor = IJL_G;
image.DIBColor = IJL_BGR;
image.DIBChannels = 3;
break;
case 3:
image.JPGColor = IJL_YCBCR;
image.DIBColor = IJL_BGR;
image.DIBChannels = 3;
break;
case 4:
image.JPGColor = IJL_YCBCRA_FPX;
image.DIBColor = IJL_RGBA_FPX;
image.DIBChannels = 3;
default:
// This catches everything else, but no
// color twist will be performed by the IJL.
image.JPGColor = IJL_OTHER;
image.DIBColor = IJL_OTHER;
image.DIBChannels = 3; //image.JPGChannels;
break;
}
//Allocate memory for the image
DWORD dwImageSize = image.JPGWidth * image.JPGHeight * image.DIBChannels;
BYTE* pImageData = new BYTE[dwImageSize];
if(pImageData == NULL){
ijlFree(&image);
return FALSE;
}
//Call the IJL to load the Jpeg from file
image.DIBWidth = image.JPGWidth;
image.DIBHeight = image.JPGHeight;
image.DIBPadBytes = 0;
image.DIBBytes = pImageData;
ijlRead(&image, IJL_JFILE_READWHOLEIMAGE);
/* if (ijlRead(&image, IJL_JFILE_READWHOLEIMAGE) != IJL_OK)
{
TRACE(_T("Cannot read image pImageData from %s file!\n"), image.JPGFile);
delete [] pImageData;
ijlFree(&image);
return FALSE;
}*/
//Finished with IJL
if (ijlFree(&image) != IJL_OK) {
TRACE(_T("Cannot free Intel JPEG library!\n"));
}
int bps = WIDTHBYTES(image.JPGWidth * 24);
m_dwLength = sizeof(BITMAPINFOHEADER)+bps * image.JPGHeight;
m_pDib = new BYTE[sizeof(BITMAPINFOHEADER)+bps * image.JPGHeight];
BITMAPINFO * pBMI = (BITMAPINFO *)m_pDib;
memset(pBMI, 0, sizeof(BITMAPINFOHEADER));
pBMI->bmiHeader.biSize = sizeof(pBMI->bmiHeader);
pBMI->bmiHeader.biWidth = image.JPGWidth;
pBMI->bmiHeader.biHeight = image.JPGHeight;
pBMI->bmiHeader.biBitCount = 24;
pBMI->bmiHeader.biPlanes = 1;
pBMI->bmiHeader.biCompression = BI_RGB;
// allocate bitmap
//int bps = (width * channels + 3) /4 * 4;
m_pData = m_pDib + sizeof(BITMAPINFOHEADER);
if(m_pData == NULL){
delete [] pImageData;
return FALSE;
}
int LineBytes = image.JPGWidth * 3;
char *psrc = (char *)pImageData;
char *pline = (char *)(m_pData + image.JPGHeight * bps);
for(int i = image.JPGHeight-1; i>=0; i--)
{
pline -= bps;
memcpy(pline, psrc, LineBytes);
psrc += LineBytes;
}
delete [] pImageData;
return TRUE;
}
BOOL CImage::WriteToFile(CFile * pFile)
{
CString FileName=pFile->GetFileName();
int nPointPos=FileName.Find(".");
FileName.MakeLower();
FileName=FileName.Mid(nPointPos+1);
if(FileName=="bmp")
return WriteAsBMP(pFile);
if(FileName=="pgm")
return WriteAsPGM(pFile);
if(FileName=="bin" || FileName=="dat" || FileName=="raw" )
return WriteAsData(pFile);
if(FileName=="txt")
{
CString temp = pFile->GetFilePath();
pFile -> Close();
BOOL b = SaveAsText(temp, FALSE);
pFile -> Open(temp, CFile::modeWrite);
return b;
}
return WriteAsBMP(pFile);
}
BOOL CImage::WriteToFile(CString filename)
{
CFile* pFile = new CFile;
if(!pFile->Open(filename,CFile::modeWrite|CFile::modeCreate))
{
AfxMessageBox("In CImage::WriteToFile(),Can not opent the file!");
return false;
}
BOOL b = WriteToFile(pFile);
pFile->Close();
delete pFile;
return b;
}
void CImage::ImageClear()
{
if (m_pDib)
//delete []m_pDib; // free the DIB memory
delete []m_pDib;
m_pDib = NULL;
m_pData = NULL;
m_bIsDIB = TRUE;
m_dwLength = 0L;
}
DWORD CImage::Transform(WORD width)
{
DWORD dwBytes = (width * 8) / 32;
if ((width * 8) % 32) {
dwBytes ++;
}
dwBytes *= 4; //bytes per line
return dwBytes;
}
BOOL CImage::ReadFromIMG(CFile* pFile)
{
int bpp;
LPBITMAPINFOHEADER pBMIH;
DWORD dwFileLength = pFile->GetLength();
WORD w,h;
pFile->Read((WORD* )&w,sizeof(WORD));
pFile->Read((WORD* )&h,sizeof(WORD));
dwFileLength -= 2 * sizeof(WORD);
bpp = int(dwFileLength / (w * h));
if(bpp != 1 && bpp != 3)/* 8 or 24 */
{
AfxMessageBox("Wrong Data!");
return false;
}
DWORD dwBytes = Transform(w);//bytes per line
m_dwLength = DWORD(dwBytes * h * bpp) + sizeof(BITMAPINFOHEADER)
+ sizeof(RGBQUAD) * 256;
if (!AllocateMemory()) {
AfxMessageBox("Allocmemory Error");
return FALSE;}
pBMIH=BMInfoHdPtr();
pBMIH->biSize = sizeof(BITMAPINFOHEADER);
pBMIH->biWidth = w;
pBMIH->biHeight = h;
pBMIH->biPlanes = 1;
pBMIH->biBitCount = 8 * bpp;
pBMIH->biCompression = BI_RGB;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -