⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 picture.cpp

📁 高速公路收费系统车道软件. 功能: 1 检测公路过往车辆 2 收费过程控制和数据采集 3 车辆信息和图片上传服务器.
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// Picture.cpp: implementation of the CImageProcess class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "lane_new.h"
#include "Picture.h"
#include "DSStream.h"

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

#ifdef __cplusplus
	extern "C" {
#endif // __cplusplus
#define HAVE_BOOLEAN
#include "jpeglib.h"

#ifdef __cplusplus
	}
#endif // __cplusplus

extern CLane_newApp theApp;
extern BYTE * pData;

#include <setjmp.h>
#include <AfxOle.h>

struct ErrorStruct {
  struct jpeg_error_mgr pub;	// "public" fields
  jmp_buf setjmp_buffer;		// for return to caller
};
typedef struct ErrorStruct *JpegErrorPtr;

METHODDEF(void) ErrorExit(j_common_ptr Info);

METHODDEF(void) ErrorExit(j_common_ptr Info)
{
	JpegErrorPtr Err=(JpegErrorPtr)Info->err;
	char Buffer[JMSG_LENGTH_MAX];
	(*Info->err->format_message)(Info,Buffer);
	DWORD i=1;
	SendMessageTimeout(AfxGetMainWnd()->m_hWnd,WM_ABNORMAL,0,(LPARAM)"生成JPEG文件出错\n",SMTO_BLOCK,200,&i);
	longjmp(Err->setjmp_buffer,1);
}

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

CImageProcess::CImageProcess()
{
}

/*	从剪切板中读取图象数据 */
void CImageProcess::ProcessPicture(char *FileName,int Quality)
{
	DWORD RetValue=1;
	try{
	/*if(strlen(FileName)<20) return;
	COleDataObject OleData;
	if(OleData.AttachClipboard()==0){	//将剪切板联系到OLE类
		SendMessageTimeout(AfxGetMainWnd()->m_hWnd,WM_ABNORMAL,0,(LPARAM)"无法和剪贴板联结\n",SMTO_BLOCK,200,&RetValue);
		return;
	}
	if(OleData.IsDataAvailable(CF_DIB)==0){//剪切板数据是否为BMP图片?
		OleData.Release();
		SendMessageTimeout(AfxGetMainWnd()->m_hWnd,WM_ABNORMAL,0,(LPARAM)"剪贴板上不是图片数据\n",SMTO_BLOCK,200,&RetValue);
		return;
	}
	HGLOBAL hObj=OleData.GetGlobalData(CF_DIB);//获取OLE类句柄
	if(hObj==NULL){
		OleData.Release();
		SendMessageTimeout(AfxGetMainWnd()->m_hWnd,WM_ABNORMAL,0,(LPARAM)"获取剪贴板数据失败\n",SMTO_BLOCK,200,&RetValue);
		return;
	}
	pData=(unsigned char *)GlobalLock(hObj);//锁定类句柄并获取图象数据
	unsigned char *pData=NULL; 
	if(pData==NULL){
		OleData.Release();
		SendMessageTimeout(AfxGetMainWnd()->m_hWnd,WM_ABNORMAL,0,(LPARAM)"转换HGLOBAL为指针失败\n",SMTO_BLOCK,200,&RetValue);
		return;
	}*/
	if(pData!=NULL){
		CompressPicture((unsigned char *)pData,FileName,Quality);//将BMP图象压缩为JPEG图象
		delete [] pData;
		pData=NULL;
	}
	//GlobalUnlock(hObj);				//解锁类句柄
	//GlobalFree(hObj);				//释放类句柄
	//OleData.Release();				//释放剪切板数据
	}
	catch(...){
		SendMessageTimeout(AfxGetMainWnd()->m_hWnd,WM_ABNORMAL,0,(LPARAM)"CImageProcess::ProcessPicture()出现异常\n",SMTO_BLOCK,500,&RetValue);
	}
}

/*	利用外来的函数库压缩图片 */
void CImageProcess::CompressPicture(unsigned char *pData,char *FileName,int Quality)
{
	DWORD RetValue=1;
	try{
	BITMAPINFOHEADER BmpInfoHeader;
	int Length=sizeof(BITMAPINFOHEADER);
	memmove(&BmpInfoHeader,pData,Length);
	int ReadCount=Length;
	if((BmpInfoHeader.biCompression==BI_RLE4)||(BmpInfoHeader.biCompression==BI_RLE8)){
		SendMessageTimeout(AfxGetMainWnd()->m_hWnd,WM_ABNORMAL,0,(LPARAM)"剪贴板中的图片为压缩格式\n",SMTO_BLOCK,200,&RetValue);
		return;
	}
	if(BmpInfoHeader.biSizeImage==0){	//BI_RGB格式的BMP文件该值可以为0
		BmpInfoHeader.biSizeImage=(((BmpInfoHeader.biWidth*BmpInfoHeader.biBitCount+31)>>8)<<2)*BmpInfoHeader.biHeight;
	}
//	if(BmpInfoHeader.biBitCount!=24){
//		SendMessageTimeout(AfxGetMainWnd()->m_hWnd,WM_ABNORMAL,0,(LPARAM)"剪贴板中的图片非24为BMP格式\n",SMTO_BLOCK,200,&RetValue);
//		return;
//	}
	unsigned char *DataBuff=NULL;;
	if((DataBuff=new unsigned char[BmpInfoHeader.biWidth*BmpInfoHeader.biHeight*3])==NULL){
		SendMessageTimeout(AfxGetMainWnd()->m_hWnd,WM_ABNORMAL,0,(LPARAM)"内存不足无法压缩图片\n",SMTO_BLOCK,200,&RetValue);
		return;
	}
	long RowSize=BmpInfoHeader.biWidth*3;
	unsigned char tmpStr[14];
	int Row,Col,tmpValue;
	for(Row=BmpInfoHeader.biHeight-1;Row>=0;Row--){
		switch(BmpInfoHeader.biBitCount){
		case 24:
/*	24位图象每个像素用三个字节表示,分别为蓝、绿、红	*/
			for(Col=0;Col<BmpInfoHeader.biWidth;Col++){
				memmove(tmpStr,pData+ReadCount,3);
				*(DataBuff+Row*RowSize+Col*3)=tmpStr[2];
				*(DataBuff+Row*RowSize+Col*3+1)=tmpStr[1];
				*(DataBuff+Row*RowSize+Col*3+2)=tmpStr[0];
				ReadCount+=3;
			}
			while(ReadCount&3){
				ReadCount++;
			}
			break;
		case 16:
/*	16位图象每个像素用2个字节表示,红、绿、蓝各用5位,最高位未用
	如果直接将红、绿、蓝的颜色值取出进行压缩,因为每种颜色的色度
	范围为0-255,而我们只使用了0-31,从而导致图片趋向黑色。如果
	人为地将色度值乘以8,则图象色彩失真很厉害,因此我认为必须使用
	调色板,但我在图象数据中无法找到调色板信息(暂时将色度值扩展8
	倍,以后如果确实需要处理16位图象,再想办法)	*/
			if(BmpInfoHeader.biCompression==BI_RGB){
				for(Col=0;Col<BmpInfoHeader.biWidth;Col++){
					tmpValue=pData[ReadCount]*256+pData[ReadCount+1];
					*(DataBuff+Row*RowSize+Col*3)=((tmpValue&0x7c00)>>10)+128;
					*(DataBuff+Row*RowSize+Col*3+1)=((tmpValue&0x3e0)>>5)+128;
					*(DataBuff+Row*RowSize+Col*3+2)=(tmpValue&0x1f)+128;
					ReadCount+=2;
				}
				while(ReadCount&2){
					ReadCount++;
				}
			}
			break;
		}
	}
/***********************************************************/
/*	RGBQUAD *ColorMap=NULL;
	switch(BmpInfoHeader.biBitCount){
	case 24:							//24位真彩色BMP文件无调色板
		break;
	case 1:
	case 4:
	case 8:
		if(BmpInfoHeader.biClrUsed==0){	//若为0,调色板颜色数目用最大值
			BmpInfoHeader.biClrUsed=1<<BmpInfoHeader.biBitCount;
		}
		Length=BmpInfoHeader.biClrUsed;
		if((ColorMap=new RGBQUAD[BmpInfoHeader.biClrUsed])==NULL){
			SendMessage(AfxGetMainWnd()->m_hWnd,WM_ABNORMAL,0,(LPARAM)"内存不足,图片压缩忽略\n");
			return;
		}
		for(int i=0;i<Length;i++){
			ColorMap[i].rgbBlue=pData[ReadCount+i*4];
			ColorMap[i].rgbGreen=pData[ReadCount+i*4+1];
			ColorMap[i].rgbRed=pData[ReadCount+i*4+2];
			ColorMap[i].rgbRed=pData[ReadCount+i*4+3];
		}
		ReadCount+=4*Length;
		break;
	}
	unsigned char *DataBuff=NULL;;
	if((DataBuff=new unsigned char[BmpInfoHeader.biWidth*BmpInfoHeader.biHeight*3])==NULL){
		if(ColorMap!=NULL) delete [] ColorMap;
		ColorMap=NULL;
		SendMessage(AfxGetMainWnd()->m_hWnd,WM_ABNORMAL,0,(LPARAM)"内存不足,图片压缩忽略\n");
		return;
	}
	long RowSize=BmpInfoHeader.biWidth*3;
	char tmpStr[3];
	int Row,Col;
	for(Row=BmpInfoHeader.biHeight-1;Row>=0;Row--){
		if(BmpInfoHeader.biBitCount==24){
			for(Col=0;Col<BmpInfoHeader.biWidth;Col++){
				memmove(tmpStr,pData+ReadCount,3);
				*(DataBuff+Row*RowSize+Col*3)=tmpStr[2];
				*(DataBuff+Row*RowSize+Col*3+1)=tmpStr[1];
				*(DataBuff+Row*RowSize+Col*3+2)=tmpStr[0];
				ReadCount=ReadCount+3;
			}
		} else {
			UINT PixelMask=(1<<BmpInfoHeader.biBitCount)-1;
			for(Col=0;Col<BmpInfoHeader.biWidth;Col++){
				tmpStr[0]=pData[ReadCount];
				ReadCount++;
				int Index=(tmpStr[0]>>BmpInfoHeader.biBitCount)&PixelMask;
				*(DataBuff+Row*RowSize+Col*3+2)=ColorMap[Index].rgbBlue;
				*(DataBuff+Row*RowSize+Col*3+1)=ColorMap[Index].rgbGreen;
				*(DataBuff+Row*RowSize+Col*3)=ColorMap[Index].rgbRed;
			}
		}
	}
	if(ColorMap!=NULL){
		delete [] ColorMap;
		ColorMap=NULL;	*/
/*******************************************/
	iImageWidth=BmpInfoHeader.biWidth;
	OverlayPlazaNO(DataBuff);
//	从文件名中获取车辆信息而不从CTransInfo中获取的原因有:
//	1、避免不同线程间访问冲突
//	2、此时CTransInfo中的数据可能已经被清空
	int nLen=strlen(PICTURE_PATH)+1;
//	获取车道号码
	memset(tmpStr,0,14);
	memmove(tmpStr,FileName+nLen+P_LANE_NO,2);
	OverlayLaneNO(DataBuff,tmpStr);
//	获取当前时间
	memset(tmpStr,0,14);
	memmove(tmpStr,FileName+nLen+P_DATE,12);
	OverlayTime(DataBuff,tmpStr);
//	获取收费员号码
	memset(tmpStr,0,14);
	memmove(tmpStr,FileName+nLen+P_COLLECT_NO,5);
	OverlayCollectNO(DataBuff,tmpStr);
//	获取车型
	memset(tmpStr,0,14);
	tmpStr[0]=FileName[nLen+P_BUS_CLASS];
	OverlayBusClass(DataBuff,tmpStr[0]-'0');
//	获取车情
	memset(tmpStr,0,14);
	tmpStr[0]=FileName[nLen+P_BUS_TYPE];
//	如果有违章,则车情改为违章,用'9'表示;若有更改,则车情改为
//	更改,用'8'表示
	if(FileName[nLen+P_MODIFY]!='0') tmpStr[0]='8';
	if(FileName[nLen+P_VIOLATE]!='0') tmpStr[0]='9';
	OverlayBusType(DataBuff,tmpStr[0]);
//	获取车牌
	memset(tmpStr,0,14);
	memmove(tmpStr,FileName+nLen+P_BUS_NO,10);
	OverlayBusNO(DataBuff,tmpStr);
//	获取价格
	memset(tmpStr,0,14);
	memmove(tmpStr,FileName+nLen+P_FARE,4);
	OverlayFare(DataBuff,tmpStr);
//	将文件名中的价格项扣除
	memset(FileName+nLen+P_FARE,0,4);
	FILE *fp1;
	if((fp1=fopen(FileName,"wb"))==NULL){
		SendMessageTimeout(AfxGetMainWnd()->m_hWnd,WM_ABNORMAL,0,(LPARAM)"产生JPEG文件错误\n",SMTO_BLOCK,200,&RetValue);
		return;
	}
	struct jpeg_compress_struct Info;	//以下完成JEPG文件的压缩
	struct ErrorStruct JpegError;
	Info.err=jpeg_std_error(&JpegError.pub);
	JpegError.pub.error_exit=ErrorExit;
	if(setjmp(JpegError.setjmp_buffer)) {
		fclose(fp1);
		jpeg_destroy_compress(&Info);	//压缩失败,上传BMP文件
		return;
	}
	jpeg_create_compress(&Info);	//初始化JPEG压缩类
	jpeg_stdio_dest(&Info,fp1);
	Info.image_width=BmpInfoHeader.biWidth;
	Info.image_height=BmpInfoHeader.biHeight;
	Info.input_components=3;		//对RGB图象,每象素3个元素
	Info.in_color_space=JCS_RGB;
	jpeg_set_defaults(&Info);
	jpeg_set_quality(&Info,Quality,TRUE);
	jpeg_start_compress(&Info,TRUE);
	int RowStep=BmpInfoHeader.biWidth*3;
	while(Info.next_scanline<Info.image_height){
		LPBYTE OutRow;
		OutRow=DataBuff+(Info.next_scanline*BmpInfoHeader.biWidth*3);
		jpeg_write_scanlines(&Info,&OutRow,1);
	}
	jpeg_finish_compress(&Info);
	fclose(fp1);
	jpeg_destroy_compress(&Info);
	if(DataBuff!=NULL){
		delete [] DataBuff;				//压缩成功,上传JPEG文件
		DataBuff=NULL;
	}
	SendMessageTimeout(AfxGetMainWnd()->m_hWnd,WM_SEND_PICTURE,0,(LPARAM)FileName,SMTO_BLOCK,500,&RetValue);
	}
	catch(...){
		SendMessageTimeout(AfxGetMainWnd()->m_hWnd,WM_ABNORMAL,0,(LPARAM)"CImageProcess::CompressPicture()出现异常\n",SMTO_BLOCK,500,&RetValue);
	}
}

void CImageProcess::CreateHZK()
{
	bOverlayOK=FALSE;
	DWORD RetValue=1;
	try{
		FILE *fp1;
		char strFileName[130];
		memset(strFileName,0,130);
		theApp.GetFullPath(strFileName);
		strcat(strFileName,"hzk24k");
//	将要叠加的汉字从字库文件中读入内存		
		if((fp1=fopen(strFileName,"rb"))==NULL){
			SendMessageTimeout(AfxGetMainWnd()->m_hWnd,WM_ABNORMAL,0,(LPARAM)"无法打开24点阵字库文件\n",SMTO_BLOCK,500,&RetValue);
			return;
		}
		char tmpStr[MAX_SYMBOL_COUNT];
//	将交易汉字读入内存
		memset(tmpStr,0,MAX_SYMBOL_COUNT);
		memmove(tmpStr,"正常车免征车月票车军警车违章车型车道车队\
			收费员价格更改\
			闽粤军警浙新冀晋苏黄吉琼宁皖鲁豫蓝川渝贵云藏陕京\

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -