📄 envyimage.cpp
字号:
// EnvyImage.cpp: implementation of the CEnvyImage class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "TVI.h"
#include "EnvyImage.h"
#include "io.h"
#include "math.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CEnvyImage::CEnvyImage()
{
m_lpClusterImage = NULL;
m_bitmapInfo = NULL;
m_lpData = NULL; m_lpImage = NULL;
m_gray = 1; // 设置读入图象就显示灰度影象
m_hpalette = NULL;
m_hClusterPalette = NULL;
m_hFile = NULL; // 初始化文件句柄
m_band = 0;
m_displayCluster = 0;
m_bitmapInfoCluster = 0;
}
CEnvyImage::~CEnvyImage()
{
Empty();
DetachMapFile();
if(m_hpalette!=NULL)
{
::DeleteObject(m_hpalette);
}
if(m_hClusterPalette!=NULL)
{
::DeleteObject(m_hClusterPalette);
}
}
//////////////////////////////////////////////////////////////////////////////////////
// 参数说明: const char* lpszPahtName; // 文件名称
// int &row,&col; // 返回图像的行列数
// int &band; // 返回图像的波段数
// 函数功能:该函数用于读取图像的头文件
// 返回值: 读取成功返回1,否则返回0
//////////////////////////////////////////////////////////////////////////////////////
int CEnvyImage::OpenHeader(const char *lpszPathName, int &row, int &col, int &band,int &offset,int& order)
{
FILE* file;
char tempChar[300]; // 中间字符串
char str[20],stro[10];
float xStart,yStart;
float xRes,yRes;
int norder;
// 打开文件
if((file=fopen(lpszPathName,"r"))==0)
return 0;
// 读取关键字
fgets(tempChar,300,file);
// 检查文件是否为对应得ENVI文件
if(strcmp(tempChar,"ENVI\n")!=0) return 0;
while (fgets(tempChar,300,file)) {
// 读取前一个字符串
sscanf(tempChar,"%s",str);
// 描述信息,目前没有用到
if(strcmp(str,"description")==0)
{
continue;
}
// 读取行
if(strcmp(str,"samples")==0)
{
sscanf(tempChar,"samples = %d",&col);
continue;
}
// 读取列
if(strcmp(str,"lines")==0)
{
sscanf(tempChar,"lines = %d",&row);
continue;
}
// 波段数
if(strcmp(str,"bands")==0)
{
sscanf(tempChar,"bands = %d",&band);
continue;
}
// 存储方式
if(strcmp(str,"interleave")==0)
{
sscanf(tempChar,"interleave = %s",stro);
// 比较,决定该影象文件是哪一种
if(strcmp(stro,"bsq")==0)
{
order = 0;
}
if(strcmp(stro,"bip")==0)
{
order = 1;
}
continue;
}
// 文件偏移位置
if(strcmp(str,"header")==0)
{
sscanf(tempChar,"header offset = %d",&offset);
continue;
}
// 读取起始点坐标
if(strcmp(str,"x")==0)
{
sscanf(tempChar,"x start = %f",&xStart);
continue;
}
if(strcmp(str,"y")==0)
{
sscanf(tempChar,"y start = %f",&yStart);
continue;
}
// 读取投影参数,目前没有用到
if(strcmp(str,"map")==0)
{
continue;
}
// 读取影像分辨率
if(strcmp(str,"pixel")==0)
{
sscanf(tempChar,"pixel size = {%f, %f, units=Meters}",&xRes,&yRes);
continue;
}
// 读取存放顺序
if(strcmp(str,"byte")==0)
{
sscanf(tempChar,"byte order = %d}",&norder);
continue;
}
// 读取波段名称,目前未用到
if(strcmp(str,"band")==0)
{
continue;
}
};
fclose(file);
return 1;
}
//////////////////////////////////////////////////////////////////////////
// 函数功能:该函数用于收回分配的内存
//////////////////////////////////////////////////////////////////////////
void CEnvyImage::Empty()
{
if(m_lpImage!=NULL)
{
GlobalUnlock(m_globalMemory);
GlobalFree(m_globalMemory);
}
if(m_bitmapInfo!=NULL)
{
delete []m_bitmapInfo; m_bitmapInfo=NULL;
}
if(m_bitmapInfoCluster!=NULL)
{
delete []m_bitmapInfoCluster; m_bitmapInfoCluster = NULL;
}
if(m_lpClusterImage!=NULL)
{
delete []m_lpClusterImage; m_lpClusterImage = NULL;
}
}
//////////////////////////////////////////////////////////////////////////
// 参数说明:LPCSTR lpszPathName; // 文件路径
// 函数功能:该函数用于读取影象数据,参数为影象的头文件路径
//////////////////////////////////////////////////////////////////////////
int CEnvyImage::LoadImage(LPCSTR lpszPathName)
{
// 清空影象数据
Empty();
DetachMapFile();
m_gray = 1; // 设置只显示灰度影象
char datafile[256];
// 读取头文件
if(!OpenHeader(lpszPathName,m_imageRow,m_imageCol,m_band,m_offSet,m_pixelOrder))
{
// 读取头文件出错
AfxMessageBox("读取头文件出错!");
return -1;
}
// 开辟内存空间
m_imageSaveCol = (m_imageCol*8+31)/32*4;
int nMemory = (m_imageCol*24+31)/32*4;
m_globalMemory = GlobalAlloc(GHND, m_imageRow*nMemory*sizeof(BYTE));
m_lpImage = (BYTE*)GlobalLock(m_globalMemory);
if(m_lpImage==0)
{
Empty(); return -1;
}
// 读取影象文件
strcpy(datafile,lpszPathName);
*strrchr(datafile,'.') = 0x00;
strcat(datafile,".raw");
if(_access(datafile,00)!=0)
{
Empty(); return -1;
}
// 形成文件映射
AttachMapFile(datafile,TRUE);
// 构成显示文件的数据块
return 1;
}
//////////////////////////////////////////////////////////////////////////
// 参数说明:BITMAPINFO &bitmapInfo; // 信息头
// int row,col; // 文件长宽
// int savecol; // 每行存储的长度
// int gray; // 标志是否为彩色影象
// 函数功能:形成用于显示的头文件
//////////////////////////////////////////////////////////////////////////
void CEnvyImage::CreateImageHeader(BITMAPINFO &bitmapInfo,int row,int col,int saveCol,int gray)
{
// 设置每个象素的位数
bitmapInfo.bmiHeader.biBitCount = 24;
bitmapInfo.bmiHeader.biHeight = row;
bitmapInfo.bmiHeader.biWidth = col;
bitmapInfo.bmiHeader.biCompression = BI_RGB;
bitmapInfo.bmiHeader.biClrUsed = 0;
bitmapInfo.bmiHeader.biClrImportant = 0;
bitmapInfo.bmiHeader.biXPelsPerMeter = 0;
bitmapInfo.bmiHeader.biYPelsPerMeter = 0;
bitmapInfo.bmiHeader.biSize = sizeof(BITMAPINFO);
bitmapInfo.bmiHeader.biSizeImage = row*saveCol;
bitmapInfo.bmiHeader.biPlanes = 1;
}
//////////////////////////////////////////////////////////////////////////
// 参数说明:LPBYTE lpImageSource; // 源影象指针
// LPBYTE lpImageTarger; // 目标影象数据指针
// BITMAPINFO* bitmap; // 创建的信息头
// int red, green, blue; // rgb对应的不同波段
// int band,order; // 波段个数和排列次序
// int gray; // 是否为彩色显示
// int row,col,saveCol; // 影象长宽和存储时对应的真实宽度
// 函数功能:该函数用于创建显示的影象
//////////////////////////////////////////////////////////////////////////
int CEnvyImage::CreateImage(LPBYTE lpImageSource, LPBYTE lpImageTarget, BITMAPINFO* bitmap,int red, int green, int blue, int band, int order, int gray, int row, int col, int saveCol)
{
LPBYTE lpSource;
int i,j;
m_displayCluster = 0; // 设置为不显示聚类结果模式
// 创建头文件
// CreateImageHeader(bitmap,row,col,saveCol,gray);
CreatRawHeader(col,row,saveCol,gray,m_hpalette,m_bitmapInfo);
// 形成数据文件
if(gray==1)
{
memset(lpImageTarget,0L,row*saveCol);
switch(order) {
case 1:
{
lpSource = lpImageSource;
for(i=0; i<row; i++)
{
for(j=0; j<col; j++)
{
*(lpImageTarget+(row-1-i)*saveCol+j) = *(lpImageSource+(i*col+j-1)*band+red-1);
}
}
}
break;
case 0:
{
lpSource = lpImageSource+(red-1)*col*row;
for(i=0; i<row; i++)
{
for(j=0; j<col; j++)
{
*(lpImageTarget+(row-1-i)*saveCol+j) = *(lpSource+i*col+j);
}
}
}
break;
default:
return -1;
}
}
else
{
memset(lpImageTarget,0L,row*saveCol);
switch(order) {
case 1:
{
lpSource = lpImageSource;
for(i=0; i<row; i++)
{
for(j=0; j<col; j++)
{
*(lpImageTarget+(row-1-i)*saveCol+3*j) = *(lpImageSource+(i*col+j-1)*band+red-1);
*(lpImageTarget+(row-1-i)*saveCol+3*j+1) = *(lpImageSource+(i*col+j-1)*band+green-1);
*(lpImageTarget+(row-i-1)*saveCol+3*j+2) = *(lpImageSource+(i*col+j-1)*band+blue-1);
}
}
}
break;
case 0:
{
lpSource = lpImageSource;
for(i=0; i<row; i++)
{
for(j=0; j<col; j++)
{
*(lpImageTarget+(row-i-1)*saveCol+3*j) = *(lpImageSource+i*col+j+(red-1)*col*row);
*(lpImageTarget+(row-i-1)*saveCol+3*j+1) = *(lpImageSource+i*col+j+(green-1)*col*row);
*(lpImageTarget+(row-i-1)*saveCol+3*j+2) = *(lpImageSource+i*col+j+(blue-1)*col*row);
}
}
}
break;
default:
return -1;
}
}
return 1;
}
//////////////////////////////////////////////////////////////////////////
// 函数功能:该函数用于创建显示的影象
//////////////////////////////////////////////////////////////////////////
void CEnvyImage::CreateDisplatImage(int red, int green, int blue, int gray)
{
if(m_lpData==0) return;
// 检查是否需要重新分配存储空间内存
if(m_gray!=gray)
{
m_gray = gray;
m_imageSaveCol = (m_imageCol*gray*8+31)/32*4;
// if(m_lpImage!=NULL)
// {
// delete []m_lpImage;
// m_lpImage = NULL;
// }
// m_lpImage = new BYTE [m_imageSaveCol*m_imageRow];
}
CreateImage((LPBYTE)m_lpData,m_lpImage,m_bitmapInfo,red,green,blue,m_band,m_pixelOrder,gray,m_imageRow,m_imageCol,m_imageSaveCol);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -