📄 setscanner.cpp
字号:
lp2=lp2+BytesPerRow;
}
lpBits2=lpStart2;
memcpy(lpBits2,lp1,y1*BytesPerRow);
lpBits2=lpBits2+y1*BytesPerRow;
lp1=lp1+y1*BytesPerRow;
}//结束写文件
count++;
bytesout+=BytesWritten;
RowsWritten=bytesout/BytesPerRow;
}//执行循环,直到结束读取数据
//写文件
//彩色图像RGB的数值在存储文件时对调为BGR,这是BMP文件格式的要求
if(pScanner->m_nColor==16777216)
{
PreviewBitmap.Write(lpStart3+y1*dwBytesInLine, dwBytesBMP-y1*dwBytesInLine);
}
else //存储灰度或者黑白图像文件
{
PreviewBitmap.Write(lpStart3+y1*dwBytesInLineH, dwBytesBMPH-y1*dwBytesInLineH);
}
PreviewBitmap.Close();
//删除进程条,释放内存
delete pScanningProgress;
GlobalUnlock(hbuffer2);
GlobalFree(hbuffer2);
GlobalUnlock(hMem);
GlobalFree(hMem);
}
//--------------------2004年2月18日增加---------------------------------//
// 扫描校正方式设置及校正参数获取 //
// Twain 扫描、文件扫描及预览扫描时调用,用于一次扫描任务前设定扫描校 //
// 正方式,下传的相关校正用参数及偏色系数由jiaose.ini内的相关参数项获取//
// 返回:1-->底层校正设置正常 0-->底层校正设置出现故障 //
//----------------------------------------------------------------------//
int CSetScanner::Scan_JZMode() //设置扫描校正方式SCSI命令包:扫描校正方式设置及校正参数获取
{
//从jiaose.ini中读取扫描校正方式字节
// int JZMode= GetPrivateProfileInt("ScanCai_Mod ScnCaiMod","JZMode",1,InitDir2);
/*底层使用的说明校正方式字节的定义:
0-底层校正扫描
1-底层校正精扫描
2-校正参数扫描
3-校正参数精扫描
4-不校正扫描
6-感光校正参数扫描
8-偏移校正参数扫描
10-增益校正参数扫描
上层选择输入值为:0~7(8项选择输入选项),下传时需进行有效性判断和转换:
JZMode>7,强制JZMode=2
JZMode=5、6、7时,分别转换为6、8、10后再下传
*/
int JZMode= GetPrivateProfileInt("ScanCai_Mod","ScnCaiMod",1,InitDir2);
switch (JZMode)
{
case 0:
case 1:
case 2:
case 3:
case 4:
break;
case 5:
JZMode=6;
break;
case 6:
JZMode=8;
break;
case 7:
JZMode=10;
break;
default:
JZMode=2;
break;
}
Stp_Para_INI(); //初始化Def_Stp_Para数组内300字节的缺省和分步校正参数
//加入在参数输入对话框中显示“进入下传分步校正参数包SCSI命令程序”功能
//初始化SCSI调用缓冲区
ASPI32Status=0xff;
for(int i=0;i<16;i++)
mySRBEIO.SenseArea[i]=0;
int ASPI_Host_Adapter_ID;
ASPI_Host_Adapter_ID=GetPrivateProfileInt("ASPI_Adapter","ASPI",0,InitDir2);
mySRBEIO.SRB_Cmd =SC_EXEC_SCSI_CMD;
mySRBEIO.SRB_Status =0;
mySRBEIO.SRB_HaId =ASPI_Host_Adapter_ID;
mySRBEIO.SRB_Flags =SRB_DIR_SCSI;
mySRBEIO.SRB_Hdr_Rsvd =0;
mySRBEIO.SRB_Target =6;
mySRBEIO.SRB_Lun =0;
mySRBEIO.SRB_Rsvd1 =0;
//分步校正下传参数包Def_Stp_Para缓冲区的300个字节:150字节的缺省参数及150字节的分步参数
mySRBEIO.SRB_BufLen =300;
mySRBEIO.SRB_BufPointer =(unsigned char *)Def_Stp_Para;
mySRBEIO.SRB_SenseLen =SENSE_LEN;
mySRBEIO.SRB_CDBLen =10;
mySRBEIO.SRB_HaStat =0;
mySRBEIO.SRB_TargStat =0;
mySRBEIO.SRB_Rsvd2 =0;
mySRBEIO.CDBByte[0] =0x2A; //设置扫描校正方式SCSI命令包 CDBLen=10。命令码=2AH
mySRBEIO.CDBByte[1] =0x00;
mySRBEIO.CDBByte[2] =LOBYTE(JZMode); //设置扫描校正方式字节
mySRBEIO.CDBByte[3] =0x00;
mySRBEIO.CDBByte[4] =0x00;
mySRBEIO.CDBByte[5] =0x00;
mySRBEIO.CDBByte[6] =0x00;
mySRBEIO.CDBByte[7] =HIBYTEOFWORD(300);
mySRBEIO.CDBByte[8] =LOBYTEOFWORD(300);
mySRBEIO.CDBByte[9] =0;
mySRBEIO.SRB_PostProc =0;
ASPI32Status =SendASPI32Command( (LPSRB) &mySRBEIO);
while(mySRBEIO.SRB_Status==SS_PENDING);
if(mySRBEIO.SRB_Status==SS_ERR)
{
MessageBox("SRB_Status==ss_error");
// return 0;
}
if(mySRBEIO.SRB_TargStat==0x02) //约定GOOD为00H,检查出错为02H
{
SCSI_CHECK();
}
return 1;
}
//////////////////////////////////////////////////////////////
//发送SETWINDOWS命令
//////////////////////////////////////////////////////////////
void CSetScanner::SetWindow(int n,int m)
{
ASPI32Status=0xff;
char DataBuffer[90];
char chBrightness;
char chThreashold;
char chContrast;
int i;
int nResolution,nTop,nLeft,nWidth,nLength,nWidth2;
int ymaxFBL,ymaxFBL_Adj;
WORD wHalfTone=0;
int y1;
int gray;
int scannermode;
int shuzu;
shuzu=GetPrivateProfileInt("Shuzu","shuzu",1200,InitDir2);
ymaxFBL_Adj=GetPrivateProfileInt("ymax","ymaxFBL_Adj",5000,InitDir2);
ymaxFBL=GetPrivateProfileInt("ymax","ymaxFBL",5000,InitDir2)+ymaxFBL_Adj;
//************************************************************
//以下代码是准备向SCSI接口传递的数据
//************************************************************
//从\\windows\\twacker.ini文件中,获取扫描分辨率初值
//并且根据分辨率确定色拼齐数值
if(m==1)//扫描时参数
{
pScanner->m_nDPI= GetPrivateProfileInt("resoultion","reso",100,InitDir2);
nResolution =pScanner->m_nDPI;
pScanner->m_nColor = GetPrivateProfileInt("color num","color",16777216,InitDir2);
}
if(m==0)//预览时参数
{
pScanner->m_nDPI=100;
nResolution =100;
pScanner->m_nColor=16777216;
}
//由于存在奇偶拼,因此必须考虑奇偶行的差距
//目前认为差距为pScanner->m_nDPI/100
int reso1;
int x1;
x1=0;
y1=0;
reso1=25;
while(pScanner->m_nDPI>reso1)
{
reso1=reso1+50;
x1++;
y1=2*x1;
}
int pjrow;
// pjrow=(int)(pScanner->m_nDPI/100.0+0.5);
pjrow=(int)(pScanner->m_nDPI/100.0);
y1=y1+pjrow;
//确定扫描图像的扫描区域,起始点的纵向以电机走步为单位,水平方向以600DPI为单位的象素点数目
//扫描长度为实际分辨率下象素点为为单位
nTop = n;
nLeft = (int)((pScanner->m_rtScanZoom).left/FuMian*shuzu);
nWidth = (int)(((pScanner->m_rtScanZoom).right-(pScanner->m_rtScanZoom).left)/FuMian*shuzu);
//真彩色时的长度,用于实现行拼和奇偶拼
nLength= (int)((((pScanner->m_rtScanZoom).bottom-(pScanner->m_rtScanZoom).top)/FuMian)*(pScanner->m_nDPI)+y1);
//根据需要而下传的一个参数,表示当前分辨率下的实际象素点数目
nWidth2 =(int)(((pScanner->m_rtScanZoom).right-(pScanner->m_rtScanZoom).left)/FuMian*(pScanner->m_nDPI));
//传递数据时,灰度和黑白处理方式不同,不过黑白送上来的数据是0或者FF。
if(pScanner->m_nColor==2)
{
nWidth2=(nWidth2/8)*8;
nWidth=(nWidth2*shuzu)/pScanner->m_nDPI;
//仅仅是奇偶拼色
nLength= (int)((((pScanner->m_rtScanZoom).bottom-(pScanner->m_rtScanZoom).top)/FuMian)*(pScanner->m_nDPI)+pjrow);
}
if(pScanner->m_nColor==256)
{
//仅仅是奇偶拼色
nLength=(int)((((pScanner->m_rtScanZoom).bottom-(pScanner->m_rtScanZoom).top)/FuMian)*(pScanner->m_nDPI)+pjrow);
}
//下传的校正数值等
chBrightness = '\0';
chThreashold = '\0';
chContrast = '\0';
UpdateData(TRUE);
for(i=0;i<90;i++)
DataBuffer[i]=0;
DataBuffer[0] = 0;
DataBuffer[1] = 7;
DataBuffer[6] = HIBYTEOFWORD(82);
DataBuffer[7] = LOBYTEOFWORD(82);
DataBuffer[8+0] = 0;
DataBuffer[8+1] = 0;
//X和Y轴的分辨率
DataBuffer[8+2] = HIBYTEOFWORD(nResolution);
DataBuffer[8+3] = LOBYTEOFWORD(nResolution);
DataBuffer[8+4] = HIBYTEOFWORD(nResolution);
DataBuffer[8+5] = LOBYTEOFWORD(nResolution);
//X和Y轴的左上角位置
DataBuffer[8+6] = FIRSTBYTEOFDWORD(nLeft);
DataBuffer[8+7] = SECONDBYTEOFDWORD(nLeft);
DataBuffer[8+8] = THIRDBYTEOFDWORD(nLeft);
DataBuffer[8+9] = LASTBYTEOFDWORD(nLeft);
DataBuffer[8+10] = FIRSTBYTEOFDWORD(nTop);
DataBuffer[8+11] = SECONDBYTEOFDWORD(nTop);
DataBuffer[8+12] = THIRDBYTEOFDWORD(nTop);
DataBuffer[8+13] = LASTBYTEOFDWORD(nTop);
//窗口的宽度和长度
DataBuffer[8+14] = FIRSTBYTEOFDWORD(nWidth);
DataBuffer[8+15] = SECONDBYTEOFDWORD(nWidth);
DataBuffer[8+16] = THIRDBYTEOFDWORD(nWidth);
DataBuffer[8+17] = LASTBYTEOFDWORD(nWidth);
DataBuffer[8+18] = FIRSTBYTEOFDWORD(nLength);
DataBuffer[8+19] = SECONDBYTEOFDWORD(nLength);
DataBuffer[8+20] = THIRDBYTEOFDWORD(nLength);
DataBuffer[8+21] = LASTBYTEOFDWORD(nLength);
//明度、线程和对比度
DataBuffer[8+22] = chBrightness;
DataBuffer[8+23] = chThreashold; //阈值
DataBuffer[8+24] = chContrast;
DataBuffer[8+25] = 0x05; //图像数据的组合方式
switch(pScanner->m_nColor)
{
case 16777216:
DataBuffer[8+26] = 24;
scannermode=0x80; //彩色扫描方式
break;
case 256:
gray=GetPrivateProfileInt("xianzhen","channel",42,InitDir2);
DataBuffer[8+26] =8;
if(gray==44)
{
scannermode=0x44;
}
if(gray==42)
{
scannermode=0x42;
}
if(gray==41)
{
scannermode=0x41;
}
break;
case 2:
DataBuffer[8+26] =1;
gray=GetPrivateProfileInt("xianzhen","channel",42,InitDir2);
if(gray==44)
{
scannermode=0x24;
}
if(gray==42)
{
scannermode=0x22;
}
if(gray==41)
{
scannermode=0x21;
}
break;
default:
DataBuffer[8+26] = 24;
scannermode=0x80; //彩色扫描方式
break;
}
DataBuffer[8+27] = HIBYTE(wHalfTone);
DataBuffer[8+28] = LOBYTE(wHalfTone);
DataBuffer[8+29] = (char)(0x80);
DataBuffer[8+30] = 0;
DataBuffer[8+31] = 0;
DataBuffer[8+32] = 0; //图像压缩代码
//以下为扩展部分
// ***** 头尾重叠下传参数 *****
int Head,End,Adj;
char HStr[10],EStr[9],AStr[9];
strcpy(HStr,"Head_CNT1");
strcpy(EStr,"End_CNT1");
strcpy(AStr,"END1_Adj");
i=48;
for (int j=1;j<=8;j++)
{
HStr[8]=LOBYTE(0x30+j);
EStr[7]=LOBYTE(0x30+j);
AStr[3]=LOBYTE(0x30+j);
Head=GetPrivateProfileInt("CCD_Pj",HStr,10,InitDir2);
End=GetPrivateProfileInt("CCD_Pj",EStr,10,InitDir2);
Adj=GetPrivateProfileInt("CCD_Adjust",AStr,0,InitDir2);
DataBuffer[i+0]=HIBYTE(Head); //头部重叠区象素数
DataBuffer[i+1]=LOBYTE(Head);
DataBuffer[i+2]=HIBYTE(End+Adj); //尾部重叠区象素数
DataBuffer[i+3]=LOBYTE(End+Adj);
i=i+4;
}
//修改第一头的头部重叠数:将头部剪切量加进去
Head=GetPrivateProfileInt("CCD_Pj","Head_CNT1",10,InitDir2);
Adj=GetPrivateProfileInt("CCD_Adjust","Head_Adj",10,InitDir2);
DataBuffer[48]=HIBYTE(Head+Adj); //头部重叠区象素数+头部剪切量
DataBuffer[49]=LOBYTE(Head+Adj);
//A0扫描仪:将尾部修改剪切量加到第五头的尾部剪切值中去
//A1扫描仪:将尾部修改剪切量加到第三头的尾部剪切值中去
End=GetPrivateProfileInt("CCD_Pj","End_CNT5",10,InitDir2);
Adj=GetPrivateProfileInt("CCD_Adjust","END5_Adj",10,InitDir2);
DataBuffer[66]=HIBYTE(End+Adj); //第5头尾部重叠区象素数+尾部剪切量
DataBuffer[67]=LOBYTE(End+Adj);
DataBuffer[8+72] = scannermode; //RGB彩色模式以及选择的线阵
DataBuffer[8+73]=HIBYTE(nWidth2); //一行扫描线在设定扫描分辨率下的实际象素点数目
DataBuffer[8+74]=LOBYTE(nWidth2);
DataBuffer[8+75]=HIBYTE(shuzu); // X走向最大分辨率
DataBuffer[8+76]=LOBYTE(shuzu);
DataBuffer[8+77]=HIBYTE(ymaxFBL); // Y走向最大步数
DataBuffer[8+78]=LOBYTE(ymaxFBL);
//************************************************************
//以下代码是向SCSI接口传递数据
//************************************************************
ASPI_Host_Adapter_ID=GetPrivateProfileInt("ASPI_Adapter","ASPI",0,InitDir2);
for(i=0;i<16;i++)
mySRBEIO.SenseArea[i]=0;
//定义SCSI的SC_EXEC_SCSI_CMD命令块
mySRBEIO.SRB_Cmd =SC_EXEC_SCSI_CMD;
mySRBEIO.SRB_Status =0;
mySRBEIO.SRB_HaId =ASPI_Host_Adapter_ID;
mySRBEIO.SRB_Flags =SRB_DIR_SCSI;
mySRBEIO.SRB_Hdr_Rsvd =0;
mySRBEIO.SRB_Target =6;
mySRBEIO.SRB_Lun =0;
mySRBEIO.SRB_Rsvd1 =0;
mySRBEIO.SRB_BufLen =90;
mySRBEIO.SRB_BufPointer =(unsigned char *)DataBuffer;
mySRBEIO.SRB_SenseLen =SENSE_LEN;
mySRBEIO.SRB_CDBLen =10;
mySRBEIO.SRB_HaStat =0;
mySRBEIO.SRB_TargStat =0;
mySRBEIO.SRB_Rsvd2 =0;
//定义SETWINDOW命令
mySRBEIO.CDBByte[0] =0x24;
mySRBEIO.CDBByte[1] =0;
mySRBEIO.CDBByte[2] =0;
mySRBEIO.CDBByte[3] =0;
mySRBEIO.CDBByte[4] =0;
mySRBEIO.CDBByte[5] =0;
mySRBEIO.CDBByte[6] =FIRSTBYTEOFDWORD(90);
mySRBEIO.CDBByte[7] =THIRDBYTEOFDWORD(90);
mySRBEIO.CDBByte[8] =LASTBYTEOFDWORD(90);
mySRBEIO.CDBByte[9] =0;
mySRBEIO.SRB_PostProc=0;
//调用SCSI函数包,向SCSI发送命令
ASPI32Status =SendASPI32Command( (LPSRB) &mySRBEIO);
//检测SCSI返回状态
while(mySRBEIO.SRB_Status==SS_PENDING);
if(mySRBEIO.SRB_Status==SS_ERR)
{
MessageBox("SRB_Status==ss_error");
}
if(mySRBEIO.SRB_TargStat==0x02) //约定GOOD为00H,检查出错为02H
{
SCSI_CHECK();
}
//测试,用于扫描起始显示时间
time_t date1_t;
time(&date1_t);
int Hour,Minute,Second;
CTime time1(date1_t);
pTesttime = new Ctesttime();
pTesttime->Create( );
//获取系统时间,并在对话框中显示扫描起始时间
Hour=time1.GetHour();
Minute=time1.GetMinute();
Second=time1.GetSecond();
pTesttime->start(Hour,Minute,Second);
}
/*--------------------------------------------------------------/
/ SCSI 图像数据读取命令 /
/ 由CSetScanner::cunchu()调用,用于文件扫描 /
/ 参数: LPSTR lp --> 读取图像数据缓冲区 /
/ int bytes --> 读取图像数据的长度(字节数) /
/ int bytes1 --> 一次Read SCSI命令上传图象象素点数 /
/ int n --> 本次READ命令所读取的扫描行数 /
/ int m -->
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -