如何在不缩放的情况下使用HTML5画布翻转图像 [英] How to flip an image with the HTML5 canvas without scaling

查看:106
本文介绍了如何在不缩放的情况下使用HTML5画布翻转图像的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用HTML5 canvas元素在Web应用程序中显示图像,我想水平翻转图像将缩放转换应用于画布。这意味着我不想使用 CanvasRenderingContext2D.scale()为此,因为我不想翻转任何东西。

I use the HTML5 canvas element to display an image in a web application and I want to flip the image horizontally without applying a scaling transformation to the canvas. This means that I do not want to use CanvasRenderingContext2D.scale() for this purpose, because I don't want to flip anything else.

// I don't want this, because it breaks the rest of the application. I have
// implemented zooming and landmark placement functionality, which no longer
// work properly after scaling.
ctx.save();
ctx.scale(-1, 1);
ctx.drawImage(image, -image.width, 0, image.width, image.height);
ctx.restore();

在我看来,我应该能够使用 CanvasRenderingContext2D.drawImage()方法,因为该页面的内容为:

It seems to me that I should be able to do this with the CanvasRenderingContext2D.drawImage() method, since that page reads:


sWidth:要绘制到目标上下文中的源图像子矩形的宽度。如果未指定,则使用从sx和sy指定的坐标到图像右下角的整个矩形。 如果指定负值,则绘制时图像会水平翻转。

这就是我绘制的方式图像:

This is how I draw the image:

var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
var image = document.getElementById('source');
ctx.drawImage(image, 0, 0, image.width, image.height, 0, 0, image.width, image.height);

此处的示例: https://developer.mozilla.org/zh-CN/docs/Web/API/CanvasRenderingContext2D/drawImage#Using_the_drawImage_method

但是如果我尝试按照说明翻转图像,则在Firefox中会出现以下错误:

But if I try to flip the image as per the description, I get the following error in Firefox:

ctx.drawImage(image, 0, 0, -image.width, image.height, 0, 0, image.width, image.height);




IndexSizeError:索引或大小为负数或大于允许的
金额

IndexSizeError: Index or size is negative or greater than the allowed amount

我不明白我在做什么错。如何在不缩放画布的情况下水平翻转图像?

I don't understand what I'm doing wrong here. How can I flip an image horizontally without scaling the canvas?

推荐答案

负区域似乎不受支持(还好吗?),或 此行可能会影响实施方式,参考。步骤4

Negative region does not seem to be supported (yet?), or this line may affect how the implementation is done, ref. step 4:


即使
,图像数据也必须沿原始方向处理

The image data must be processed in the original direction, even if the dimensions given are negative.

在任何情况下,我们都无法做很多事情,只能考虑其他方法-

In any case, we can't do much about it but to look at alternative ways -

这给您留下了一些选择-我想您要避免使用保存/恢复,并且您可以-

This leaves you with some options though - I assume you want to avoid using save/restore, and you can -

重置转换

这是最快的方法,但是您需要知道它将重置所有转换。在大多数情况下,这可能是可以的,所以:

This is the fastest method, but you need to be aware of that it will reset any transformation. And this may be OK in most cases, so:

ctx.scale(-1, 1);
ctx.drawImage(image, -image.width, 0);
ctx.setTransform(1, 0, 0, 1, 0, 0);

最后一个调用是使用单位矩阵重置转换矩阵。

The last call is resetting the transformation matrix using an identity matrix.

撤消上一个转换操作

如果您依赖其他转换,则可以简单地撤消上一个转换操作。这是第二快的选项(它需要在内部进行矩阵乘法):

If you depend on other transformations, you can simply reverse the last transformation operation. This is the second fastest option (it need to do a matrix multiplication internally):

ctx.scale(-1, 1);
ctx.drawImage(image, -image.width, 0);
ctx.scale(-1, 1);   // revert scale only

使用保存/恢复

您已经知道...但是它很慢,因为它保存并恢复了画布的整个状态,而不仅仅是转换。

As you already know... but slow as it saves and restores the whole state of the canvas, not just the transformation.

手动翻转

如果出于某种原因根本不需要使用转换,则始终可以逐行翻转它。这是第二种效率最低的方法,但是允许您不进行任何转换即可工作,并且确实可以做其他事情,例如置换:

If there for some reason is a requirement not to use transformation at all, you can always flip it scanline by scanline. This is the second least efficient method but allows you to work without transformations, and it does allow you to do other things like displacing:

for(var x = 0; x < width; x++)
    ctx.drawImage(img, x, 0, 1, height, width - x, 0, 1, height);

(宽度和高度是图像的宽度和高度)。

(width and height being the image's width and height).

像素操纵

最后,仅出于记录目的,当然是获取像素数据并循环通过,切换位置等。这是最慢的方法,它取决于CORS的要求,因此不建议这样做。

And the last, just for the record, is of course to get the pixel data and loop through, switch places etc. This is the slowest method and it depends on CORS requirement, and is not recommended for this.

这篇关于如何在不缩放的情况下使用HTML5画布翻转图像的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆