【备忘】canvas下图片翻转-转自oldj.net(英杰兄)

2012-01-07 00:44

【备忘】canvas下图片翻转-转自oldj.net(英杰兄)

by 岑安

at 2012-01-06 16:44:00

original http://www.cnblogs.com/hongru/archive/2012/01/06/2314871.html

原文链接: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// 水平“翻转”画布
05ctx.translate(canvas_width, 0);
06ctx.scale(-1, 1);
07// 下面画的图片是水平翻转的
08ctx.drawImage(img, canvas_width - img.width - px, py);
09// 画布恢复正常
10ctx.translate(canvas_width, 0);
11ctx.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 {
08border: solid 1px #333;
09}
10</style>
11</head>
12<body>
13<canvas id="cv" width="300" height="240"></canvas>
14<script>
15var canvas = document.getElementById("cv"),
16    ctx = canvas.getContext("2d"),
17    img = new Image();
18 
19img.src = "/images/oldj_gmail.png";
20 
21function 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 
42function 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 
76img.onload = function () {
77    show();
78};
79</script>
80</body>
81</html>

本文链接