如何在 canvas 中将图像像素转换为 S 曲线形状
How to convert image pixel into s-curve shape in canvas
我有这样的图片
我希望我们在图像中看到的直线(实际上是像素)应该转换为 S 曲线。我已经使用 canvas 及其属性实现了 C 型曲线,但无法实现 S 型曲线。
请帮帮我。
如果我没理解错的话,你希望每条垂直线都跟随一个“S”吗?
如果是这种情况,您可以使用 f.ex。 Math.sin()
与 drawImage()
及其裁剪参数相结合,以每个像素列对图像进行切片,同时根据 sin() 置换切片。
关键公式是:
var step = Math.PI * 2 / w;
这将一个完整的圆映射到 canvas 的宽度,这样当到达终点时我们将回到起点,在本例中形成 S 曲线。
var y = Math.sin(step * x) * scale;
这会根据先前计算的步长值计算 y 轴上的位移,现在链接到 x 位置。这会产生一个介于 -1 和 1 之间的值,因此我们需要将其放大。比例代表以像素数表示的最大半径。
例子
var ctx = c.getContext("2d"); // just some inits for demo
var img = new Image;
img.onload = slice;
img.src = "//i.stack.imgur.com/UvqUP.gif";
function slice() {
var w = c.width = this.width;
var h = c.height = this.height;
var step = Math.PI * 2 / w; // full circle / width of canvas
var scale = 75; // max displacement on y
for(var x = 0; x < w; x++) {
ctx.drawImage(this,
x, 0, 1, h, // source line from image
x, Math.sin(step*x)*scale, 1, h); // displaced line
}
}
<canvas id=c></canvas>
在 x 轴上(在这种情况下显然不可见,因为变化是沿着直线发生的,还有其他方法可以使用,例如在每一端用 s 形过度绘制):
var ctx = c.getContext("2d"); // just some inits for demo
var img = new Image;
img.onload = slice;
img.src = "//i.stack.imgur.com/UvqUP.gif";
function slice() {
var w = c.width = this.width;
var h = c.height = this.height;
var step = Math.PI * 2 / h; // full circle / width of canvas
var scale = 75; // max displacement on y
for(var y = 0; y < h; y++) {
ctx.drawImage(this,
0, y, w, 1, // source line from image
Math.sin(step*y)*scale, y, w, 1); // displaced line
}
}
<canvas id=c></canvas>
我有这样的图片
我希望我们在图像中看到的直线(实际上是像素)应该转换为 S 曲线。我已经使用 canvas 及其属性实现了 C 型曲线,但无法实现 S 型曲线。
请帮帮我。
如果我没理解错的话,你希望每条垂直线都跟随一个“S”吗?
如果是这种情况,您可以使用 f.ex。 Math.sin()
与 drawImage()
及其裁剪参数相结合,以每个像素列对图像进行切片,同时根据 sin() 置换切片。
关键公式是:
var step = Math.PI * 2 / w;
这将一个完整的圆映射到 canvas 的宽度,这样当到达终点时我们将回到起点,在本例中形成 S 曲线。
var y = Math.sin(step * x) * scale;
这会根据先前计算的步长值计算 y 轴上的位移,现在链接到 x 位置。这会产生一个介于 -1 和 1 之间的值,因此我们需要将其放大。比例代表以像素数表示的最大半径。
例子
var ctx = c.getContext("2d"); // just some inits for demo
var img = new Image;
img.onload = slice;
img.src = "//i.stack.imgur.com/UvqUP.gif";
function slice() {
var w = c.width = this.width;
var h = c.height = this.height;
var step = Math.PI * 2 / w; // full circle / width of canvas
var scale = 75; // max displacement on y
for(var x = 0; x < w; x++) {
ctx.drawImage(this,
x, 0, 1, h, // source line from image
x, Math.sin(step*x)*scale, 1, h); // displaced line
}
}
<canvas id=c></canvas>
在 x 轴上(在这种情况下显然不可见,因为变化是沿着直线发生的,还有其他方法可以使用,例如在每一端用 s 形过度绘制):
var ctx = c.getContext("2d"); // just some inits for demo
var img = new Image;
img.onload = slice;
img.src = "//i.stack.imgur.com/UvqUP.gif";
function slice() {
var w = c.width = this.width;
var h = c.height = this.height;
var step = Math.PI * 2 / h; // full circle / width of canvas
var scale = 75; // max displacement on y
for(var y = 0; y < h; y++) {
ctx.drawImage(this,
0, y, w, 1, // source line from image
Math.sin(step*y)*scale, y, w, 1); // displaced line
}
}
<canvas id=c></canvas>