原文鏈接:http://oldj.net/article/flip-images-in-html5/
貌似 HTML5 的 Canvas 只提供了圖片的旋轉、縮放功能,沒有提供圖片翻轉(水平翻轉或垂直翻轉)的支持,搜索加試驗之后,得到幾種實現圖片翻轉的方法,記錄一下。
第一種最簡單的是使用 CSS,代碼片斷如下:
1 |
< style > |
2 |
.flip-x { |
3 |
filter: FlipH; /* IE only */ |
4 |
-moz-transform: matrix(-1, 0, 0, 1, 0, 0); |
5 |
-webkit-transform: matrix(-1, 0, 0, 1, 0, 0); |
6 |
} |
7 |
</ style > |
8 |
< img src = "http://oldj.net/images/oldj.net.png" class = "flip-x" /> |
支持 IE 、Firefox 等各大瀏覽器。不過,如果想在 HTML5 的 Canvas 中翻轉一個圖片,CSS 就無能為力了。
在 Canvas 中翻轉圖片大致有兩種思路,一種是先“翻轉”畫布,在上面畫好需要的圖片后再將畫布“翻轉”回來;另一種是先在畫布上正常畫上原圖,用 getImageData 方法取得圖片的每一個象素的數據,再將數據鏡像交換一下。
先來看“翻轉”畫布的方法,代碼大致類似於這樣:
01 |
// 正常繪制: |
02 |
// ctx.drawImage(img, px, py); |
03 |
04 |
// 水平“翻轉”畫布 |
05 |
ctx.translate(canvas_width, 0); |
06 |
ctx.scale(-1, 1); |
07 |
// 下面畫的圖片是水平翻轉的 |
08 |
ctx.drawImage(img, canvas_width - img.width - px, py); |
09 |
// 畫布恢復正常 |
10 |
ctx.translate(canvas_width, 0); |
11 |
ctx.scale(-1, 1); |
可以看到,主要用到了 translate 以及 scale 方法。先用 translate 方法將坐標原點設為畫布右上角(默認為左上角),再用 scale(-1, 1) 的方式將畫布水平翻轉,在上面畫好圖之后再恢復即可。
另一種象素級的操作原理上也非常簡單,就不多解釋了,可以直接看源碼:
01 |
<!doctype html> |
02 |
<html> |
03 |
<head> |
04 |
<meta charset= "UTF-8" /> |
05 |
<title>test</title> |
06 |
<style type= "text/css" > |
07 |
#cv { |
08 |
border: solid 1px #333; |
09 |
} |
10 |
</style> |
11 |
</head> |
12 |
<body> |
13 |
<canvas id= "cv" width= "300" height= "240" ></canvas> |
14 |
<script> |
15 |
var canvas = document.getElementById( "cv" ), |
16 |
ctx = canvas.getContext( "2d" ), |
17 |
img = new Image(); |
18 |
19 |
img.src = "/images/oldj_gmail.png" ; |
20 |
21 |
function show() { |
22 |
// 正常圖片 |
23 |
ctx.drawImage(img, 10, 10); |
24 |
25 |
// 水平翻轉 |
26 |
ctx.translate(300, 0); |
27 |
ctx.scale(-1, 1); |
28 |
// 下面畫的圖片是水平翻轉的 |
29 |
ctx.drawImage(img, 300 - img.width - 10, 60); |
30 |
// 恢復正常 |
31 |
ctx.translate(300, 0); |
32 |
ctx.scale(-1, 1); |
33 |
34 |
// 下面的圖片是正常的 |
35 |
ctx.drawImage(img, 10, 110); |
36 |
37 |
38 |
// 象素級水平翻轉圖片的方法 |
39 |
show2(); |
40 |
} |
41 |
42 |
function show2() { |
43 |
// 象素級水平翻轉的方法 |
44 |
45 |
// 先畫一個正常的畫片 |
46 |
var px = 10, |
47 |
py = 160; |
48 |
49 |
ctx.drawImage(img, px, py); |
50 |
51 |
// 取得這個圖片的數據,圖片與當前頁面必須同域,否則會出錯 |
52 |
var img_data = ctx.getImageData(px, py, img.width, img.height), |
53 |
54 |
x, y, p, i, i2, t, |
55 |
h = img_data.height; |
56 |
w = img_data.width, |
57 |
w_2 = w / 2; |
58 |
59 |
// 將 img_data 的數據水平翻轉 |
60 |
for (y = 0; y < h; y ++) { |
61 |
for (x = 0; x < w_2; x ++) { |
62 |
i = (y<<2) * w + (x<<2); |
63 |
i2 = ((y + 1) << 2) * w - ((x + 1) << 2); |
64 |
for (p = 0; p < 4; p ++) { |
65 |
t = img_data.data[i + p]; |
66 |
img_data.data[i + p] = img_data.data[i2 + p]; |
67 |
img_data.data[i2 + p] = t; |
68 |
} |
69 |
} |
70 |
} |
71 |
72 |
// 重繪水平翻轉后的圖片 |
73 |
ctx.putImageData(img_data, px, py); |
74 |
} |
75 |
76 |
img.onload = function () { |
77 |
show(); |
78 |
}; |
79 |
</script> |
80 |
</body> |
81 |
</html> |