📄 第2章 图象的几何变换.htm
字号:
<P style="LINE-HEIGHT: 18pt">LPBITMAPINFOHEADER lpTempImgData;</P>
<P
style="LINE-HEIGHT: 18pt">LPSTR
lpTempPtr;</P>
<P
style="LINE-HEIGHT: 18pt">int
SrcX0,SrcY0,SrcX1,SrcY1;</P>
<P
style="LINE-HEIGHT: 18pt">int
DstX0,DstY0,DstX1,DstY1;</P>
<P
style="LINE-HEIGHT: 18pt">int
RectWidth,RectHeight;</P>
<P
style="LINE-HEIGHT: 18pt">BOOL
xVisible,yVisible;</P>
<P
style="LINE-HEIGHT: 18pt">HDC
hDc;</P>
<P
style="LINE-HEIGHT: 18pt">HFILE
hf;</P>
<P
style="LINE-HEIGHT: 18pt">int
i;</P>
<P style="LINE-HEIGHT: 18pt"><SPAN lang=EN-US>//</SPAN><SPAN
style="FONT-FAMILY: 宋体">出现对话框,输入</SPAN><SPAN lang=EN-US>x</SPAN><SPAN
style="FONT-FAMILY: 宋体">偏移量</SPAN><SPAN lang=EN-US>xOffset</SPAN><SPAN
style="FONT-FAMILY: 宋体">,和</SPAN><SPAN lang=EN-US>y</SPAN><SPAN
style="FONT-FAMILY: 宋体">偏移量</SPAN><SPAN lang=EN-US>yOffset</SPAN></P>
<P style="LINE-HEIGHT: 18pt"><SPAN lang=EN-US>dlgInputBox = (DLGPROC)
MakeProcInstance ( (FARPROC)InputBox,ghInst );</SPAN></P>
<P style="LINE-HEIGHT: 18pt"><SPAN lang=EN-US>DialogBox (ghInst, "INPUTBOX",
hWnd, dlgInputBox);</SPAN></P>
<P style="LINE-HEIGHT: 18pt"><SPAN lang=EN-US>FreeProcInstance ( (FARPROC)
dlgInputBox );</SPAN></P>
<P style="LINE-HEIGHT: 18pt"><SPAN lang=EN-US>//OffBits</SPAN><SPAN
style="FONT-FAMILY: 宋体">为</SPAN><SPAN lang=EN-US>BITMAPINFOHEADER</SPAN><SPAN
style="FONT-FAMILY: 宋体">结构长度加调色板的大小</SPAN></P>
<P style="LINE-HEIGHT: 18pt"><SPAN
lang=EN-US>OffBits=bf.bfOffBits-sizeof(BITMAPFILEHEADER); </SPAN></P>
<P style="LINE-HEIGHT: 18pt"><SPAN
lang=EN-US>BufSize=OffBits+bi.biHeight*LineBytes;//</SPAN><SPAN
style="FONT-FAMILY: 宋体">要开的缓冲区的大小</SPAN></P>
<P style="LINE-HEIGHT: 18pt"><SPAN lang=EN-US>//</SPAN><SPAN
style="FONT-FAMILY: 宋体">为新产生的位图分配缓冲区内存</SPAN></P>
<P style="LINE-HEIGHT: 18pt"><SPAN
lang=EN-US>if((hTempImgData=LocalAlloc(LHND,BufSize))==NULL)</SPAN></P>
<P style="LINE-HEIGHT: 18pt"><SPAN lang=EN-US>{</SPAN></P>
<P style="LINE-HEIGHT: 18pt"><SPAN lang=EN-US>MessageBox(hWnd,"Error alloc
memory!","Error Message",MB_OK|</SPAN></P>
<P style="LINE-HEIGHT: 18pt"><SPAN lang=EN-US>MB_ICONEXCLAMATION);</SPAN></P>
<P style="LINE-HEIGHT: 18pt"><SPAN lang=EN-US>return FALSE; //</SPAN><SPAN
style="FONT-FAMILY: 宋体">失败,返回</SPAN></P>
<P style="LINE-HEIGHT: 18pt"><SPAN lang=EN-US>}</SPAN></P>
<P style="LINE-HEIGHT: 18pt"><SPAN lang=EN-US>//lpImgData</SPAN><SPAN
style="FONT-FAMILY: 宋体">为指向原来位图数据的指针</SPAN></P>
<P style="LINE-HEIGHT: 18pt"><SPAN
lang=EN-US>lpImgData=(LPBITMAPINFOHEADER)GlobalLock(hImgData);</SPAN></P>
<P style="LINE-HEIGHT: 18pt"><SPAN lang=EN-US>//lpTempImgData</SPAN><SPAN
style="FONT-FAMILY: 宋体">为指向新产生位图数据的指针</SPAN></P>
<P style="LINE-HEIGHT: 18pt"><SPAN
lang=EN-US>lpTempImgData=(LPBITMAPINFOHEADER)LocalLock(hTempImgData);</SPAN></P>
<P style="LINE-HEIGHT: 18pt"><SPAN lang=EN-US>lpPtr=(char
*)lpImgData;</SPAN></P>
<P style="LINE-HEIGHT: 18pt"><SPAN lang=EN-US>lpTempPtr=(char
*)lpTempImgData;</SPAN></P>
<P style="LINE-HEIGHT: 18pt"><SPAN lang=EN-US>//</SPAN><SPAN
style="FONT-FAMILY: 宋体">将新的缓冲区中的每个字节都填成</SPAN><SPAN lang=EN-US>255</SPAN><SPAN
style="FONT-FAMILY: 宋体">,这样以后未处理的象素就是白色</SPAN></P>
<P style="LINE-HEIGHT: 18pt"><SPAN
lang=EN-US>memset(lpTempPtr,(BYTE)255,BufSize);</SPAN></P>
<P style="LINE-HEIGHT: 18pt"><SPAN lang=EN-US>//</SPAN><SPAN
style="FONT-FAMILY: 宋体">两幅图之间的头信息,包括调色板都是相同的,所以直接拷贝头和调色板</SPAN></P>
<P style="LINE-HEIGHT: 18pt"><SPAN
lang=EN-US>memcpy(lpTempPtr,lpPtr,OffBits);</SPAN></P>
<P style="LINE-HEIGHT: 18pt"><SPAN lang=EN-US>//xVisible</SPAN><SPAN
style="FONT-FAMILY: 宋体">为</SPAN><SPAN lang=EN-US>FALSE</SPAN><SPAN
style="FONT-FAMILY: 宋体">时,表示</SPAN><SPAN lang=EN-US>x</SPAN><SPAN
style="FONT-FAMILY: 宋体">方向已经移出了可显示的范围</SPAN></P>
<P style="LINE-HEIGHT: 18pt"><SPAN lang=EN-US>xVisible=TRUE; </SPAN></P>
<P style="LINE-HEIGHT: 18pt"><SPAN lang=EN-US>if( xOffset<= -bi.biWidth
)</SPAN></P>
<P style="LINE-HEIGHT: 18pt"><SPAN lang=EN-US>xVisible=FALSE; </SPAN></P>
<P style="LINE-HEIGHT: 18pt"><SPAN lang=EN-US>else if(
xOffset<=0){</SPAN></P>
<P style="LINE-HEIGHT: 18pt">DstX0=0; //<SPAN
style="FONT-FAMILY: 宋体">表示移动后,有图区域的左上角点的</SPAN><SPAN lang=EN-US>x</SPAN><SPAN
style="FONT-FAMILY: 宋体">坐标</SPAN></P>
<P style="LINE-HEIGHT: 18pt"><SPAN lang=EN-US>DstX1=bi.biWidth+xOffset;
//</SPAN><SPAN style="FONT-FAMILY: 宋体">表示移动后,有图区域的右下角点的</SPAN><SPAN
lang=EN-US>x</SPAN><SPAN style="FONT-FAMILY: 宋体">坐标</SPAN></P>
<P style="LINE-HEIGHT: 18pt"><SPAN lang=EN-US>}</SPAN></P>
<P style="LINE-HEIGHT: 18pt"><SPAN lang=EN-US>else if (
xOffset<bi.biWidth){</SPAN></P>
<P style="LINE-HEIGHT: 18pt"><SPAN lang=EN-US>DstX0=xOffset;</SPAN></P>
<P style="LINE-HEIGHT: 18pt"><SPAN lang=EN-US>DstX1=bi.biWidth;</SPAN></P>
<P style="LINE-HEIGHT: 18pt"><SPAN lang=EN-US>}</SPAN></P>
<P style="LINE-HEIGHT: 18pt"><SPAN lang=EN-US>else</SPAN></P>
<P style="LINE-HEIGHT: 18pt"><SPAN lang=EN-US>xVisible=FALSE;</SPAN></P>
<P style="LINE-HEIGHT: 18pt"><SPAN lang=EN-US>SrcX0=DstX0-xOffset;
//</SPAN><SPAN style="FONT-FAMILY: 宋体">对应</SPAN><SPAN
lang=EN-US>DstX0</SPAN><SPAN style="FONT-FAMILY: 宋体">在原图中的</SPAN><SPAN
lang=EN-US>x</SPAN><SPAN style="FONT-FAMILY: 宋体">坐标</SPAN></P>
<P style="LINE-HEIGHT: 18pt"><SPAN lang=EN-US>SrcX1=DstX1-xOffset;
//</SPAN><SPAN style="FONT-FAMILY: 宋体">对应</SPAN><SPAN
lang=EN-US>DstX1</SPAN><SPAN style="FONT-FAMILY: 宋体">在原图中的</SPAN><SPAN
lang=EN-US>x</SPAN><SPAN style="FONT-FAMILY: 宋体">坐标</SPAN></P>
<P style="LINE-HEIGHT: 18pt"><SPAN lang=EN-US>RectWidth=DstX1-DstX0;
//</SPAN><SPAN style="FONT-FAMILY: 宋体">有图区域的宽度</SPAN></P>
<P style="LINE-HEIGHT: 18pt"><SPAN lang=EN-US>//yVisible</SPAN><SPAN
style="FONT-FAMILY: 宋体">为</SPAN><SPAN lang=EN-US>FALSE</SPAN><SPAN
style="FONT-FAMILY: 宋体">时,表示</SPAN><SPAN lang=EN-US>y</SPAN><SPAN
style="FONT-FAMILY: 宋体">方向已经移出了可显示的范围</SPAN></P>
<P style="LINE-HEIGHT: 18pt"><SPAN lang=EN-US>yVisible=TRUE; </SPAN></P>
<P style="LINE-HEIGHT: 18pt"><SPAN lang=EN-US>if( yOffset<= -bi.biHeight
)</SPAN></P>
<P style="LINE-HEIGHT: 18pt"><SPAN lang=EN-US>yVisible=FALSE;</SPAN></P>
<P style="LINE-HEIGHT: 18pt"><SPAN lang=EN-US>else if(
yOffset<=0){</SPAN></P>
<P style="LINE-HEIGHT: 18pt"><SPAN lang=EN-US>DstY0=0; //</SPAN><SPAN
style="FONT-FAMILY: 宋体">表示移动后,有图区域的左上角点的</SPAN><SPAN lang=EN-US>y</SPAN><SPAN
style="FONT-FAMILY: 宋体">坐标</SPAN></P>
<P style="LINE-HEIGHT: 18pt"><SPAN lang=EN-US>DstY1=bi.biHeight+yOffset;
//</SPAN><SPAN style="FONT-FAMILY: 宋体">表示移动后,有图区域的右下角点的</SPAN><SPAN
lang=EN-US>y</SPAN><SPAN style="FONT-FAMILY: 宋体">坐标</SPAN></P>
<P style="LINE-HEIGHT: 18pt"><SPAN lang=EN-US>}</SPAN></P>
<P style="LINE-HEIGHT: 18pt"><SPAN lang=EN-US>else if (
yOffset<bi.biHeight){</SPAN></P>
<P style="LINE-HEIGHT: 18pt"><SPAN lang=EN-US>DstY0=yOffset;</SPAN></P>
<P style="LINE-HEIGHT: 18pt"><SPAN lang=EN-US>DstY1=bi.biHeight;</SPAN></P>
<P style="LINE-HEIGHT: 18pt"><SPAN lang=EN-US>}</SPAN></P>
<P style="LINE-HEIGHT: 18pt"><SPAN lang=EN-US>else</SPAN></P>
<P style="LINE-HEIGHT: 18pt"><SPAN lang=EN-US>yVisible=FALSE;</SPAN></P>
<P style="LINE-HEIGHT: 18pt"><SPAN lang=EN-US>SrcY0=DstY0-yOffset;
//</SPAN><SPAN style="FONT-FAMILY: 宋体">对应</SPAN><SPAN
lang=EN-US>DstY0</SPAN><SPAN style="FONT-FAMILY: 宋体">在原图中的</SPAN><SPAN
lang=EN-US>y</SPAN><SPAN style="FONT-FAMILY: 宋体">坐标</SPAN></P>
<P style="LINE-HEIGHT: 18pt"><SPAN lang=EN-US>SrcY1=DstY1-yOffset;
//</SPAN><SPAN style="FONT-FAMILY: 宋体">对应</SPAN><SPAN
lang=EN-US>DstY1</SPAN><SPAN style="FONT-FAMILY: 宋体">在原图中的</SPAN><SPAN
lang=EN-US>y</SPAN><SPAN style="FONT-FAMILY: 宋体">坐标</SPAN></P>
<P style="LINE-HEIGHT: 18pt"><SPAN lang=EN-US>RectHeight=DstY1-DstY0;
//</SPAN><SPAN style="FONT-FAMILY: 宋体">有图区域的高度</SPAN></P>
<P style="LINE-HEIGHT: 18pt"><SPAN lang=EN-US>if( xVisible && yVisible){
//x,y</SPAN><SPAN style="FONT-FAMILY: 宋体">方向都没有完全移出可显示的范围</SPAN></P>
<P style="LINE-HEIGHT: 18pt"><SPAN lang=EN-US>for(i=0;i<RectHeight;i++){
//</SPAN><SPAN style="FONT-FAMILY: 宋体">拷贝每一行</SPAN></P>
<P style="LINE-HEIGHT: 18pt"><SPAN lang=EN-US>//lpPtr</SPAN><SPAN
style="FONT-FAMILY: 宋体">指向要拷贝的那一行的最左边的象素对应在原图中的位</SPAN></P>
<P style="LINE-HEIGHT: 18pt"><SPAN lang=EN-US>//</SPAN><SPAN
style="FONT-FAMILY: 宋体">置。特别要<B>注意的是</B>,由于</SPAN><SPAN
lang=EN-US>.bmp</SPAN><SPAN
style="FONT-FAMILY: 宋体">是上下颠倒的,<B>偏移是</B></SPAN><B><SPAN
lang=EN-US></SPAN></B></P>
<P style="LINE-HEIGHT: 18pt"><SPAN
lang=EN-US>//(BufSize-LineBytes-(i+SrcY0)*LineBytes)+SrcX0</SPAN><SPAN
style="FONT-FAMILY: 宋体">,<B>而不是</B></SPAN><B><SPAN lang=EN-US></SPAN></B></P>
<P style="LINE-HEIGHT: 18pt"><SPAN
lang=EN-US>//(i+SrcY0)*LineBytes)+SrcX0</SPAN><SPAN
style="FONT-FAMILY: 宋体">,你试着举个例子就明白了。</SPAN></P>
<P style="LINE-HEIGHT: 18pt"><SPAN
lang=EN-US>lpPtr=(char*)lpImgData+(BufSize-LineBytes-</SPAN></P>
<P style="LINE-HEIGHT: 18pt"><SPAN
lang=EN-US>(i+SrcY0)*LineBytes)+SrcX0;</SPAN></P>
<P style="LINE-HEIGHT: 18pt"><SPAN lang=EN-US>//lpTempPtr</SPAN><SPAN
style="FONT-FAMILY: 宋体">指向要拷贝的那一行的最左边的象素对应在新图中</SPAN><SPAN
lang=EN-US>//</SPAN><SPAN style="FONT-FAMILY: 宋体">的位置。同样要注意上面</SPAN><SPAN
lang=EN-US>//</SPAN><SPAN style="FONT-FAMILY: 宋体">的问题。</SPAN></P>
<P style="LINE-HEIGHT: 18pt"><SPAN
lang=EN-US>lpTempPtr=(char*)lpTempImgData+</SPAN></P>
<P style="LINE-HEIGHT: 18pt"><SPAN
lang=EN-US>(BufSize-LineBytes-(i+DstY0)*LineBytes)+DstX0;</SPAN></P>
<P style="LINE-HEIGHT: 18pt"><SPAN lang=EN-US>//</SPAN><SPAN
style="FONT-FAMILY: 宋体">拷贝一行</SPAN><SPAN lang=EN-US>(</SPAN><SPAN
style="FONT-FAMILY: 宋体">宽度为</SPAN><SPAN lang=EN-US>RectWidth)</SPAN></P>
<P
style="LINE-HEIGHT: 18pt"><SPAN>
</SPAN>memcpy(lpTempPtr,lpPtr,RectWidth);</P>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -