这个过程看不懂,谁能帮我把它改成旋转180度及270度?最好给我解释一下.(100分)

  • 主题发起人 主题发起人 taizhi
  • 开始时间 开始时间
T

taizhi

Unregistered / Unconfirmed
GUEST, unregistred user!
procedure ImageRotate90(aBitmap: TBitmap);<br>var<br> &nbsp;nIdx, nOfs,<br> &nbsp;x, y, i,<br> &nbsp;nMultiplier: integer;<br> &nbsp;nMemWidth, nMemHeight, nMemSize,<br> &nbsp;nScanLineSize: LongInt;<br> &nbsp;aScnLnBuffer: PChar;<br> &nbsp;aScanLine: PByteArray;<br>begin<br> &nbsp;nMultiplier := GetPixelSize(ABitmap);<br> &nbsp;nMemWidth := aBitmap.Height;<br> &nbsp;nMemHeight := aBitmap.Width;<br> &nbsp;nMemSize := nMemWidth * nMemHeight * nMultiplier;<br> &nbsp;GetMem(aScnLnBuffer, nMemSize);<br> &nbsp;try<br> &nbsp; nScanLineSize := aBitmap.Width * nMultiplier;<br> &nbsp; GetMem(aScanLine, nScanLineSize);<br> &nbsp; try<br> &nbsp; &nbsp; for y := 0 to aBitmap.Height-1 do<br> &nbsp; &nbsp; begin<br> &nbsp; &nbsp; &nbsp; Move(aBitmap.ScanLine[y]^, aScanLine^, nScanLineSize);<br> &nbsp; &nbsp; &nbsp; for x := 0 to aBitmap.Width-1 do<br> &nbsp; &nbsp; &nbsp; begin<br> &nbsp; &nbsp; &nbsp; &nbsp; [red]nIdx := ((aBitmap.Width-1) - x) * nMultiplier;<br> &nbsp; &nbsp; &nbsp; &nbsp; nOfs := (x * nMemWidth * nMultiplier) + &nbsp;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; (y * nMultiplier); //这两个计算公式是如何得来的?[/red] &nbsp; &nbsp; &nbsp; &nbsp; <br> &nbsp; &nbsp; &nbsp; &nbsp; for i := 0 to nMultiplier-1 do<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Byte(aScnLnBuffer[nOfs + i]) := aScanLine[nIdx+i];<br> &nbsp; &nbsp; &nbsp; end;<br> &nbsp; &nbsp; end;<br> &nbsp; &nbsp; aBitmap.Height := nMemHeight;<br> &nbsp; &nbsp; aBitmap.Width := nMemWidth;<br><br> &nbsp; &nbsp; for y := 0 to nMemHeight-1 do<br> &nbsp; &nbsp; begin<br> &nbsp; &nbsp; &nbsp; nOfs := y * nMemWidth * nMultiplier;<br> &nbsp; &nbsp; &nbsp; Move((@(aScnLnBuffer[nOfs]))^, aBitmap.ScanLine[y]^, nMemWidth * nMultiplier);<br> &nbsp; &nbsp; end;<br> &nbsp; finally<br> &nbsp; &nbsp; FreeMem(aScanLine, nScanLineSize);<br> &nbsp; end;<br> &nbsp;finally<br> &nbsp; &nbsp;FreeMem(aScnLnBuffer, nMemSize);<br> &nbsp;end;<br>end;
 
留个记号
 
马尿代码就是难看 无损旋转变成头晕晕的转
 
你另外一个贴子的代码更容易做一些。已经帮你改好。<br>http://www.delphibbs.com/delphibbs/dispq.asp?lid=3547516
 
直接操作内存啊,研究一下
 
向各位再请教一下:<br>nIdx := ((aBitmap.Width-1) - x) * nMultiplier;<br>nOfs := (x * nMemWidth * nMultiplier) +(y * nMultiplier); <br>以上这两个计算公式是如何得来的? &nbsp;有谁能告诉我吗?
 
to 冰力不足<br> &nbsp;你说&quot;马尿代码&quot;是什么意思?如果你觉得有什么不妥的地方,就直说啊?
 
to zywcd<br>你能帮我解决一下红色的这两行代码是怎么得来的吗?
 
你首先注意这句:nMultiplier := GetPixelSize(ABitmap);获取当前BITMAP不同颜色深度对应的每个像素所占字节大小。(占byte数目)<br>nIdx := ((aBitmap.Width-1) - x) * nMultiplier;//计算源图处理像素位置指针位置<br>nOfs := (x * nMemWidth * nMultiplier) +(y * nMultiplier); //计算目标BITMAP像素指针位置<br> for i := 0 to nMultiplier-1 do<br> &nbsp; &nbsp; Byte(aScnLnBuffer[nOfs + i]) := aScanLine[nIdx+i];//根据上面计算的指针位置,把源图像素复制到目标BITMAP
 
什么怎么得来的啊?你看看是什么意思就可以了啊!不就是操作位图的各个像素嘛!自己用几个数据代进去看看!在纸上画画算一下就知道了
 
to zywcd<br> &nbsp;我知道那两行的代码是什么作用,但还是不明白公式得来的理由.如为什么nOfs 等于 (x * nMemWidth * nMultiplier) +(y * nMultiplier); 你能帮我解释一下吗?<br> &nbsp;我明白了公式得来的理由之后,我才知道怎么写旋转180度及270度.
 
找开源控件学习一下。
 
你另外一个贴子都给你写好了。你看看吧。
 
to zwcd<br>那个贴子,只能针对于24位图像进行旋转,如果是32位则旋转后变成黑白色.
 
//逆时针旋转90度&lt;您的程序&gt;<br><br>procedure ImageRotate90(aBitmap: TBitmap);<br>var<br> &nbsp;nIdx, nOfs,<br> &nbsp;x, y, i,<br> &nbsp;nMultiplier: integer;<br> &nbsp;nMemWidth, nMemHeight, nMemSize,<br> &nbsp;nScanLineSize: LongInt;<br> &nbsp;aScnLnBuffer: PChar;<br> &nbsp;aScanLine: PByteArray;<br>begin<br> &nbsp;nMultiplier := GetPixelSize(ABitmap);<br> &nbsp;nMemWidth := aBitmap.Height;<br> &nbsp;nMemHeight := aBitmap.Width;<br> &nbsp;nMemSize := nMemWidth * nMemHeight * nMultiplier;<br> &nbsp;GetMem(aScnLnBuffer, nMemSize);<br> &nbsp;try<br> &nbsp; nScanLineSize := aBitmap.Width * nMultiplier;<br> &nbsp; GetMem(aScanLine, nScanLineSize);<br> &nbsp; try<br> &nbsp; &nbsp; for y := 0 to aBitmap.Height-1 do<br> &nbsp; &nbsp; begin<br> &nbsp; &nbsp; &nbsp; Move(aBitmap.ScanLine[y]^, aScanLine^, nScanLineSize);<br>{<br> &nbsp; &nbsp; &nbsp; for x := 0 to aBitmap.Width-1 do<br> &nbsp; &nbsp; &nbsp; begin<br> &nbsp; &nbsp; &nbsp; &nbsp; nIdx := ((aBitmap.Width-1) - x) * nMultiplier;<br> &nbsp; &nbsp; &nbsp; &nbsp; nOfs := (x * nMemWidth * nMultiplier) + &nbsp;// y component of the dst<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; (y * nMultiplier); // x component of the dst<br> &nbsp; &nbsp; &nbsp; &nbsp; for i := 0 to nMultiplier-1 do<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Byte(aScnLnBuffer[nOfs + i]) := aScanLine[nIdx+i];<br> &nbsp; &nbsp; &nbsp; end;<br>}<br> &nbsp; &nbsp; end;<br> &nbsp; &nbsp; aBitmap.Height := nMemHeight;<br> &nbsp; &nbsp; aBitmap.Width := nMemWidth;<br><br> &nbsp; &nbsp; for y := 0 to nMemHeight-1 do<br> &nbsp; &nbsp; begin<br> &nbsp; &nbsp; &nbsp; nOfs := y * nMemWidth * nMultiplier;<br> &nbsp; &nbsp; &nbsp; Move((@(aScnLnBuffer[nOfs]))^, aBitmap.ScanLine[y]^, nMemWidth * nMultiplier);<br> &nbsp; &nbsp; end;<br> &nbsp; finally<br> &nbsp; &nbsp; FreeMem(aScanLine, nScanLineSize);<br> &nbsp; end;<br> &nbsp;finally<br> &nbsp; &nbsp;FreeMem(aScnLnBuffer, nMemSize);<br> &nbsp;end;<br>end; &nbsp;<br><br><br>//-------------------------<br>用下一段替换你原程序中的相应位置,是顺时针旋转90度,也就是旋转270度拉<br> for x := 0 to aBitmap.Width-1 do<br> &nbsp; &nbsp; &nbsp; begin<br> &nbsp; &nbsp; &nbsp; &nbsp; //nIdx := ((aBitmap.Width-1) - x) * nMultiplier;<br> &nbsp; &nbsp; &nbsp; &nbsp; nIdx := (x) * nMultiplier;<br> &nbsp; &nbsp; &nbsp; &nbsp; nOfs := (x * nMemWidth * nMultiplier) + &nbsp;// y component of the dst<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ((aBitmap.Height-1-y) * nMultiplier); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // x component of the dst<br> &nbsp; &nbsp; &nbsp; &nbsp; for i := 0 to nMultiplier-1 do<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Byte(aScnLnBuffer[nOfs + i]) := aScanLine[nIdx+i];<br> &nbsp; &nbsp; &nbsp; end;<br><br><br><br><br>//旋转180度<br>procedure ImageRotate180(aBitmap: TBitmap);<br>var<br> &nbsp;nIdx, nOfs,<br> &nbsp;x, y, i,<br> &nbsp;nMultiplier: integer;<br> &nbsp;nMemWidth, nMemHeight, nMemSize,<br> &nbsp;nScanLineSize: LongInt;<br> &nbsp;aScnLnBuffer: PChar;<br> &nbsp;aScanLine: PByteArray;<br>begin &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;//TODO:这里应该是根据Abitmap.PixelFormat返回的一个值,<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;//例如Pf24bit应该是3<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// 这里我用了3 , &nbsp; 简单起见,呵呵<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;//<br> &nbsp;nMultiplier := 3;//(ABitmap);<br> &nbsp;nMemWidth := aBitmap.Width;<br> &nbsp;nMemHeight := aBitmap.Height;<br><br><br> &nbsp;nMemSize := nMemWidth * nMemHeight * nMultiplier; //获取整个图片大小的内存<br> &nbsp;GetMem(aScnLnBuffer, nMemSize); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; //-<br> &nbsp;try<br> &nbsp; nScanLineSize := aBitmap.Width * nMultiplier; &nbsp; //图片的扫描行宽度<br> &nbsp; GetMem(aScanLine, nScanLineSize);<br> &nbsp; try<br> &nbsp; &nbsp; for y :=0 to &nbsp;aBitmap.Height-1 do<br> &nbsp; &nbsp; begin<br> &nbsp; &nbsp; &nbsp; Move(aBitmap.ScanLine[y]^, aScanLine^, nScanLineSize);<br> &nbsp; &nbsp; &nbsp; //下边这个循环主要功能就是根据旋转的度数要求<br> &nbsp; &nbsp; &nbsp; //将原图片中像素的值放到缓冲区中合适的位置。<br> &nbsp; &nbsp; &nbsp; //例如要求旋转180度。则原图中左上角的像素应该变成缓冲<br> &nbsp; &nbsp; &nbsp; //区中的右下角的像素<br> &nbsp; &nbsp; &nbsp; for x := 0 to aBitmap.Width-1 &nbsp;do<br> &nbsp; &nbsp; &nbsp; begin<br> &nbsp; &nbsp; &nbsp; &nbsp; nIdx := ( x) * nMultiplier;<br> &nbsp; &nbsp; &nbsp; &nbsp; nOfs := ((ABitmap.Height-1-y) * nMemWidth * nMultiplier) + &nbsp;// y component of the dst<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ((ABitMap.Width-1- X) * nMultiplier); // x component of the dst<br> &nbsp; &nbsp; &nbsp; &nbsp; for i := 0 to nMultiplier-1 do<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Byte(aScnLnBuffer[nOfs + i]) := aScanLine[nIdx+i];<br> &nbsp; &nbsp; &nbsp; end;<br><br> &nbsp; &nbsp; end;<br> &nbsp; &nbsp; aBitmap.Height := nMemHeight;<br> &nbsp; &nbsp; aBitmap.Width := nMemWidth;<br><br> &nbsp; &nbsp; //将缓冲区中的数据刷新到图片中<br> &nbsp; &nbsp; for y := 0 to nMemHeight-1 do<br> &nbsp; &nbsp; begin<br> &nbsp; &nbsp; &nbsp; nOfs := y * nMemWidth * nMultiplier;<br> &nbsp; &nbsp; &nbsp; Move((@(aScnLnBuffer[nOfs]))^, aBitmap.ScanLine[y]^, nMemWidth * nMultiplier);<br> &nbsp; &nbsp; end;<br> &nbsp; finally<br> &nbsp; &nbsp; FreeMem(aScanLine, nScanLineSize);<br> &nbsp; end;<br> &nbsp;finally<br> &nbsp; &nbsp;FreeMem(aScnLnBuffer, nMemSize);<br> &nbsp;end;<br>end;
 
to lanyun2<br>你的方法对于旋转180度无效?
 
旋转-90度,<br>procedure ImageRotate90(aBitmap:TBitmap);<br>var<br> &nbsp;nIdx,nOfs,<br> &nbsp; &nbsp;x,y,i,<br> &nbsp; &nbsp;nMultiplier:integer;<br> &nbsp;nMemWidth,nMemHeight,nMemSize,<br> &nbsp; &nbsp;nScanLineSize:LongInt;<br> &nbsp;aScnLnBuffer:PChar;<br> &nbsp;aScanLine:PByteArray;<br>begin<br> &nbsp;nMultiplier:=3; //GetPixelSize(ABitmap);<br> &nbsp;nMemWidth:=aBitmap.Height;<br> &nbsp;nMemHeight:=aBitmap.Width;<br> &nbsp;nMemSize:=nMemWidth*nMemHeight*nMultiplier;<br> &nbsp;GetMem(aScnLnBuffer,nMemSize);<br> &nbsp;try<br> &nbsp; &nbsp;nScanLineSize:=aBitmap.Width*nMultiplier;<br> &nbsp; &nbsp;GetMem(aScanLine,nScanLineSize);<br> &nbsp; &nbsp;try<br> &nbsp; &nbsp; &nbsp;for y:=0 to aBitmap.Height-1 do<br> &nbsp; &nbsp; &nbsp;begin<br> &nbsp; &nbsp; &nbsp; &nbsp;Move(aBitmap.ScanLine[y]^,aScanLine^,nScanLineSize);<br> &nbsp; &nbsp; &nbsp; &nbsp;for x:=0 to aBitmap.Width-1 &nbsp; do<br> &nbsp; &nbsp; &nbsp; &nbsp;begin<br> // &nbsp; &nbsp; &nbsp; &nbsp;nIdx:=((aBitmap.Width-1)-x)*nMultiplier; //旋转90度<br> &nbsp; &nbsp; &nbsp; &nbsp; nIdx:=(x)*nMultiplier; //旋转-90度<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;nOfs:=(x*nMemWidth*nMultiplier)+(( aBitmap.Height-1- y)*nMultiplier);<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;for i:=0 to nMultiplier-1 do<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Byte(aScnLnBuffer[nOfs+i]):=aScanLine[nIdx+i];<br> &nbsp; &nbsp; &nbsp; &nbsp;end;<br> &nbsp; &nbsp; &nbsp;end;<br> &nbsp; &nbsp; &nbsp;aBitmap.Height:=nMemHeight;<br> &nbsp; &nbsp; &nbsp;aBitmap.Width:=nMemWidth;<br><br> &nbsp; &nbsp; &nbsp;for y:=0 to nMemHeight-1 do<br> &nbsp; &nbsp; &nbsp;begin<br> &nbsp; &nbsp; &nbsp; &nbsp;nOfs:=y*nMemWidth*nMultiplier;<br> &nbsp; &nbsp; &nbsp; &nbsp;Move((@(aScnLnBuffer[nOfs]))^,aBitmap.ScanLine[y]^,nMemWidth*nMultiplier);<br> &nbsp; &nbsp; &nbsp;end;<br> &nbsp; &nbsp;finally<br> &nbsp; &nbsp; &nbsp;FreeMem(aScanLine,nScanLineSize);<br> &nbsp; &nbsp;end;<br> &nbsp;finally<br> &nbsp; &nbsp;FreeMem(aScnLnBuffer,nMemSize);<br> &nbsp;end;<br>end;
 
zywcd,lanyun2<br> &nbsp;能帮我看看如何旋转180度吗?
 
你将图片Refresh一下,应该能看到效果吧?
 
Refresh也一样,没有一点反应.90度与270度就有用.
 
后退
顶部