大家好,我是公众号3分钟学堂的郭立员,今天继续学习安卓按键。
上期文章讲到怎么实现图片旋转,但是有一个问题,自带的命令只能实现90度及其倍数的角度旋转。
如果我想要旋转20°,35°,41°等任意角度,自带命令就无法实现。那怎么办呢?
于是我翻出了珍藏20年的初中数学课本,找到角度的正弦、余弦、正切这节课,重新温习了一遍,顿时豁然开朗了,才思泉涌,想到了解决思路。然后……
好吧,编不下去了,直接进入主题吧。
我们以图片中心点为旋转中心,进行旋转。
在图的左上角区域有一个红点,大家稍微留意一下,下面我们开始顺时针旋转45°。
旋转后红点发生了变化,我们隐去图片看一下。
这两个点有啥关系:
①相距中心点的距离相同
②角度相差45°
有了这两个关系,我们运用正弦、余弦、正切就可以根据第一点坐标,计算出旋转45度以后的坐标,因为第一点是任意的点,所以我们可以通过遍历所有点,然后在算出每个点旋转后的坐标,把颜色值直接赋值过去,就得到新的图片。
当然我知道,大家基本上数学都忘得差不多了,我也是回忆了半天才想起来的,做了一下笔记,计算出4个象限的计算公式。
按照公式套用命令代码:
- Dim Path = "/sdcard/pictures/b.png"
- Dim NewPath = "/sdcard/pictures/3k.jpg"
- dim PicSize = Image.Size(Path)
- Dim x=PicSize[1]
- Dim y=PicSize[2]
- Dim PixelData =Image.GetPicData(Path)
- Dim NewPixelData= Image.GetScreenData(1,1,x,y)
- For i = 1 To x
- For j = 1 To y
- For k = 1 To 3
- NewPixelData[i][j][k]=255
- Next
- Next
- Next
- Dim x0=int(x/2)
- Dim y0=int(y/2)
- Dim n=120
- Dim xf,yf
- PixelData[1][1][1] = 255
- PixelData[1][1][2] = 255
- PixelData[1][1][3]=255
- For i = 1 To x
- For j = 1 To y
- For k = 1 To 3
- xf = getx(x0, y0, i, j, n)
- yf = gety(x0, y0, i, j, n)
- // TracePrint xf,yf,k,"|",i,j,k
- If xf < 1 or yf < 1 or cstr(xf)="-nan" or cstr(yf)="-nan" Then
- xf = 1
- yf=1
- End If
- NewPixelData[i][j][k] = PixelData[xf][yf][k]
- Next
- Next
- Next
- Image.SavePixelData NewPixelData, NewPath
- Function getx(x0,y0,x1,y1,n)
- Dim r=Sqr((x0-x1)^2+(y0-y1)^2)
- Dim pi=3.14
- Dim t1,t2,x2,y2
- If x0 >= x1 and y0 >= y1 Then
- t1=atn((y0-y1)/(x0-x1))
- t2=t1+n*pi/180
- x2 = x0 - Cos(t2) * r
- If x2 > x0 * 2 Then
- getx = 0
- Else
- getx=round(x2)
- End If
- ElseIf x0 <= x1 and y0 >= y1 Then
- t1 = Atn((x1 - x0) / (y0 - y1))
- t2 = t1 + n * pi / 180
- x2 = x0 + Sin(t2) * r
- If x2 > x0 * 2 Then
- getx = 0
- Else
- getx=round(x2)
- End If
- ElseIf x1 <= x0 and y1 >= y0 Then
- t1 = Atn((x0 - x1) / (y1 - y0))
- t2 = t1 + n * pi / 180
- x2 = x0 - Sin(t2) * r
- If x2 > x0 * 2 Then
- getx = 0
- Else
- getx=round(x2)
- End If
- ElseIf x1 >= x0 and y1 >= y0 Then
- t1 = Atn((y1 - y0) / (x1 - x0))
- t2 = t1 + n * pi / 180
- x2 = x0 + Cos(t2) * r
- If x2 > x0 * 2 Then
- getx =0
- Else
- getx=round(x2)
- End If
- End If
- End Function
- Function gety(x0, y0, x1, y1, n)
- Dim r=Sqr((x0-x1)^2+(y0-y1)^2)
- Dim pi=3.14
- Dim t1,t2,x2,y2
- If x0 >= x1 and y0 >= y1 Then
- t1=atn((y0-y1)/(x0-x1))
- t2=t1+n*pi/180
- y2 = y0 - sin(t2) * r
- If y2 > y0 * 2 Then
- gety = 0
- Else
- gety=round(y2)
- End If
- ElseIf x0 <= x1 and y0 >= y1 Then
- t1 = Atn((x1 - x0) / (y0 - y1))
- t2 = t1 + n * pi / 180
- y2 = y0-cos(t2) * r
- If y2 > y0 * 2 Then
- gety = 0
- Else
- gety=round(y2)
- End If
- ElseIf x1 <= x0 and y1 >= y0 Then
- t1 = Atn((x0 - x1) / (y1 - y0))
- t2 = t1 + n * pi / 180
- y2 = y0 + Cos(t2) * r
- If y2 > y0 * 2 Then
- gety = 0
- Else
- gety=round(y2)
- End If
- ElseIf x1 >= x0 and y1 >= y0 Then
- t1 = Atn((y1 - y0) / (x1 - x0))
- t2 = t1 + n * pi / 180
- y2 = y0 + Sin(t2) * r
- If y2 > y0 * 2 Then
- gety = 0
- Else
- gety=round(y2)
- End If
- End If
- End Function
复制代码旋转后的效果:
图片只能是方形的,所有超出部分被省略了,缺失部分我用白色补上了。
对于我写的这个代码可以直接用,只需要修改3处,原始图片路径,旋转后的图片路径,旋转角度变量n,n的值是正数就是逆时针,n的值是负数就是顺时针,其他就不用动了。
代码中的路径不能写错,否则会报错。
好了本期就这些内容,觉得还行,点个赞,留个言。