【问题标题】:How to fix warped/distorted and cut-out images in HTML canvas object with javascript?如何使用 javascript 修复 HTML 画布对象中扭曲/扭曲和剪切的图像?
【发布时间】:2019-09-04 15:09:44
【问题描述】:

我正在尝试使用 JavaScript 在 HTML5 中使用画布对象的绘制图像功能切出图像的最大可能正方形区域。此外,剪切区域应该是原始图像的中心。

(我还在图像顶部渲染水印。)

无需尝试剪切图像的中心就可以正常工作,但是每当我尝试这样做时,结果都会变形。

这是warped image 还有这个how the original looks like

下面的代码sn-p中也给出了一个扭曲图像的例子!

要切出图像的一部分,您必须为每个 2 个变量声明两个坐标 P1 和 P2

坐标系是like this(我认为):

要计算我正在使用的 P1 和 P2:

图像宽度


P1:
----
x1 = 0
y1 = (imageheight / 2) - (imagewidth / 2)
// if I'm replacing y1 with 0, it wont get warped
// but it will cut out the top of the image

and

P2:
----
x2 = imagewidth
y2 = y1 + imagewidth

图像宽度 > 图像高度


P1:
----
x1 = (imagewidth / 2) - (imageheight / 2)
y1 = 0
// if I'm replacing x1 with 0, it wont get warped
// but it will cut out the most left part of the image

and

P2:
----
x2 = x1 + imageheight
y2 = imageheight

这是我的代码:

基本上它写入这个对象:

<div id="buy_imagelist" class=imagelist></div>

javascript:

var numbers = ["images/test_images/bluefireoly-2.jpg"];
var txt = "";
var numCanvas = 0;

for(var src in numbers) {
    numCanvas++;
}

var i = 0;
for(var src in numbers) {
    txt = txt + '<canvas class=imagelistsingle style=padding:7px id=myCanvas' + i + ' width="300" height="300"></canvas>';
    i++;
}

document.getElementById('buy_imagelist').innerHTML = txt;
var imageNumber_canvas = 0;

numbers.forEach(myFunction);

function myFunction(value, index, array) {

    var canvas = document.getElementById('myCanvas' + imageNumber_canvas);
    if(canvas == null) {
        window.alert("Error - Images could not be loaded");
    }
    var context = canvas.getContext('2d');

    function loadImages(imagelist, callback) {
        var images = {};
        var loadedImages = 0;
        var numImages = 0;

        for(var src in imagelist) {
            numImages++;
        }

        for(var src in imagelist) {

            images[src] = new Image();
            images[src].onload = function() {
                if(++loadedImages >= numImages) {
                    callback(images);
                }
            };
            images[src].src = imagelist[src];

        }

    }

    var imagelist = {
        testimage: value,
        wasserzeichen: "images/wasserzeichen/wasserzeichen_1.png"
    };

    loadImages(imagelist, function(images) {

        var testimage = images.testimage;

        var imagewidth = testimage.naturalWidth;
        var imageheight = testimage.naturalHeight;

        var x1 = 0;
        var y1 = 0;
        var x2 = imagewidth;
        var y2 = imageheight;

        if(imagewidth !== imageheight) {

            if(imageheight < imagewidth) {

                x1 = (imagewidth / 2) - (imageheight / 2);
                y1 = 0;

                x2 = x1 + imageheight;
                y2 = imageheight;

            } else {

                x1 = 0;
                y1 = (imageheight / 2) - (imagewidth / 2);

                x2 = imagewidth;
                y2 = y1 + imagewidth;

            }

        }

        context.drawImage(testimage, x1, y1, x2, y2, 0, 0, 300, 300);
        context.drawImage(images.wasserzeichen, 0, 0, 300, 300);
    });

    imageNumber_canvas++;

}

正如预期的那样,这适用于方形图像。

错误一定是在这里的某个地方(特别是我用“//!”标记的地方)

var testimage = images.testimage;

var imagewidth = testimage.naturalWidth;
var imageheight = testimage.naturalHeight;

var x1 = 0;
var y1 = 0;
var x2 = imagewidth;
var y2 = imageheight;

if(imagewidth !== imageheight) {

    if(imageheight < imagewidth) {

        x1 = (imagewidth / 2) - (imageheight / 2); //!
        y1 = 0;

        x2 = x1 + imageheight;
        y2 = imageheight;

    } else {

        x1 = 0;
        y1 = (imageheight / 2) - (imagewidth / 2); //!

        x2 = imagewidth;
        y2 = y1 + imagewidth;

    }

}

context.drawImage(testimage, x1, y1, x2, y2, 0, 0, 300, 300);
context.drawImage(images.wasserzeichen, 0, 0, 300, 300);

对于上面给出的非方形图片 (1028x1920) (width

-> y1 = 446
-> 所以 y2 = 446 + 1028 = 1474

所以 y1 > 0
所以 y2 -> 切出的正方形应该适合原始图像

使用此代码亲自尝试一下: (点击“整页”查看图片)

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <title>Example</title>
</head>

<body>

  <div id="buy_imagelist" class=imagelist></div>

  <script>
    var numbers = ["https://i.pinimg.com/originals/46/1c/01/461c0133da95e315cd4e245f79219ec0.jpg"];
    var txt = "";
    var numCanvas = 0;

    for (var src in numbers) {
      numCanvas++;
    }

    var i = 0;
    for (var src in numbers) {
      txt = txt + '<canvas class=imagelistsingle style=padding:7px id=myCanvas' + i + ' width="300" height="300"></canvas>';
      i++;
    }

    document.getElementById('buy_imagelist').innerHTML = txt;
    var imageNumber_canvas = 0;

    numbers.forEach(myFunction);

    function myFunction(value, index, array) {

      var canvas = document.getElementById('myCanvas' + imageNumber_canvas);
      if (canvas == null) {
        window.alert("Error - Images could not be loaded");
      }
      var context = canvas.getContext('2d');

      function loadImages(imagelist, callback) {
        var images = {};
        var loadedImages = 0;
        var numImages = 0;

        for (var src in imagelist) {
          numImages++;
        }

        for (var src in imagelist) {

          images[src] = new Image();
          images[src].onload = function() {
            if (++loadedImages >= numImages) {
              callback(images);
            }
          };
          images[src].src = imagelist[src];

        }

      }

      var imagelist = {
        testimage: value
      };

      loadImages(imagelist, function(images) {

        var testimage = images.testimage;

        var imagewidth = testimage.naturalWidth;
        var imageheight = testimage.naturalHeight;

        var x1 = 0;
        var y1 = 0;
        var x2 = imagewidth;
        var y2 = imageheight;

        if (imagewidth !== imageheight) {

          if (imageheight < imagewidth) {

            x1 = (imagewidth / 2) - (imageheight / 2);
            y1 = 0;

            x2 = x1 + imageheight;
            y2 = imageheight;

          } else {

            x1 = 0;
            y1 = (imageheight / 2) - (imagewidth / 2);

            x2 = imagewidth;
            y2 = y1 + imagewidth;

          }

        }

        context.drawImage(testimage, x1, y1, x2, y2, 0, 0, 300, 300);

      });

      imageNumber_canvas++;

    }
  </script>

</body>

</html>

【问题讨论】:

    标签: javascript html image canvas


    【解决方案1】:

    drawImage 方法的第四个和第五个参数是widthheight,而不是x2y2

    MDN 上的文档在第一个示例中使用了这个

    ctx.drawImage(image, 33, 71, 104, 124, 21, 20, 87, 104);
    

    有解释

    源图像取自坐标 (33, 71),宽度为 104,高度为 124。它在 (21, 20) 处绘制到画布上,宽度为 87,高度为 104。

    tl;dr

    您必须提供剪切图像的宽度/高度,而不是右下角的坐标:

    context.drawImage(testimage, x1, y1, x2 - x1, y2 - y1, 0, 0, 300, 300);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-06-25
      • 2016-03-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-05-31
      相关资源
      最近更新 更多