如何实现图片文件的旋转问题?
在VB里如何实现图片文件旋转,就像在ACDSEE里对图片进行旋转90°、180°、270°,同时重新将新文件保存到该图片里(即覆盖原文件),如何实现? 问题点数:50、回复次数:17Top
1 楼Gujianda(朝成暮毁,越学越怕!)回复于 2005-11-04 08:45:01 得分 0
不清楚你的用意,三星级的资历应该会完成这个旋转算法问题吧。
我想难度在各类图像文件的解压缩/压缩算法上。
Top
2 楼VBToy(无证编程)回复于 2005-11-04 08:47:41 得分 0
VB中位图旋转的实现
在VISUAL BASIC中没有什么命令或函数能够实现将一个位图旋转一个角度后显示出来,但我们可以用画点的方式,将一个图画盒中的位图中的像素点旋转一个角度后画入另一个图画盒中,当源图画盒中的像素都被画到目标图画盒中时,也就完成了位图的旋转。这里主要用到了VISUAL BASIC中的两个方法:POINT方法和PSET方法。POINT方法的作用是从源图画盒中提取一个像素点的颜色值;而PSET方法的作用是按照旋转后的坐标和相应像素点的颜色值在目标图画盒中画点。显然这个方法的速度不会太快,因而适用于较小的图片。
下面介绍一下实现方法:进入VISUAL BASIC中,建立一个新的窗体。在窗体中加入两个图画盒控件(Picture1和Picture2),设置它们的Name属性为PicSource和PicTarget,并为PicSource图画盒的Picture属性设置一幅位图。再在窗体中加入一个按钮(CommandRotorate),设置它的Caption属性为“旋转”。然后加入以下代码:
Option Explicit
Const Pi = 3.14
Private Sub CommandRototate_Click()
Dim x As Integer, y As Integer
Dim X1 As Integer, Y1 As Integer
Dim X2 As Double, Y2 As Double
Dim X3 As Double, Y3 As Double
Dim JiaoDu As Double
Dim HuDu As Double
JiaoDu = 45 '角度
HuDu = JiaoDu * Pi / 180 '弧度
PicSource.ScaleMode = vbPixels
PicTarget.ScaleMode = vbPixels
For x = 0 To PicTarget.ScaleWidth
X1 = x - PicTarget.ScaleWidth \ 2
For y = 0 To PicTarget.ScaleHeight
Y1 = y - PicTarget.ScaleHeight \ 2
X2 = X1 * Cos(-HuDu) + Y1 * Sin(-HuDu)
Y2 = Y1 * Cos(-HuDu) - X1 * Sin(-HuDu)
X3 = X2 + PicSource.ScaleWidth \ 2
Y3 = Y2 + PicSource.ScaleHeight \ 2
If X3 > 0 And X3 < PicSource.ScaleWidth - 1 And Y3 > 0 And Y3 <
PicSource.ScaleHeight - 1 Then
PicTarget.PSet (x, y), PicSource.Point(X3, Y3)
End If
Next y
Next x
End Sub
运行后,按下“旋转”按钮,可以见到源图画盒中的位图旋转45度后进入到目标图画盒中。如果要改变旋转的角度,只需将JiaoDu变量设置为相应值即可。Top
3 楼rainstormmaster(暴风雨 v2.0)回复于 2005-11-04 09:18:05 得分 0
什么系统,2000以上的系统可以试试api函数PlgBlt,他可以实现位图的旋转:
【声明】
Private Declare Function PlgBlt Lib "gdi32" Alias "PlgBlt" (ByVal hdcDest As Long, lpPoint As POINTAPI, ByVal hdcSrc As Long, ByVal nXSrc As Long, ByVal nYSrc As Long, ByVal nWidth As Long, ByVal nHeight As Long, ByVal hbmMask As Long, ByVal xMask As Long, ByVal yMask As Long) As Long
【说明】
复制一幅位图,同时将其转换成一个平行四边形。利用它可对位图进行旋转处理
【返回值】
Long,非零表示成功,零表示失败。会设置GetLastError
【备注】
如果对源图象应用了旋转或剪切处理,这个函数的执行就会失败。可用GetDeviceCaps判断这个函数是否得到了一个特定设备场景的支持
【参数表】
hdcDest -------- Long,图象使用的目标设备场景
lpPoint -------- POINTAPI,POINTAPI结构数组中使用的第一个条目。第一个点对应于一个平行四边形左上角位置;第二个点代表右下角位置;第三个点代表左下角位置;第四个点是在前三个点的基础上导出的
hdcSrc --------- Long,图象的源设备场景
nXSrc,nYSrc ---- Long,源图象左上角的x,y坐标,采用逻辑坐标系统表示
nWidth,nHeight - Long,源图象大小,用逻辑坐标表示
hbmMask -------- Long,一个可选的句柄,指向一个单色掩模。如设定了这个参数,那么只有与掩模值1对应的二进制位才会传输到目的地
xMask,yMask ---- Long,掩模位图欲使用区域左上角的x,y坐标
适用平台
Windows NT
Top
4 楼Summer006(脸都丢尽了!闭关修练。。。。)回复于 2005-11-04 09:40:48 得分 0
哦呵呵。90度整数倍的旋转简单的很嘛。最多就是图像宽高交替一下。
用一个循环转换一下坐标就是了。,x变成y,或者x变成width-x。
任意角度就要sin,cos这些了。还要原点。。比较麻烦,楼上的朋友也贴了,可以参考
Top
5 楼nofound007(★★★ 天堂小鱼儿 ★★★)回复于 2005-11-04 10:56:08 得分 0
仅旋转当然简单,我把旋转后的文件保存到文件中去啊……Top
6 楼nofound007(★★★ 天堂小鱼儿 ★★★)回复于 2005-11-04 10:56:24 得分 0
当然要保证不失真!!!Top
7 楼pcm112(独孤成明)回复于 2005-11-04 11:05:17 得分 0
可以试试用微软的ijl11.dllTop
8 楼pcm112(独孤成明)回复于 2005-11-04 11:06:48 得分 0
http://www.vbaccelerator.com/codelib/gfx/vbjpeg.htmTop
9 楼nofound007(★★★ 天堂小鱼儿 ★★★)回复于 2005-11-04 11:44:50 得分 0
应该不用这么复杂吧;Top
10 楼WallesCai(女人之美,在于蠢得无怨无悔,男人之美,在于撒谎撒得白日见鬼)回复于 2005-11-04 11:53:29 得分 0
楼主这个问题其实包含了两个问题:
1:图像旋转:这个可以用API或者画点的方法解决
2:图像保存:VB只能保存BMP,如果是其他类型,可以用GDI+等方法来实现。
Top
11 楼Summer006(脸都丢尽了!闭关修练。。。。)回复于 2005-11-04 11:57:33 得分 0
你要能做到把图片的每点颜色读到内存中数组里,就成功1/3了。
再对这个数组进行处理转换,你就是一个旋转,这里比较简单。 2/3了。
再把转换后的数组写入原图片里边,完了。
哪步有问题啊?
ps:据我所知vb里面图像处理的3种基本方法,按效率从高到低,也是难度从难到易排:
SafeArray2D() 和CopyMemory配合使用
GetDIBits() 是这样写吗?忘了
picturebox控件 的point ,pset方法
不知道有没有更快的方法?lz用的哪种?Top
12 楼lxcy(始经天月照,终若流星驰!)回复于 2005-11-04 13:58:09 得分 0
api就可以了Top
13 楼nofound007(★★★ 天堂小鱼儿 ★★★)回复于 2005-11-04 17:24:23 得分 0
API举个例子……???Top
14 楼Gujianda(朝成暮毁,越学越怕!)回复于 2005-11-06 09:02:59 得分 0
上面的红星老大们,请说说,对于有压缩的图像,旋转过程中不牵涉到压缩计算问题吗?
我不懂,但想想没那么简单。旋转问题有什么好讨论的,学过高中解析几何的就该会!Top
15 楼nofound007(★★★ 天堂小鱼儿 ★★★)回复于 2006-01-10 23:15:38 得分 0
1 谁说VB不能转,我转,我转,我转转
前些时候和朋友交流图片旋转的问题,朋友讲VB做图片旋转根本是开玩笑,速度根本跟不上,我就不信这个邪,经过N长时间搜罗资料,终于得到了下面的方法,DIB法,其实我们处理图片速度慢不是VB慢,而是你的方法有问题,所以写到这里大家共同研究一下:
一个Module
Type BITMAPINFOHEADER '40 bytes,这个大家可以看看BMP的格式
BmSize As Long
BmWidth As Long
BmHeight As Long
BmPlanes As Integer
BmBitCount As Integer
BmCompression As Long
BmSizeImage As Long
BmXPelsPerMeter As Long
BmYPelsPerMeter As Long
BmClrUsed As Long
BmClrImportant As Long
End Type
Type BITMAPINFO
BmHeader As BITMAPINFOHEADER
End Type
'下面是两个操作DIB的函数
Declare Sub GetDIBits Lib "GDI32" (ByVal hDC&, ByVal hBitmap&, ByVal nStartScan&, ByVal nNumScans&, lpBits As Any, lpBI As BITMAPINFO, ByVal wUsage&)
Declare Sub SetDIBits Lib "GDI32" (ByVal hDC&, ByVal hBitmap&, ByVal nStartScan&, ByVal nNumScans&, lpBits As Any, lpBI As BITMAPINFO, ByVal wUsage&)
下面是窗体部分,两个Picture,Picture1装载一个图片,要小点的哦,呵呵,Picture2显示旋转结果,一个HScroll
,下面是代码:
Sub RotatePicDI(SrcPic As PictureBox, DestPic As PictureBox, A As Double)
Dim SrcInfo As BITMAPINFO, DesInfo As BITMAPINFO
Dim X&, Y&, CA As Double, SA As Double, nX&, nY&
Dim sW&, sH&, sW2&, sH2&, dW&, dH&, dW2&, dH2&
Const Pi = 0.017453292519943
CA = Cos(A * Pi * -1): SA = Sin(A * Pi * -1)
sW = SrcPic.ScaleWidth
sH = SrcPic.ScaleHeight
dW = DestPic.ScaleWidth
dH = DestPic.ScaleHeight
sW2 = sW / 2: sH2 = sH / 2
dW2 = dW / 2: dH2 = dH / 2
SrcInfo.BmHeader.BmSize = 40
SrcInfo.BmHeader.BmWidth = sW
SrcInfo.BmHeader.BmHeight = -sH
SrcInfo.BmHeader.BmPlanes = 1
SrcInfo.BmHeader.BmBitCount = 32
SrcInfo.BmHeader.BmSizeImage = 3 * sW * sH
LSet DesInfo = SrcInfo
DesInfo.BmHeader.BmWidth = dW
DesInfo.BmHeader.BmHeight = -dH
DesInfo.BmHeader.BmSizeImage = 3 * dW * dH
ReDim SrcPix(0, sW - 1, sH - 1) As Long
ReDim DesPix(0, dW - 1, dH - 1) As Long
Call GetDIBits(SrcPic.hDC, SrcPic.Image, 0&, sH, SrcPix(0, 0, 0), SrcInfo, 0&)
For Y = 0 To dH - 1
For X = 0 To dW - 1
nX = CA * (X - dW2) - SA * (Y - dH2) + sW2
nY = SA * (X - dW2) + CA * (Y - dH2) + sH2
If nX > -1 And nY > -1 And nX < sW And nY < sH Then
DesPix(0, X, Y) = SrcPix(0, nX, nY)
End If
Next
Next
Call SetDIBits(DestPic.hDC, DestPic.Image, 0&, dH, DesPix(0, 0, 0), DesInfo, 0&)
DestPic.Picture = DestPic.Image
End Sub
Private Sub HScroll1_Scroll()
RotatePicDI Picture1, Picture2, HScroll1.Value
End Sub
拖动HScroll1看看结果吧
作者: Deane·King 2005-12-30 10:16 回复此发言
Top
16 楼guoguo1982(蝈蝈)回复于 2006-01-11 09:50:14 得分 0
学习中Top
17 楼yangyangyy(逍遥公主)回复于 2006-01-11 17:01:08 得分 0
VB调用缩略图水印组件wsImage3.5 中的支持图片任意角度旋转功能即可。
www.wave12.comTop




