www.pudn.com > 医学图像处理示例源代码.rar > Image.cpp
//这里是"image.h"的实现函数定义 #include "stdafx.h" #include#include #include #include "image.h" #include FloatImage::FloatImage() { lp_data = NULL; lp_AddRow = NULL; Width = Height = 0; } FloatImage::~FloatImage() { DeleteData(); } FloatImage::FloatImage(unsigned int w, unsigned int h) { Width = w; Height = h; ImageSize = w * h; lp_data = NULL; lp_AddRow = NULL; Construct(w, h); } void FloatImage::Construct(unsigned int w, unsigned int h) { DeleteData(); if( ImageSize > 0 ) lp_data = new float[ImageSize]; memset(lp_data, 0, ImageSize* sizeof(float) ); if( Height > 0 ) lp_AddRow = new float*[Height]; lp_AddRow[0] = lp_data; for( UINT i= 1; i < Height; i++) lp_AddRow[i] = lp_AddRow[i- 1] + Width; } void FloatImage::DeleteData() { if(lp_data != NULL) delete []lp_data; if(lp_AddRow != NULL) delete []lp_AddRow; } //--------------------------CImage class declaration -------------------// //*********************************************************** //*********************************************************** C2DArray::C2DArray() { m_lpDibArray = NULL; RowAddress = NULL; } //*********************************************************** //*********************************************************** C2DArray::~C2DArray() { if(m_lpDibArray != NULL) ReleaseDibArray(); } //*********************************************************** //*********************************************************** void C2DArray::ReleaseDibArray() { if( m_lpDibArray != NULL ) { delete []m_lpDibArray; m_lpDibArray = NULL; } if( RowAddress != NULL) { delete []RowAddress; RowAddress = NULL; } } //*********************************************************** //*********************************************************** C2DArray::C2DArray(P_LONG width, P_LONG height) { m_nDibWidth = width; m_nDibHeight = height; m_lpDibArray = NULL; RowAddress = NULL; m_lpDibArray = new P_BYTE[width * height]; if( m_lpDibArray == NULL) AfxThrowMemoryException(); RowAddress = new P_BYTE*[m_nDibHeight]; RowAddress[0] = m_lpDibArray; for(int i=1; i = m_nDibWidth) || (y < 0) || ( y >= m_nDibHeight) ) { if( x < 0 ) x = 0; else if( x >= m_nDibWidth ) x = m_nDibWidth-1; if(y<0) y = 0; else if( y >= m_nDibHeight ) y = m_nDibHeight-1; return false; } else return true; } BOOL C2DArray::CheckDataRange(CPoint pt) { return CheckDataRange(pt.x, pt.y); } //*********************************************************** //*********************************************************** P_BYTE C2DArray::SGetXYValue(P_LONG x, P_LONG y) { #ifdef _DEBUG if(!CheckDataRange(x, y)) { AfxMessageBox("下标越界!!!"); AfxAbort(); } #endif return RowAddress[y][x]; } P_BYTE C2DArray::SGetXYValue(CPoint pt) { return SGetXYValue(pt.x, pt.y); } //*********************************************************** //*********************************************************** void C2DArray::SSetXYValue(P_LONG x, P_LONG y, P_BYTE value) { #ifdef _DEBUG if(!CheckDataRange(x,y)) { AfxMessageBox("下标越界!!!"); AfxAbort(); } #endif RowAddress[y][x] = value; } void C2DArray::SSetXYValue(CPoint pt, P_BYTE value) { SSetXYValue(pt.x, pt.y, value); } BOOL CImage::CheckPoint(P_LONG &x, P_LONG &y) { if( (x<0)||(x>=m_ImageWidth)||(y<0)||(y>=m_ImageHeight) ) { if( x < 0) x = 0; else if( x >= m_ImageWidth ) x = m_ImageWidth-1; if( y < 0 ) y = 0; else if( y >= m_ImageHeight ) y = m_ImageHeight-1; return false; } else return true; } BOOL CImage::CheckPoint(CPoint &pt) { return CheckPoint(pt.x, pt.y); } //*********************************************************** //*********************************************************** BOOL CImage::CheckRect(CPoint &p1,CPoint &p2) { if(!CheckPoint(p1) || !CheckPoint(p2)) return false; P_LONG tempx, tempy, temp; tempx = p2.x - p1.x; tempy = p2.y - p1.y; if( tempx < 0 ) { temp = p1.x; p1.x = p2.x; p2.x = temp; } if( tempy < 0) { temp = p1.y; p1.y = p2.y; p2.y = temp; } if( labs(tempx)<5||labs(tempy)<5) return false; else return true; } BOOL CImage::CheckRect(CRect &ImageRect) { if( ImageRect.left < 0 ) { ImageRect.left = 0; } else if( ImageRect.right > (m_ImageWidth-1) ) { ImageRect.right = m_ImageWidth- 1; } if( ImageRect.top < 0 ) { ImageRect.top = 0; } else if( ImageRect.bottom > (m_ImageHeight-1) ) { ImageRect.bottom = m_ImageHeight- 1; } if( ImageRect.Width()<5||ImageRect.Height()<5) return false; else return true; } //*********************************************************** //*********************************************************** void CImage::ConstructInit() { m_fScale = 1.0; m_bImgModified = FALSE; m_wColorMapNum = 0; m_lpDibInfo = NULL; m_lpHSIArray = NULL; m_lpDibArrayBuff = NULL; m_hDIB = NULL; m_Bright = -1; m_Contrast = -1; m_SorceType = 0; } // 释放全部的内存 void CImage::DeleteMe() { if( m_hDIB != NULL) ReleaseCopyHandle(); if( m_lpDibInfo != NULL) ReleaseDibPalInfo(); if( m_lpDibArray != NULL) ReleaseDibArray(); if( m_lpHSIArray != NULL) ReleaseHueImg(); if(m_lpDibArrayBuff != NULL) ReleaseBuffer(); } //释放m_lpDibInfo内存 void CImage::ReleaseDibPalInfo() { if( m_pUseful != NULL ) { delete []m_pUseful; m_lpDibInfo = NULL; m_pUseful = NULL; } } //释放m_lpDibArrayBuff内存 void CImage::ReleaseBuffer() { if( m_lpDibArrayBuff != NULL ) { delete []m_lpDibArrayBuff ; m_lpDibArrayBuff = NULL; } } //释放m_lpHSIArray内存 void CImage::ReleaseHueImg() { if( m_lpHSIArray != NULL ) { delete []m_lpHSIArray; m_lpHSIArray = NULL; } } //*********************************************************** //*********************************************************** BOOL CImage::NewBuffer() { if( m_lpDibArrayBuff != NULL ) ReleaseBuffer(); if( m_ImageSize ) { m_lpDibArrayBuff = new P_BYTE[m_ImageSize]; if( m_lpDibArrayBuff == NULL ) { AfxThrowMemoryException(); // especial exception handle return false; } else return true; } else return false; } //*********************************************************** //*********************************************************** BOOL CImage::NewHSIImg() { if( m_lpHSIArray != NULL ) ReleaseHueImg(); if( m_HSIImageWidth*m_HSIImageHeight ) { m_lpHSIArray = new P_BYTE[m_HSIImageWidth*m_HSIImageHeight]; if( m_lpHSIArray == NULL ) { AfxThrowMemoryException(); // especial exception handle return false; } else return true; } else return false; } //*********************************************************** //*********************************************************** CImage::CImage() { ConstructInit(); } //*********************************************************** //*********************************************************** CImage::~CImage() { if( m_hDIB != NULL) ReleaseCopyHandle(); if( m_lpDibInfo != NULL) ReleaseDibPalInfo(); if( m_lpHSIArray != NULL) ReleaseHueImg(); if(m_lpDibArrayBuff != NULL) ReleaseBuffer(); } CImage::CImage(CImage &source) { ConstructInit(); m_ImageSize = source.m_ImageSize; m_ImageWidth = source.m_ImageWidth; m_ImageHeight = source.m_ImageHeight; m_nDibWidth = source.m_nDibWidth; m_nDibHeight = source.m_nDibHeight; m_wImageDepth = source.m_wImageDepth; m_wColorMapNum = source.m_wColorMapNum; m_HSIImageWidth = source.m_HSIImageWidth; m_HSIImageHeight = source.m_HSIImageHeight; m_dwRBitMask = source.m_dwRBitMask; m_dwGBitMask = source.m_dwGBitMask; m_dwBBitMask = source.m_dwBBitMask; m_wlowRedBit = source.m_wlowRedBit; m_wlowGreenBit = source.m_wlowGreenBit; m_wlowBlueBit = source.m_wlowBlueBit; m_wNumRedBits = source.m_wNumRedBits; m_wNumGreenBits = source.m_wNumGreenBits; m_wNumBlueBits = source.m_wNumBlueBits; AllocateMemory(); if( m_lpDibInfo != NULL ) //create the bitmap info { m_lpDibInfo->bmiHeader = source.m_lpDibInfo->bmiHeader; if(m_wColorMapNum) //create the color table { for(int i=0; i bmiColors[i] = source.m_lpDibInfo->bmiColors[i]; } BakupColorIndex(); } } memcpy(m_lpDibArray, source.m_lpDibArray, m_ImageSize); GenerateRowAddress(); } CImage::CImage(CImage &source, CPoint <p, CPoint &RBp) { #ifdef _DEBUG if(!source.CheckRect(LTp, RBp)) { AfxMessageBox("下标越界!!!"); AfxAbort(); } #endif ConstructInit(); m_wImageDepth = source.m_wImageDepth; m_wColorMapNum = source.m_wColorMapNum; m_HSIImageWidth = source.m_HSIImageWidth; m_HSIImageHeight = source.m_HSIImageHeight; P_LONG width = RBp.x - LTp.x + 1; P_LONG height = RBp.y - LTp.y + 1; m_ImageWidth = width; m_ImageHeight = height; m_nDibWidth = (width* m_wImageDepth/ 8 + 3) & ~3; m_nDibHeight = height; m_ImageSize = m_nDibWidth* m_nDibHeight; AllocateMemory(); if( m_lpDibInfo != NULL ) //create the bitmap info { m_lpDibInfo->bmiHeader = source.m_lpDibInfo->bmiHeader; m_lpDibInfo->bmiHeader.biWidth = width; m_lpDibInfo->bmiHeader.biHeight = source.m_IsImageDownUp ? m_nDibHeight : -m_nDibHeight;; if( m_wColorMapNum ) { for(int i= 0; i< m_wColorMapNum; i++) { m_lpDibInfo->bmiColors[i] = source.m_lpDibInfo->bmiColors[i]; } BakupColorIndex(); } } GenerateRowAddress(); BYTE *bpSourceAdd; int OffSet = LTp.x * m_wImageDepth/ 8; int DataLength = width * m_wImageDepth/ 8; for( P_LONG y = 0; y < height; y++) { bpSourceAdd = source.RowAddress[LTp.y + y] + OffSet; memcpy( RowAddress[y], bpSourceAdd, DataLength ); } } CImage::CImage(P_LONG width, P_LONG height, int PixelDepth, DWORD colornum) { ConstructInit(); CreateEmpty(width, height, PixelDepth, colornum); } //*********************************************************** //*********************************************************** BOOL CImage::CreateEmpty(P_LONG width, P_LONG height, int PixelDepth, DWORD colornum) { DeleteMe(); ConstructInit(); m_wImageDepth = PixelDepth; m_ImageWidth = width; m_ImageHeight = height; m_nDibWidth = (width* m_wImageDepth/ 8 + 3) & ~3; m_nDibHeight = height; m_ImageSize = m_nDibWidth* m_nDibHeight; m_wColorMapNum = GetColorMapNum(m_wImageDepth); m_HSIImageWidth = (width + 3) & ~3; m_HSIImageHeight = height; if( m_wImageDepth == 16 || m_wImageDepth == 32 ) AllocateMemory(true); else AllocateMemory(); if(m_lpDibInfo!=NULL && m_lpDibArray!=NULL) //create the bitmap info { m_lpDibInfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); m_lpDibInfo->bmiHeader.biWidth = width; m_lpDibInfo->bmiHeader.biHeight = height; m_lpDibInfo->bmiHeader.biPlanes = 1; m_lpDibInfo->bmiHeader.biBitCount = m_wImageDepth; m_lpDibInfo->bmiHeader.biCompression = BI_RGB; m_lpDibInfo->bmiHeader.biSizeImage = m_ImageSize; m_lpDibInfo->bmiHeader.biXPelsPerMeter = 0; m_lpDibInfo->bmiHeader.biYPelsPerMeter = 0; m_lpDibInfo->bmiHeader.biClrUsed = m_wColorMapNum; m_lpDibInfo->bmiHeader.biClrImportant = 0; GenerateRowAddress(); if( m_wImageDepth <= 8 ) //create the color table { for(int i= 0; i< m_wColorMapNum; i++) { m_lpDibInfo->bmiColors[i].rgbBlue = (P_BYTE)i; m_lpDibInfo->bmiColors[i].rgbGreen = (P_BYTE)i; m_lpDibInfo->bmiColors[i].rgbRed = (P_BYTE)i; m_lpDibInfo->bmiColors[i].rgbReserved = 0; } BakupColorIndex(); memset(m_lpDibArray, (P_BYTE)colornum, m_ImageSize); } else 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; DWORD *Mask = (DWORD *)m_lpDibInfo->bmiColors; Mask[0] = m_dwRBitMask; Mask[1] = m_dwGBitMask; Mask[2] = m_dwBBitMask; RGBTRIPLE Pixel3; BYTE *RGB = (BYTE * )&colornum; Pixel3.rgbtRed = RGB[0] / 8; Pixel3.rgbtGreen = RGB[1] / 8; Pixel3.rgbtBlue = RGB[2] / 8; WORD Pixel2 = Pixel3.rgbtRed< bmiHeader.biSize = sizeof(BITMAPINFOHEADER); m_lpDibInfo->bmiHeader.biWidth = width; m_lpDibInfo->bmiHeader.biHeight = source.m_IsImageDownUp ? height : -height; m_lpDibInfo->bmiHeader.biPlanes = 1; m_lpDibInfo->bmiHeader.biBitCount = m_wImageDepth; m_lpDibInfo->bmiHeader.biCompression = BI_RGB; m_lpDibInfo->bmiHeader.biSizeImage = m_ImageSize; m_lpDibInfo->bmiHeader.biXPelsPerMeter = 0; m_lpDibInfo->bmiHeader.biYPelsPerMeter = 0; m_lpDibInfo->bmiHeader.biClrUsed = m_wColorMapNum; m_lpDibInfo->bmiHeader.biClrImportant = 0; if( m_wImageDepth <= 8 )// create the color table { for(int i= 0; i< m_wColorMapNum; i++) { m_lpDibInfo->bmiColors[i] = source.m_lpDibInfo->bmiColors[i]; } BakupColorIndex(); } } GenerateRowAddress(); //下面开始用插值方法来产生放大的图像 P_LONG xx, yy, tx, ty; float alpha, belta; float *coef = new float[nScale]; for(int i= 0; i< nScale; i++) coef[i] = (float)i / (float)nScale; if( m_wImageDepth == 8 ) { P_BYTE I11, I12, I21, I22, I; for( P_LONG y0 = 0; y0 < SourceH ; y0++) { yy = y0 * nScale; ty = y0 + LTp.y; for( P_LONG x0 = 0; x0 < SourceW; x0++) { xx = x0 * nScale; tx = x0 + LTp.x; I11 = source.RowAddress[ ty ][ tx ]; I12 = source.RowAddress[ ty ][tx+1]; I21 = source.RowAddress[ty+1][ tx ]; I22 = source.RowAddress[ty+1][tx+1]; for(P_LONG j = 0; j < nScale; j ++) { belta = coef[j]; for( P_LONG i = 0; i < nScale; i ++) { alpha = coef[i]; I = (P_BYTE)( (float)(I11 + (I12-I11) * alpha) * (1.0 - belta) + (float)(I21 + (I22-I21) * alpha) * belta+0.5); RowAddress[yy+ j][xx+ i] = I; } } } } int LineRemain = m_nDibWidth - m_ImageWidth; if(LineRemain) { for(P_LONG j = 0; j < m_ImageHeight ; j ++) { P_BYTE *lp = RowAddress[j] + width-1; P_BYTE gray = *lp++; memset(lp, gray, LineRemain); } } }//end of if(m_wImageDepth==8) else if( m_wImageDepth == 24 ) { int g11, g12, g21, g22; RGBTRIPLE I11, I12, I21, I22, I, *RGBRowAddress; for( P_LONG y0 = 0; y0 < SourceH; y0 ++) { yy = y0 * nScale; ty = y0 + LTp.y; for( P_LONG x0 = 0; x0 < SourceW; x0 ++) { xx = x0 * nScale; tx = x0 + LTp.x; I11 = source.GetRGBPixel(tx, ty ); I12 = source.GetRGBPixel(tx+1, ty); I21 = source.GetRGBPixel(tx, ty+1); I22 = source.GetRGBPixel(tx+1, ty+1); for(P_LONG j = 0; j < nScale; j ++) { RGBRowAddress = (RGBTRIPLE*)(RowAddress[yy+ j]); belta = coef[j]; for( P_LONG i = 0; i < nScale; i ++) { alpha = coef[i]; g11 = I11.rgbtRed; g12 = I12.rgbtRed; g21 = I21.rgbtRed; g22 = I22.rgbtRed; I.rgbtRed= (P_BYTE)((float)(g11 + (g12-g11) * alpha) * (1.0 - belta) + (float)(g21 + (g22-g21) * alpha) * belta+0.5); g11 = I11.rgbtGreen; g12 = I12.rgbtGreen; g21 = I21.rgbtGreen; g22 = I22.rgbtGreen; I.rgbtGreen= (P_BYTE)((float)(g11 + (g12-g11) * alpha) * (1.0 - belta) + (float)(g21 + (g22-g21) * alpha) * belta+0.5); g11 = I11.rgbtBlue; g12 = I12.rgbtBlue; g21 = I21.rgbtBlue; g22 = I22.rgbtBlue; I.rgbtBlue= (P_BYTE)((float)(g11 + (g12-g11) * alpha) * (1.0 - belta) + (float)(g21 + (g22-g21) * alpha) * belta+0.5); RGBRowAddress[xx+ i] = I; } } } } int LineRemain = m_nDibWidth - m_ImageWidth * 3; if( LineRemain ) { for(P_LONG j =1; j <= m_ImageHeight ; j++) { P_BYTE *lp = RowAddress[j] - 1 - LineRemain; memset(lp, 255, LineRemain); } } } if( coef != NULL ) delete []coef; return TRUE; } //*********************************************************** //*********************************************************** BOOL CImage::CreateMicroImg(CImage &source, P_LONG MicroW, P_LONG MicroH) { //还需要加入高彩的放大处理 DeleteMe(); m_wImageDepth = source.m_wImageDepth; m_wColorMapNum = source.m_wColorMapNum; m_ImageWidth = MicroW; m_ImageHeight = MicroH; m_nDibWidth = (m_ImageWidth* m_wImageDepth/ 8 + 3) & ~3;; m_nDibHeight = MicroH; m_ImageSize = m_nDibWidth * m_nDibHeight; m_HSIImageWidth = (MicroW + 3) & ~3; m_HSIImageHeight = MicroH; AllocateMemory(); if( m_lpDibInfo!=NULL && m_lpDibArray != NULL ) //create the bitmap info { m_lpDibInfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); m_lpDibInfo->bmiHeader.biWidth = MicroW; m_lpDibInfo->bmiHeader.biHeight = source.m_IsImageDownUp ? MicroH : -MicroH; m_lpDibInfo->bmiHeader.biPlanes = 1; m_lpDibInfo->bmiHeader.biBitCount = m_wImageDepth; m_lpDibInfo->bmiHeader.biCompression = BI_RGB; m_lpDibInfo->bmiHeader.biSizeImage = m_ImageSize; m_lpDibInfo->bmiHeader.biXPelsPerMeter = 0; m_lpDibInfo->bmiHeader.biYPelsPerMeter = 0; m_lpDibInfo->bmiHeader.biClrUsed = m_wColorMapNum; m_lpDibInfo->bmiHeader.biClrImportant = 0; if( m_wImageDepth <= 8 )// create the color table { for(int i= 0; i< m_wColorMapNum; i++) { m_lpDibInfo->bmiColors[i] = source.m_lpDibInfo->bmiColors[i]; } BakupColorIndex(); } } GenerateRowAddress(); //下面开始用插值方法来产生缩小的图像 P_LONG x0, y0, xx, yy; float dx = (float)source.m_ImageWidth/ (float)MicroW; float dy = (float)source.m_ImageHeight/ (float)MicroH; float OrgPtx, OrgPty; if( m_wImageDepth == 8 ) { for(OrgPty = 0, y0 = 0; y0 < MicroH ; y0++) { yy = int(OrgPty + 0.5); for(OrgPtx = 0, x0 = 0; x0 < MicroW ; x0++) { xx = int(OrgPtx + 0.5); RowAddress[y0][x0] = source.RowAddress[ yy ][ xx ]; OrgPtx += dx; } OrgPty += dy; } } //end of if(m_wImageDepth==8) else if( m_wImageDepth == 24 ) { RGBTRIPLE *RGBRowAddress; for(OrgPty = 0, y0 = 0; y0 < MicroH ; y0++) { yy = int(OrgPty + 0.5); RGBRowAddress = (RGBTRIPLE *)RowAddress[y0]; for(OrgPtx = 0, x0 = 0; x0 < MicroW ; x0++) { xx = int(OrgPtx + 0.5); RGBRowAddress[x0] = source.GetRGBPixel(xx, yy); OrgPtx += dx; } OrgPty += dy; } } //end of if(m_wImageDepth==24) return TRUE; } //*********************************************************** //*********************************************************** BOOL CImage::ConvertToGrayImage() { eImageType dImageType = GetImageType(); if( m_wImageDepth == IndexGrayImage) return false; P_LONG i, j, GrayImagewidth = (m_ImageWidth + 3) & ~3; BYTE *tempBMP = new BYTE[GrayImagewidth * m_ImageHeight]; memset(tempBMP, 0, GrayImagewidth * m_ImageHeight); BYTE *lAdd = tempBMP + GrayImagewidth * (m_ImageHeight - 1); RGBTRIPLE rgbV; for(j= 0; j< m_ImageHeight; j++) { for(i= 0; i< m_ImageWidth; i++) { rgbV = GetRGBPixel(i, j); lAdd[i] = (rgbV.rgbtBlue+ rgbV.rgbtGreen + rgbV.rgbtRed + 2)/3; } lAdd -= GrayImagewidth; } m_wImageDepth = 8; m_nDibWidth = GrayImagewidth; 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; m_bmfHeader.bfType = DIB_HEADER_MARKER; // "BM" m_bmfHeader.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + m_wColorMapNum * sizeof(RGBQUAD); m_bmfHeader.bfSize = m_bmfHeader.bfOffBits + m_ImageSize; m_bmfHeader.bfReserved1 = 0; m_bmfHeader.bfReserved2 = 0; AllocateMemory(); InitGrayImageInfo(); GenerateRowAddress(); memcpy(m_lpDibArray, tempBMP, m_ImageSize); if( tempBMP!= NULL ) delete[]tempBMP; return true; } //*********************************************************** //*********************************************************** void CImage::GetImageDimensions(LPCTSTR fileName, unsigned int &width, unsigned int &height, unsigned int &Depth) { CString FileName(fileName); if(FileName.Right(3) == "img" ||FileName.Right(3) == "IMG") { CFile pReadFile(fileName, CFile::modeRead | CFile::shareCompat); DWORD dwBitsSize = pReadFile.GetLength(); double multi = sqrt(dwBitsSize) / IMG_FORMAT_BASE_LENGTH; width = IMG_FORMAT_BASE_LENGTH * int(multi); height = dwBitsSize / width; } else { FILE *rf = fopen(fileName, "r"); if ( rf == NULL) return; if(FileName.Right(3) == "bmp" ||FileName.Right(3) == "BMP") { BITMAPFILEHEADER BMP_Header; BITMAPINFOHEADER BMP_InfoHeader; fread( (LPSTR)&BMP_Header, sizeof(BITMAPFILEHEADER), 1, rf ); fread( (LPSTR)&BMP_InfoHeader, sizeof(BITMAPINFOHEADER), 1, rf ); if ( BMP_Header.bfType != DIB_HEADER_MARKER ) { AfxMessageBox("您所指定的不是一个BMP文件!"); return ; } width = BMP_InfoHeader.biWidth; height = abs(BMP_InfoHeader.biHeight); Depth = BMP_InfoHeader.biBitCount; } else if(FileName.Right(3) == "pbm" ||FileName.Right(3) == "PBM") { char P14[4]; //读出图像的宽度和高度 int w = 0, h = 0; fscanf(rf, "%s\n", P14); if ( (P14[0] != 'P') && (P14[1] != '1'&&P14[1] != '4') ) { AfxMessageBox("您所指定的不是一个PBM文件!"); return; } fscanf(rf, "%d %d\n", &w, &h); width = w; height = h; Depth = 8; } else if(FileName.Right(3) == "pgm" ||FileName.Right(3) == "PGM") { char P5[4]; fscanf(rf, "%s\n", P5); if ( (P5[0] != 'P') && (P5[1] != '5') ) { AfxMessageBox("您所指定的不是一个PGM文件!"); return; } //读出图像的宽度和高度 int w = 0, h = 0, MaxGray = 255; fscanf(rf, "%d %d\n", &w, &h); fscanf(rf, "%d\n", &MaxGray); width = w; height = h; Depth = 8; } fclose(rf); } } //*********************************************************** //*********************************************************** BOOL CImage::ReadImageFromFile(LPCTSTR lpszFileName) { CFile * pReadFile; TRY { pReadFile = new CFile( lpszFileName, CFile::modeRead | CFile::shareCompat); } CATCH( CFileException, e ) { return false; } END_CATCH if( pReadFile == NULL || pReadFile->GetLength( )<54) { AfxMessageBox("文件类指针或文件格式错误!!!"); if( pReadFile != NULL ) { pReadFile->Close(); delete pReadFile; pReadFile = NULL; } return false; } else { BOOL result = false; CString FileName(lpszFileName); if(FileName.Right(3) == "img" ||FileName.Right(3) == "IMG") { result = ReadImageAsIMG( pReadFile); } else if(FileName.Right(3) == "bmp" ||FileName.Right(3) == "BMP") { result = ReadImageAsBMP( pReadFile); } if(pReadFile != NULL) { pReadFile->Close(); delete pReadFile; pReadFile = NULL; } return result; } } //*********************************************************** //*********************************************************** 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 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 ; } } } break; } case BLUECOMPONENT | 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 = 0; } } } break; } case HUEIMAGE: { CreateHSIImage( HUEIMAGE ); if( m_wImageDepth == 24) { for(int j= 0, k= 0; j< m_ImageHeight; j++, k += m_HSIImageWidth) { RGBTRIPLE* pixptr = (RGBTRIPLE*)( RowAddress[j] ); for(int i= 0; i< m_ImageWidth; i++) { pixptr[i].rgbtRed = pixptr[i].rgbtBlue = pixptr[i].rgbtGreen = m_lpHSIArray[k + i]; } } } break; } case SATURATIONIMAGE: { CreateHSIImage( SATURATIONIMAGE ); if( m_wImageDepth == 24 ) { for(int j= 0, k= 0; j< m_ImageHeight; j++, k += m_HSIImageWidth) { RGBTRIPLE* pixptr=(RGBTRIPLE*)( RowAddress[j] ); for(int i= 0; i< m_ImageWidth; i++) { pixptr[i].rgbtRed = pixptr[i].rgbtBlue = pixptr[i].rgbtGreen = m_lpHSIArray[k + i]; } } } break; } case INTENSITYIMAGE: { CreateHSIImage( INTENSITYIMAGE ); if( m_wImageDepth == 24 ) { for(int j= 0, k= 0; j< m_ImageHeight; j++, k += m_HSIImageWidth) { RGBTRIPLE* pixptr = (RGBTRIPLE*)( RowAddress[j] ); for(int i= 0; i< m_ImageWidth; i++) { pixptr[i].rgbtRed = pixptr[i].rgbtBlue = pixptr[i].rgbtGreen = m_lpHSIArray[k + i]; } } } break; } } } //*********************************************************** //*********************************************************** void CImage::BackUp() { if( m_lpDibArrayBuff == NULL) { NewBuffer(); } memcpy(m_lpDibArrayBuff, m_lpDibArray, m_ImageSize); } //*********************************************************** //*********************************************************** void CImage::ImgSwap() { if(m_lpDibArray == NULL) return; if(m_lpDibArrayBuff == NULL) BackUp(); P_BYTE *tmpImgPt = m_lpDibArray; m_lpDibArray = m_lpDibArrayBuff; m_lpDibArrayBuff = tmpImgPt; tmpImgPt = NULL; GenerateRowAddress(); } //*********************************************************** //*********************************************************** void CImage::CreateHSIImage(DWORD dwType) { if( m_lpHSIArray == NULL ) NewHSIImg(); #ifdef _DEBUG if( m_wImageDepth != 24 || m_lpHSIArray == NULL ) { AfxMessageBox("下标越界或图像色彩不对!!!"); AfxAbort(); } #endif //static DWORD OldType = 0; //double dRED, dGREEN, dBLUE; P_LONG i, j; P_BYTE *rgb; P_BYTE *Line = m_lpHSIArray; switch( dwType ) { case HUEIMAGE: { // Hue = (P_BYTE)( atan2( 0.7071 * (dGREEN - dBLUE), 0.816496 * dRED - 0.40824 * (dGREEN + dBLUE) ) // * 90.0 * 2.0 / 3.1415926 * 255.0 / 360.0); double temp = 90.0 * 2.0 / 3.1415926 * 255.0 / 360.0; double table1[512], table2[512], table3[512]; P_BYTE tmpr, tmpg, tmpb; for( j= 0; j< 512; j++ ) { table1[j] = 0.7071 * (j-255); table2[j] = 0.816496 * j; table3[j] = 0.40824 * j; } for( j= 0; j< m_HSIImageHeight; j++, Line += m_HSIImageWidth) { rgb = RowAddress[j]; for(i=0; i >4; rv = ColorIndex[index]; break; } case 8: { int index = RowAddress[y][x]; rv = ColorIndex[index]; break; } case 16: { WORD *pixptr = (WORD*)RowAddress[y]; WORD temp = pixptr[x]; rv.rgbtRed = (P_BYTE)( (temp&m_dwRBitMask) >> m_wlowRedBit ); rv.rgbtGreen = (P_BYTE)( (temp&m_dwGBitMask) >> m_wlowGreenBit ); rv.rgbtBlue = (P_BYTE)( (temp&m_dwBBitMask) ); break; } case 24: { RGBTRIPLE* pixptr = (RGBTRIPLE*)RowAddress[y]; rv = pixptr[x]; break; } case 32: { DWORD *pixptr = (DWORD*)RowAddress[y]; DWORD temp = pixptr[x]; rv.rgbtRed = (P_BYTE)( (temp&m_dwRBitMask) >> m_wlowRedBit ); rv.rgbtGreen = (P_BYTE)( (temp&m_dwGBitMask) >> m_wlowGreenBit ); rv.rgbtBlue = (P_BYTE)( temp&m_dwBBitMask ); break; } } return rv; } //*********************************************************** //*********************************************************** void CImage::SetRGBPixel(P_LONG x, P_LONG y,RGBTRIPLE color) { #ifdef _DEBUG if(!CheckPoint(x,y)||m_lpDibArray==NULL) { AfxMessageBox("下标越界或图像色彩不对!!!"); AfxAbort(); } #endif switch(m_wImageDepth) { case 8: { int index = RowAddress[y][x]; RowAddress[y][x] = (color.rgbtRed + color.rgbtGreen + color.rgbtBlue)/ 3; break; } case 16: { WORD *pixptr = (WORD*)RowAddress[y]; WORD temp = color.rgbtRed< > 8; rv.rgbtBlue = (P_BYTE) (color&0x00FF0000) >> 16; SetRGBPixel(x, y, rv); } //*********************************************************** //*********************************************************** P_BYTE CImage::GetGrayV(P_LONG x, P_LONG y) { #ifdef _DEBUG if(!CheckPoint(x,y)||m_wImageDepth!=8||m_lpDibArray==NULL) { AfxMessageBox("下标越界或非灰度图像!!!"); AfxAbort(); } #endif return RowAddress[y][x]; } P_BYTE CImage::GetGrayV(double x, double y) { int ix = int(x); int iy = int(y); double dx = x - ix; double dy = y - iy; if( ix < 0) { ix = 0; } else if( ix >= (m_ImageWidth-1) ) { ix = m_ImageWidth - 2; } if( iy < 0) { iy = 0; } else if( iy >= (m_ImageHeight- 1) ) { iy = m_ImageHeight - 2; } BYTE I11, I12, I21, I22; int I; I11 = RowAddress[ iy ][ ix ]; I12 = RowAddress[ iy ][ix+1]; I21 = RowAddress[iy+1][ ix ]; I22 = RowAddress[iy+1][ix+1]; I = (int)( (float)(I11 + (I12-I11) * dx) * (1.0 - dy) + (float)(I21 + (I22-I21) * dx) * dy + 0.5); return I>255 ? 255 : BYTE(I); } //*********************************************************** //*********************************************************** void CImage::SetGrayV(P_LONG x, P_LONG y,P_BYTE gray) { #ifdef _DEBUG if(!CheckPoint(x,y)||m_wImageDepth!=8||m_lpDibArray==NULL) { AfxMessageBox("下标越界或非灰度图像!!!"); AfxAbort(); } #endif RowAddress[y][x] = gray; } //*********************************************************** //*********************************************************** P_BYTE CImage::GetXYHueValue(P_LONG x, P_LONG y) { #ifdef _DEBUG if(!CheckPoint(x,y)||m_wImageDepth!=24||m_lpHSIArray==NULL) { AfxMessageBox("下标越界或非灰度图像!!!"); AfxAbort(); } #endif P_LONG y1 = m_HSIImageHeight - 1 - y; return m_lpHSIArray[y1 * m_HSIImageWidth + x]; } //*********************************************************** //*********************************************************** void CImage::ImageInfo() { CString msg; msg.Format("图像宽度: %5d\n图像高度: %5d\n数据宽度: %5d\n数据高度: %5d\n像素深度: %5d\n",m_ImageWidth,m_ImageHeight,m_nDibWidth,m_nDibHeight,m_wImageDepth); eImageType dImageType = GetImageType(); switch(dImageType) { case BinaryImage: { msg+="颜色数目: 2\n图像类型: 二值图像"; break; } case FourBitsImage: { msg+="颜色数目: 16\n图像类型: 4位彩色值图像"; break; } case IndexColorImage: { msg+="颜色数目: 256\n图像类型: 8位彩色图像"; break; } case IndexGrayImage: { msg+="颜色数目: 256\n图像类型: 8位灰度图像"; break; } case HighColorImage: { if(m_Is565RGBImage) msg+="颜色数目: 64K\n图像类型: 16位图像(565)"; else msg+="颜色数目: 64K\n图像类型: 16位图像(555)"; break; } case TrueColorImage: { msg+="颜色数目: 16M\n图像类型: 24位彩色图像"; break; } case UltraColorImage: { msg+="颜色数目: 4G\n图像类型: 32位彩色图像"; break; } } AfxMessageBox(msg); } //*********************************************************** //*********************************************************** WORD CImage::GetColorMapNum(int Depth) { switch(Depth) { case 1: return 2; case 4: return 16; case 8: return 256; default: return 0; } } //*********************************************************** //*********************************************************** eImageType CImage::GetImageType() { switch(m_wImageDepth) { case 1: return BinaryImage; case 4: return FourBitsImage; case 8: { int IsColorImage = 0; for(int gray= 0; gray < COLORCOUNT; gray++) { P_BYTE tr, tg, tb; tr = m_lpDibInfo->bmiColors[gray].rgbBlue; tg = m_lpDibInfo->bmiColors[gray].rgbGreen; tb = m_lpDibInfo->bmiColors[gray].rgbRed; BOOL bt =!( (tr==tg)&&(tg==tb)&&(tb==tr) ); if( bt ) { IsColorImage=1; break; } } if(IsColorImage) return IndexColorImage; else return IndexGrayImage; } case 16: return HighColorImage; case 24: return TrueColorImage; case 32: return UltraColorImage; default: return IllegalImage; } } //*********************************************************** //*********************************************************** void CImage::InitTrueColorInfo() { if( m_lpDibInfo != NULL ) { m_lpDibInfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); m_lpDibInfo->bmiHeader.biWidth = m_ImageWidth; m_lpDibInfo->bmiHeader.biHeight = m_ImageHeight; m_lpDibInfo->bmiHeader.biPlanes = 1; m_lpDibInfo->bmiHeader.biBitCount = 24; m_lpDibInfo->bmiHeader.biCompression = BI_RGB; m_lpDibInfo->bmiHeader.biSizeImage = m_ImageSize; m_lpDibInfo->bmiHeader.biXPelsPerMeter = 0; m_lpDibInfo->bmiHeader.biYPelsPerMeter = 0; m_lpDibInfo->bmiHeader.biClrUsed = m_wColorMapNum; m_lpDibInfo->bmiHeader.biClrImportant = 0; } } //*********************************************************** //*********************************************************** void CImage::InitGrayImageInfo() { if( m_lpDibInfo != NULL ) { m_lpDibInfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); m_lpDibInfo->bmiHeader.biWidth = m_ImageWidth; m_lpDibInfo->bmiHeader.biHeight = m_ImageHeight; m_lpDibInfo->bmiHeader.biPlanes = 1; m_lpDibInfo->bmiHeader.biBitCount = 8; m_lpDibInfo->bmiHeader.biCompression = BI_RGB; m_lpDibInfo->bmiHeader.biSizeImage = m_ImageSize; m_lpDibInfo->bmiHeader.biXPelsPerMeter = 0; m_lpDibInfo->bmiHeader.biYPelsPerMeter = 0; m_lpDibInfo->bmiHeader.biClrUsed = m_wColorMapNum; m_lpDibInfo->bmiHeader.biClrImportant = 0; if( m_wImageDepth == 8)// create the color table { for(int i= 0;i bmiColors[i].rgbBlue = (P_BYTE)i; m_lpDibInfo->bmiColors[i].rgbGreen = (P_BYTE)i; m_lpDibInfo->bmiColors[i].rgbRed = (P_BYTE)i; m_lpDibInfo->bmiColors[i].rgbReserved = 0; } BakupColorIndex(); } } } //*********************************************************** //*********************************************************** BOOL CImage::BakupColorIndex() { if( m_wImageDepth <= 8 ) { for(int i= 0; i< m_wColorMapNum; i++) { ColorIndex[i].rgbtBlue = m_lpDibInfo->bmiColors[i].rgbBlue; ColorIndex[i].rgbtGreen = m_lpDibInfo->bmiColors[i].rgbGreen; ColorIndex[i].rgbtRed = m_lpDibInfo->bmiColors[i].rgbRed; } return true; } return false; } void CImage::GenerateRowAddress() { if( RowAddress != NULL ) { delete []RowAddress; RowAddress = NULL; } RowAddress = new P_BYTE*[m_ImageHeight]; m_IsImageDownUp = m_lpDibInfo->bmiHeader.biHeight > 0; if( m_IsImageDownUp ) { RowAddress[m_nDibHeight-1] = m_lpDibArray; for(int i= m_nDibHeight- 2; i>=0 ; i--) { RowAddress[i] = RowAddress[i+1] + m_nDibWidth; } } else { RowAddress[0] = m_lpDibArray; for(int i= 1; i< m_nDibHeight; i++) { RowAddress[i] = RowAddress[i-1] + m_nDibWidth; } } } //*********************************************************** //*********************************************************** void CImage::AllocateMemory(BOOL IsExistRGBMask) { DeleteMe(); m_lpDibArray = new P_BYTE[m_ImageSize]; memset(m_lpDibArray, 0, m_ImageSize); if(m_lpDibArray == NULL) AfxThrowMemoryException(); //为m_hDibInfo图像信息头分配内存 DWORD DibInfoSize; if(!IsExistRGBMask) { DibInfoSize = m_wColorMapNum*sizeof(RGBQUAD) + sizeof(BITMAPINFOHEADER); } else { DibInfoSize = 3* sizeof(DWORD) + sizeof(BITMAPINFOHEADER); } m_pUseful = new P_BYTE[DibInfoSize]; if ( m_pUseful == NULL) { ReleaseDibArray(); AfxThrowMemoryException(); } m_lpDibInfo = (LPBITMAPINFO)m_pUseful; } //*********************************************************** //*********************************************************** void CImage::ReleaseCopyHandle() { if( m_hDIB != NULL ) { GlobalUnlock( m_hDIB ); GlobalFree( m_hDIB ); m_hDIB = NULL; } } //*********************************************************** //*********************************************************** HANDLE CImage::GetCopyHandle(CPoint LTp, CPoint RBp) { #ifdef _DEBUG if(!CheckRect(LTp,RBp)) { AfxMessageBox("下标越界!!!"); AfxAbort(); } #endif P_LONG width = (RBp.x - LTp.x+1); P_LONG height = (RBp.y - LTp.y+1); width = (width* m_wImageDepth/ 8 + 3) & ~3; P_LONG dwBitsSize = width * height; P_LONG DibInfoSize; DibInfoSize = sizeof(BITMAPINFOHEADER) + m_wColorMapNum*sizeof(RGBQUAD); dwBitsSize += (DibInfoSize + sizeof(BITMAPFILEHEADER)); m_hDIB = ::GlobalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT, dwBitsSize); LPSTR lpDIBHdr = (LPSTR) ::GlobalLock((HGLOBAL) m_hDIB); LPSTR lpDIBBits = lpDIBHdr + DibInfoSize; LPBITMAPINFO CopyDibInfo = (LPBITMAPINFO)lpDIBHdr; CopyDibInfo->bmiHeader = m_lpDibInfo->bmiHeader; CopyDibInfo->bmiHeader.biWidth = (RBp.x - LTp.x + 1); CopyDibInfo->bmiHeader.biHeight = height; CopyDibInfo->bmiHeader.biSizeImage = width * height; if( m_wImageDepth <= 8) { for(int i=0 ;i< m_wColorMapNum; i++) { CopyDibInfo->bmiColors[i] = m_lpDibInfo->bmiColors[i]; } } int OffsetX = LTp.x* m_wImageDepth/ 8; LPSTR lpTarget = lpDIBBits + (height-1) * width; for( P_LONG j= 0; j< height; j++, lpTarget -= width) { memcpy( lpTarget, RowAddress[LTp.y+ j] + OffsetX, width); } return m_hDIB; } //*********************************************************** //*********************************************************** void CImage::Inverse() { eImageType dImageType = GetImageType(); if(dImageType == IndexColorImage) { for(int gray=0;gray < m_wColorMapNum;gray++) { m_lpDibInfo->bmiColors[gray].rgbBlue = ~m_lpDibInfo->bmiColors[gray].rgbBlue ; m_lpDibInfo->bmiColors[gray].rgbGreen = ~m_lpDibInfo->bmiColors[gray].rgbGreen; m_lpDibInfo->bmiColors[gray].rgbRed = ~m_lpDibInfo->bmiColors[gray].rgbRed ; } } else { DWORD *lpTemp = (DWORD *)m_lpDibArray; P_LONG tempL = m_ImageSize / 4; for(P_LONG i= 0; i< tempL; i++) *lpTemp = ~*lpTemp++; } } //*********************************************************** //*********************************************************** void CImage::VerticalFlip() { P_BYTE *temp = new P_BYTE[m_nDibWidth]; // Inverse the IMG format image int dim = m_ImageHeight / 2; for(int i = 0;i < dim ;i++) { memcpy( temp, RowAddress[i], m_nDibWidth); memcpy( RowAddress[i], RowAddress[m_nDibHeight-1-i], m_nDibWidth); memcpy( RowAddress[m_nDibHeight-1-i] , temp, m_nDibWidth); } if(temp != NULL) delete []temp; } //*********************************************************** //*********************************************************** void CImage::HorizontalFlip() { if( m_wImageDepth < 8) return; int dim = m_ImageWidth / 2; int Last = (m_ImageWidth - 1)* m_wImageDepth/ 8; switch( m_wImageDepth ) { case 8: { P_BYTE *fp, *bp, swap; for(int j= 0; j< m_ImageHeight; j++) { fp = RowAddress[j]; bp = RowAddress[j] + Last; for(int i = 0;i < dim ;i++) { swap = *fp; *fp++ = *bp; *bp-- = swap; } } break; } case 16: { WORD *fp, *bp, swap; for(int j=0; j bmiHeader.biWidth = m_ImageWidth; m_lpDibInfo->bmiHeader.biHeight = m_IsImageDownUp ? m_ImageHeight : -m_ImageHeight; m_lpDibInfo->bmiHeader.biSizeImage = m_ImageSize; m_lpDibArray = new P_BYTE[m_ImageSize]; if(m_lpDibArray == NULL) AfxThrowMemoryException(); BYTE **lpBRowAddress = new BYTE*[m_OldImageHeight]; long i, j; if( m_IsImageDownUp ) { lpBRowAddress[m_OldImageHeight- 1] = m_lpDibArrayBuff; for(i= m_OldImageHeight- 2; i>=0 ; i--) { lpBRowAddress[i] = lpBRowAddress[i+1] + m_OldnDibWidth; } } else { lpBRowAddress[0] = m_lpDibArrayBuff; for(i= 1; i< m_OldImageHeight; i++) { lpBRowAddress[i] = lpBRowAddress[i-1] + m_OldnDibWidth; } } GenerateRowAddress(); DWORD start = GetTickCount(); if( Clockwise ) { switch(m_wImageDepth) { case 8: { for(j= 0; j< m_OldImageHeight; j++) { for(i= 0; i< m_OldImageWidth; i++) RowAddress[i][m_OldImageHeight- j- 1] = lpBRowAddress[j][i]; } break; } case 16: { WORD *BRowAddress, *fp; for(P_LONG j= 0; j< m_OldImageHeight; j++) { BRowAddress = (WORD*)(lpBRowAddress[j]); for(P_LONG i= 0; i< m_OldImageWidth; i++) { fp = (WORD*)RowAddress[i]; fp[m_OldImageHeight- j- 1] = BRowAddress[i]; } } break; } case 24: { RGBTRIPLE *BRowAddress, *fp; for(P_LONG j= 0; j< m_OldImageHeight; j++) { BRowAddress = (RGBTRIPLE*)(lpBRowAddress[j]); for(P_LONG i= 0; i< m_OldImageWidth; i++) { fp = (RGBTRIPLE*)RowAddress[i]; fp[m_OldImageHeight- j- 1] = BRowAddress[i]; } } break; } case 32: { DWORD *BRowAddress, *fp; for(P_LONG j= 0; j< m_OldImageHeight; j++) { BRowAddress = (DWORD*)(lpBRowAddress[j]); for(P_LONG i= 0; i< m_OldImageWidth; i++) { fp = (DWORD*)RowAddress[i]; fp[m_OldImageHeight- j- 1] = BRowAddress[i]; } } break; } } } else { switch(m_wImageDepth) { case 8: { for(j= 0; j< m_OldImageHeight; j++) { for(i= 0; i< m_OldImageWidth; i++) RowAddress[m_ImageHeight- i- 1][j] = lpBRowAddress[j][i]; } break; } case 16: { WORD *BRowAddress, *fp; for(P_LONG j= 0; j< m_OldImageHeight; j++) { BRowAddress = (WORD*)(lpBRowAddress[j]); for(P_LONG i= 0; i< m_OldImageWidth; i++) { fp = (WORD*)RowAddress[m_ImageHeight- i- 1]; fp[j] = BRowAddress[i]; } } break; } case 24: { RGBTRIPLE *BRowAddress, *fp; for(P_LONG j= 0; j< m_OldImageHeight; j++) { BRowAddress = (RGBTRIPLE*)(lpBRowAddress[j]); for(P_LONG i= 0; i< m_OldImageWidth; i++) { fp = (RGBTRIPLE*)RowAddress[m_ImageHeight- i- 1]; fp[j] = BRowAddress[i]; } } break; } case 32: { DWORD *BRowAddress, *fp; for(P_LONG j= 0; j< m_OldImageHeight; j++) { BRowAddress = (DWORD*)(lpBRowAddress[j]); for(P_LONG i= 0; i< m_OldImageWidth; i++) { fp = (DWORD*)RowAddress[m_ImageHeight- i- 1]; fp[j] = BRowAddress[i]; } } break; } } } DWORD use = GetTickCount() - start; TRACE("use = %d\n ", use); if(m_lpDibArrayBuff != NULL) ReleaseBuffer(); if(lpBRowAddress != NULL) delete []lpBRowAddress; } //--------------------------------------------------------------------- // Clipboard support // Function: CopyHandle (from SDK DibView sample clipbrd.c) // // Purpose: Makes a copy of the given global memory block. Returns // a handle to the new memory block (NULL on error). // // Routine stolen verbatim out of ShowDIB. // // Parms: h == Handle to global memory to duplicate. // // Returns: Handle to new global memory block. // //--------------------------------------------------------------------- HANDLE CopyHandle (HANDLE h) { P_BYTE *lpCopy; P_BYTE *lp; HANDLE hCopy; DWORD dwLen; if (h == NULL) return NULL; dwLen = ::GlobalSize((HGLOBAL) h); if ((hCopy = (HANDLE) ::GlobalAlloc (GHND, dwLen)) != NULL) { lpCopy = (P_BYTE *) ::GlobalLock((HGLOBAL) hCopy); lp = (P_BYTE *) ::GlobalLock((HGLOBAL) h); while (dwLen--) *lpCopy++ = *lp++; ::GlobalUnlock((HGLOBAL) hCopy); ::GlobalUnlock((HGLOBAL) h); } return hCopy; }