📄 image.cpp
字号:
//***********************************************************
BOOL CImage::SaveImageToFile(LPCTSTR lpszFileName)
{
if(m_lpDibArray==NULL) return FALSE;
CFile * pWriteFile = NULL;
TRY {pWriteFile = new CFile( lpszFileName, CFile::modeCreate | CFile::modeWrite); }
CATCH( CFileException, e )
{
AfxMessageBox(" 文件错误");
if(pWriteFile != NULL)
{
pWriteFile->Close(); delete pWriteFile; pWriteFile = NULL;
}
THROW_LAST();
}
END_CATCH
BOOL result = false;
CString FileName(lpszFileName);
if(FileName.Right(3) == "img" || FileName.Right(3) == "IMG")
{
result = SaveImageAsIMG( pWriteFile );
}
else if(FileName.Right(3) == "bmp" || FileName.Right(3) == "BMP")
{
result = SaveImageAsBMP( pWriteFile );
}
if( pWriteFile != NULL )
{
pWriteFile->Close(); delete pWriteFile; pWriteFile = NULL;
}
return true;
}
//***********************************************************
//***********************************************************
BOOL CImage::ReadImageAsBMP(CFile * pReadFile)
{
pReadFile->SeekToBegin(); // Set the file pointer to the begin of the file
//Check if the file header is "BM"
if ((pReadFile->Read((LPSTR)&m_bmfHeader, sizeof(BITMAPFILEHEADER)) !=
sizeof(BITMAPFILEHEADER)) || (m_bmfHeader.bfType != DIB_HEADER_MARKER))
{
AfxMessageBox("您所指定的不是一个BMP文件!");
return FALSE;
}
BITMAPINFOHEADER bmiHeader;
pReadFile->Read((LPSTR)&bmiHeader, sizeof(BITMAPINFOHEADER));
m_ImageWidth = bmiHeader.biWidth;
m_ImageHeight = abs(bmiHeader.biHeight);
m_wImageDepth = bmiHeader.biBitCount;
m_nDibWidth = (m_ImageWidth* m_wImageDepth/ 8 + 3) & ~3;
m_nDibHeight = m_ImageHeight;
m_ImageSize = m_nDibWidth * m_nDibHeight;
m_wColorMapNum = GetColorMapNum(m_wImageDepth);
m_HSIImageWidth = (m_ImageWidth + 3) & ~3;
m_HSIImageHeight = m_ImageHeight;
if(bmiHeader.biCompression != BI_BITFIELDS&&bmiHeader.biCompression != BI_RGB)
{
AfxMessageBox("不支持RLE4 or RLE8 压缩格式");
return FALSE;
}
if(bmiHeader.biCompression == BI_BITFIELDS&&(m_bmfHeader.bfOffBits-54)==12)
AllocateMemory(TRUE);
else
AllocateMemory();
if(m_lpDibInfo!=NULL) //create the bitmap info
{
m_lpDibInfo->bmiHeader = bmiHeader;
if(m_wImageDepth<=8&&m_wColorMapNum>0)
pReadFile->Read((LPSTR)m_lpDibInfo->bmiColors, m_wColorMapNum* sizeof(RGBQUAD));
BakupColorIndex();
}
GenerateRowAddress();
m_IsExistRGBMask = m_Is565RGBImage = FALSE;
if(m_wImageDepth==16)
{
m_dwBBitMask = 0x1F;
m_dwGBitMask = 0x3E0;
m_dwRBitMask = 0x7C00;
m_wlowRedBit = 10;
m_wlowGreenBit = 5;
m_wlowBlueBit = 0;
m_wNumRedBits = 5;
m_wNumGreenBits = 5;
m_wNumBlueBits = 5;
if(bmiHeader.biCompression == BI_BITFIELDS && (m_bmfHeader.bfOffBits-54)==12)
{
pReadFile->Read((LPSTR)m_lpDibInfo->bmiColors, 12);
m_IsExistRGBMask = true;
DWORD *Mask = (DWORD *)m_lpDibInfo->bmiColors;
m_dwRBitMask = Mask[0];
m_dwGBitMask = Mask[1];
m_dwBBitMask = Mask[2];
if(m_dwGBitMask != 0x3E0 )
{
m_Is565RGBImage = TRUE;
m_wlowRedBit = 11;
m_wNumGreenBits = 6;
}
}
}
else if(m_wImageDepth==32)
{
m_dwBBitMask = 0xFF;
m_dwGBitMask = 0xFF00;
m_dwRBitMask = 0xFF0000;
m_wlowRedBit = 16;
m_wlowGreenBit = 8;
m_wlowBlueBit = 0;
m_wNumRedBits = 8;
m_wNumGreenBits = 8;
m_wNumBlueBits = 8;
if(bmiHeader.biCompression == BI_BITFIELDS && (m_bmfHeader.bfOffBits-54)==12)
{
pReadFile->Read((LPSTR)m_lpDibInfo->bmiColors,12);
m_IsExistRGBMask = TRUE;
DWORD *Mask = (DWORD *)m_lpDibInfo->bmiColors;
m_dwBBitMask = Mask[0];
m_dwGBitMask = Mask[1];
m_dwRBitMask = Mask[2];
}
}
pReadFile->Seek(m_bmfHeader.bfOffBits, CFile::begin);
if(m_lpDibArray!=NULL)
{
TRY { pReadFile->ReadHuge(m_lpDibArray, m_ImageSize); }
CATCH(CFileException, e)
{
AfxMessageBox("读文件错误");
THROW_LAST();
}
END_CATCH
}
return true;
}
//***********************************************************
//***********************************************************
BOOL CImage::SaveImageAsBMP(CFile * pSaveFile)
{
if( pSaveFile == NULL||m_lpDibArray==NULL )
{
AfxMessageBox("文件类指针或图像数据错误!");
return FALSE;
}
m_bmfHeader.bfType = DIB_HEADER_MARKER;
m_bmfHeader.bfOffBits = sizeof(BITMAPFILEHEADER) +
m_lpDibInfo->bmiHeader.biSize +
m_wColorMapNum * sizeof(RGBQUAD);
m_bmfHeader.bfSize = m_bmfHeader.bfOffBits + m_ImageSize;
m_bmfHeader.bfReserved1 = 0;
m_bmfHeader.bfReserved2 = 0;
TRY
{ // Write the file header
pSaveFile->Write( (LPSTR)&m_bmfHeader, sizeof(BITMAPFILEHEADER));
// write bmp info header.
pSaveFile->Write( (LPSTR)&(m_lpDibInfo->bmiHeader), sizeof(BITMAPINFOHEADER));
//Write palette info
if(m_wColorMapNum)
pSaveFile->Write( (LPSTR)m_lpDibInfo->bmiColors, m_wColorMapNum*sizeof(RGBQUAD));
else if(m_IsExistRGBMask)
pSaveFile->Write( (LPSTR)m_lpDibInfo->bmiColors, 3*sizeof(RGBQUAD));
// Write the DIB bits
pSaveFile->WriteHuge(m_lpDibArray, m_ImageSize);
}
CATCH (CFileException, e)
{
AfxMessageBox(" 存文件时出错");
THROW_LAST();
}
END_CATCH
return TRUE;
}
//***********************************************************
//***********************************************************
BOOL CImage::ReadImageAsIMG(CFile * pReadFile)
{
//get length of DIB in bytes for use when reading
DWORD dwBitsSize = pReadFile->GetLength();
double multi=sqrt(dwBitsSize)/IMG_FORMAT_BASE_LENGTH;
m_ImageWidth = IMG_FORMAT_BASE_LENGTH*int(multi);
m_ImageHeight = dwBitsSize / m_ImageWidth;
if( dwBitsSize % m_ImageWidth )
{
AfxMessageBox(" Not IMG format or file error");
return FALSE;
}
m_wImageDepth = 8;
m_wColorMapNum = GetColorMapNum(m_wImageDepth);
m_nDibWidth = (m_ImageWidth* m_wImageDepth/ 8 + 3) & ~3;
m_nDibHeight = m_ImageHeight;
m_ImageSize = m_nDibWidth * m_nDibHeight;
AllocateMemory();
InitGrayImageInfo();
GenerateRowAddress();
TRY //Go read the bits.
{
pReadFile->ReadHuge(m_lpDibArray, dwBitsSize);
}
CATCH(CFileException, e)
{
AfxMessageBox("读文件错误");
THROW_LAST();
}
END_CATCH
return TRUE;
}
//***********************************************************
//***********************************************************
BOOL CImage::SaveImageAsIMG(CFile * pSaveFile)
{
if( pSaveFile == NULL||m_lpDibArray==NULL )//Check if the file pointer is valid
{
AfxMessageBox("文件类指针或图像数据错误!");
return FALSE;
}
TRY
{ // Write the IMG bits
pSaveFile->WriteHuge(m_lpDibArray, m_ImageSize);
}
CATCH (CFileException, e)
{
AfxMessageBox(" 存文件时出错");
THROW_LAST();
}
END_CATCH
return TRUE;
}
//***********************************************************
//***********************************************************
BOOL CImage::ShowCurrentImage(CDC *pMpDc,CRect ShowRect)
{
BOOL bSuccess=FALSE; // Success or fail flag
// Check for valid image data*
if( m_lpDibArray == NULL)
return bSuccess;
UINT Mode;
if(m_lpDibInfo->bmiHeader.biCompression == BI_RGB)
Mode = DIB_RGB_COLORS;
else if(m_lpDibInfo->bmiHeader.biCompression == BI_BITFIELDS)
Mode = DIB_PAL_COLORS;
// Make sure to use the stretching mode best for color pictures
pMpDc->SetStretchBltMode(COLORONCOLOR);
BOOL Show1to1 = fabs(m_fScale - 1.0)<0.05 &&
abs(ShowRect.Width() - m_ImageWidth)<5 &&
abs(ShowRect.Height() - m_ImageHeight)<5;//*/
if(Show1to1)
{
bSuccess = ::SetDIBitsToDevice(pMpDc->m_hDC, // hDC
ShowRect.left, //DestX
ShowRect.top, //DestY
(int)m_ImageWidth, //最好是图像的宽度
(int)m_ImageHeight, //最好是图像的高度
0, //SrcX
0, //SrcY
0, //nStartScan
(int)m_nDibHeight, //nNumScans
m_lpDibArray, //lpBits
m_lpDibInfo, //lpBitsInfo
Mode); //wUsage //*/
}
else
{
double tmpscalex = ShowRect.Width()/(double)m_ImageWidth;
double tmpscaley = ShowRect.Height()/(double)m_ImageHeight;
if(tmpscalex<tmpscaley)
{
m_fScale = tmpscalex;
ShowRect.bottom = ShowRect.top + int(m_fScale*m_ImageHeight + 0.5);
}
else
{
m_fScale = tmpscaley;
ShowRect.right = ShowRect.left + int(m_fScale*m_ImageWidth + 0.5);
}
bSuccess = ::StretchDIBits(pMpDc->m_hDC, // hDC
ShowRect.left, // DestX
ShowRect.top, // DestY
ShowRect.Width(), // nDestWidth
ShowRect.Height(), // nDestHeight
0, // SrcX
0, // SrcY
(int)m_ImageWidth, // wSrcWidth
(int)m_ImageHeight, // wSrcHeight
m_lpDibArray, // lpBits
m_lpDibInfo, // lpBitsInfo
Mode, // wUsage
SRCCOPY); // dwROP//*/
}
return bSuccess;
}
BOOL CImage::ShowCurrentImage(CDC *pMpDc,CPoint LTp, CPoint RBp)
{
return ShowCurrentImage( pMpDc, CRect(LTp,RBp) );
}
BOOL CImage::ShowCurrentImage(CDC *pMpDc,int x1, int y1, int x2, int y2)
{
return ShowCurrentImage( pMpDc, CRect(x1,y1,x2,y2) );
}
//***********************************************************
//***********************************************************
BOOL CImage::ShowPartialImage(CDC *pMpDc,CRect ShowRect,CPoint LTp,CPoint RBp, BOOL Is1to1)
{
#ifdef _DEBUG
if(!CheckRect(LTp,RBp)||m_lpDibArray == NULL)
{
AfxMessageBox("下标越界!!!");
AfxAbort();
}
#endif
BOOL bSuccess=FALSE; // Success/fail flag
// Make sure to use the stretching mode best for color pictures
pMpDc->SetStretchBltMode(COLORONCOLOR);
int width = RBp.x - LTp.x + 1;
int height = RBp.y - LTp.y + 1;
if(Is1to1)
{
bSuccess = ::SetDIBitsToDevice(pMpDc->m_hDC, // hDC
ShowRect.left, // DestX
ShowRect.top, // DestY
ShowRect.Width(), // nDestWidth
ShowRect.Height(), // nDestHeight
LTp.x, //SrcX
m_nDibHeight - RBp.y -1, //SrcY
0, //nStartScan
(int)m_nDibHeight- RBp.y - 1 + height, //nNumScans
m_lpDibArray, //lpBits
m_lpDibInfo, //lpBitsInfo
DIB_RGB_COLORS); //wUsage //*/
}
else
{
bSuccess = ::StretchDIBits(pMpDc->m_hDC, // hDC
ShowRect.left, // DestX
ShowRect.top, // DestY
ShowRect.Width(), // nDestWidth
ShowRect.Height(), // nDestHeight
LTp.x, // SrcX
m_ImageHeight - RBp.y -1,// SrcY
width, // wSrcWidth
height, // wSrcHeight
m_lpDibArray, // lpBits
m_lpDibInfo, // lpBitsInfo
DIB_RGB_COLORS, // wUsage
SRCCOPY); // dwROP
}
return bSuccess;
}
//***********************************************************
//***********************************************************
void CImage::SelectChannel(DWORD channel)
{
#ifdef _DEBUG
if(m_lpDibArray == NULL)
{
AfxMessageBox("下标越界!!!");
AfxAbort();
}
#endif
static BOOL HaveShowChannel = FALSE; // 是否已经显示过单色分量图
if(!HaveShowChannel)
{
BackUp();
HaveShowChannel=true;
}
else
{
ImgSwap();
BackUp();
}
switch(channel)
{
case REDCOMPONENT:
{
if( m_wImageDepth == 24 )
{
for(int j= 0; j< m_ImageHeight; j++)
{
RGBTRIPLE* pixptr = (RGBTRIPLE*)(RowAddress[j]);
for(int i= 0; i< m_ImageWidth; i++)
{
pixptr[i].rgbtGreen = pixptr[i].rgbtRed;
pixptr[i].rgbtBlue = pixptr[i].rgbtRed;
}
}
}
break;
}
case GREENCOMPONENT:
{
if( m_wImageDepth == 24 )
{
for(int j= 0; j< m_ImageHeight; j++)
{
RGBTRIPLE* pixptr = (RGBTRIPLE*)(RowAddress[j]);
for(int i= 0; i< m_ImageWidth; i++)
{
pixptr[i].rgbtRed = pixptr[i].rgbtGreen;
pixptr[i].rgbtBlue = pixptr[i].rgbtGreen;
}
}
}
break;
}
case BLUECOMPONENT:
{
if( m_wImageDepth == 24)
{
for(int j= 0; j< m_ImageHeight; j++)
{
RGBTRIPLE* pixptr = (RGBTRIPLE*)(RowAddress[j]);
for(int i= 0; i< m_ImageWidth; i++)
{
pixptr[i].rgbtGreen = pixptr[i].rgbtBlue;
pixptr[i].rgbtRed = pixptr[i].rgbtBlue;
}
}
}
break;
}
case REDCOMPONENT | GREENCOMPONENT:
{
if( m_wImageDepth == 24 )
{
for(int j= 0; j< m_ImageHeight; j++)
{
RGBTRIPLE* pixptr = (RGBTRIPLE*)(RowAddress[j]);
for(int i= 0; i< m_ImageWidth; i++)
{
pixptr[i].rgbtBlue = 0;
}
}
}
break;
}
case GREENCOMPONENT | BLUECOMPONENT:
{
if( m_wImageDepth == 24)
{
for(int j= 0; j< m_ImageHeight; j++)
{
RGBTRIPLE* pixptr = (RGBTRIPLE*)(RowAddress[j]);
for(int i= 0; i< m_ImageWidth; i++)
{
pixptr[i].rgbtRed =0 ;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -