【问题标题】:Canvas for image clipping - context.drawImage()用于图像剪辑的画布 - context.drawImage()
【发布时间】:2019-05-08 16:46:20
【问题描述】:

我想从同一张图片中显示四个画布

我正在处理一个需要分成四部分的图像。我不知道图像的实际尺寸,所以我需要它是动态的。我已经做到了这一点,我认为第一部分工作正常,但我不知道为什么它不适用于其余部分。你能指出错误可能在哪里吗?

我是画布的新手,所以我的代码基于这个答案: https://stackoverflow.com/a/8913024/6929416

var image = new Image();
image.crossOrigin = 'anonymous';
image.src = 'https://upload.wikimedia.org/wikipedia/commons/4/47/PNG_transparency_demonstration_1.png';
image.onload = cutImageUp;

function cutImageUp() {

  var natW = image.width / 2;
  var natH = image.height / 2;

  var widthOfOnePiece = jQuery(window).width() / 2;
  var heightOfOnePiece = jQuery(window).height() / 2;

  var imagePieces = [];
  for (var x = 0; x < 2; ++x) {
    for (var y = 0; y < 2; ++y) {
      var canvas = document.createElement('canvas');
      canvas.width = widthOfOnePiece;
      canvas.height = heightOfOnePiece;
      var context = canvas.getContext('2d');
      context.drawImage(image,
        x * natW, y * natH,
        natW, natH,
        x * canvas.width, y * canvas.height,
        canvas.width, canvas.height
      );
      /*drawImage(image,
      	sx, sy,
      	sWidth, sHeight,
      	dx, dy,
      	dWidth, dHeight);*/
      imagePieces.push(canvas.toDataURL());
    }
  }

  // imagePieces now contains data urls of all the pieces of the image

  // load one piece onto the page
  var anImageElement = document.getElementById('testing');
  var anImageElement2 = document.getElementById('testing2');
  var anImageElement3 = document.getElementById('testing3');
  var anImageElement4 = document.getElementById('testing4');

  anImageElement.src = imagePieces[0];
  anImageElement2.src = imagePieces[1];
  anImageElement3.src = imagePieces[2];
  anImageElement4.src = imagePieces[3];
}
img{ border: 1px solid; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<section>
<img id="testing" src="">
<img id="testing2" src="">
<img id="testing3" src="">
<img id="testing4" src="">
</section>

我希望画布尺寸适合屏幕,所以我将它们设置为窗口宽度和高度的一半。

【问题讨论】:

  • 你需要什么?有什么错误?如果你能再解释一下。
  • 只显示第一个画布,其余的都在获取数据,但显然它不是正确的数据,或者我没有正确裁剪原始图像。我需要另一个画布来显示图像的其余部分:第一块:左上角,第二块:右上角,第三块:左下角,第四块:右下角....显示整个图像,但分成四块。
  • 能否添加完整的代码(html)。
  • 当然,添加了html
  • 你的画布在哪里?类似&lt;canvas id="canvas"&gt;&lt;/canvas&gt;。我想你应该看看这个mdn canvasdrawImage

标签: javascript canvas html5-canvas


【解决方案1】:

drawImage的参数是

drawImage(
  source,
  sourceX, sourceY, sourceWidth, sourceHeight,
  destinationX, destinationY, destinationWidth, destinationHeight
)

在您的代码中,您将 destinationX 设置为 x * canvas.width 并将 destinationY 设置为 y * canvas.height。这意味着对于xy 不是0 的每次迭代,您都在目标区域之外进行绘制,即除第一个部分之外的所有部分。

只需将 destinationX-Y 硬编码到 0,你就会很好。

var image = new Image();
image.crossOrigin = 'anonymous';
image.src = 'https://upload.wikimedia.org/wikipedia/commons/4/47/PNG_transparency_demonstration_1.png';
image.onload = cutImageUp;

function cutImageUp() {

  var natW = image.width / 2;
  var natH = image.height / 2;

  var widthOfOnePiece = jQuery(window).width() / 2;
  var heightOfOnePiece = jQuery(window).height() / 2;

  var imagePieces = [];
  for (var x = 0; x < 2; ++x) {
    for (var y = 0; y < 2; ++y) {
      var canvas = document.createElement('canvas');
      canvas.width = widthOfOnePiece;
      canvas.height = heightOfOnePiece;
      var context = canvas.getContext('2d');
      context.drawImage(image,
        x * natW, y * natH,
        natW, natH,
        0, 0,
        canvas.width, canvas.height
      );
      /*drawImage(image,
      	sx, sy,
      	sWidth, sHeight,
      	dx, dy,
      	dWidth, dHeight);*/
      imagePieces.push(canvas.toDataURL());
    }
  }

  // imagePieces now contains data urls of all the pieces of the image

  // load one piece onto the page
  var anImageElement = document.getElementById('testing');
  var anImageElement2 = document.getElementById('testing2');
  var anImageElement3 = document.getElementById('testing3');
  var anImageElement4 = document.getElementById('testing4');

  anImageElement.src = imagePieces[0];
  anImageElement2.src = imagePieces[1];
  anImageElement3.src = imagePieces[2];
  anImageElement4.src = imagePieces[3];
}
img{ border: 1px solid; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<section>
  <img id="testing" src="">
  <img id="testing2" src="">
  <img id="testing3" src="">
  <img id="testing4" src="">
</section>

但请注意,toDataURL 几乎不应该被使用。相反,人们应该总是更喜欢更快的非阻塞和内存友好toBlob()
另外,这里不需要创建 4 个画布,您可以在每一轮重复使用相同的画布。

最后,您可能希望保留图像的纵横比:

var image = new Image();
image.crossOrigin = 'anonymous';
image.src = 'https://upload.wikimedia.org/wikipedia/commons/4/47/PNG_transparency_demonstration_1.png';
image.onload = cutImageUp;

function cutImageUp() {

  var natW = image.width / 2;
  var natH = image.height / 2;

  var widthOfOnePiece = jQuery(window).width() / 2 - 20;
  // preserve aspect ratio
  var heightOfOnePiece = widthOfOnePiece * (natH / natW);

  var canvas = document.createElement('canvas');
  canvas.width = widthOfOnePiece;
  canvas.height = heightOfOnePiece;
  var context = canvas.getContext('2d');
  var promises = [];
  for (var y = 0; y < 2; ++y) {
    for (var x = 0; x < 2; ++x) {
      context.clearRect(0, 0, canvas.width, canvas.height);
      context.drawImage(image,
        x * natW, y * natH,
        natW, natH,
        0, 0,
        canvas.width, canvas.height
      );
      promises.push(new Promise(function(resolve, reject) {
        canvas.toBlob(function(blob) {
          if (!blob) reject();
          resolve(blob);
        });
      }));
    }
  }

  return Promise.all(promises).then(function(blobs) {
    // imagePieces now contains data urls of all the pieces of the image

    // load one piece onto the page
    var anImageElement = document.getElementById('testing');
    var anImageElement2 = document.getElementById('testing2');
    var anImageElement3 = document.getElementById('testing3');
    var anImageElement4 = document.getElementById('testing4');

    anImageElement.src = URL.createObjectURL(blobs[0]);
    anImageElement2.src = URL.createObjectURL(blobs[1]);
    anImageElement3.src = URL.createObjectURL(blobs[2]);
    anImageElement4.src = URL.createObjectURL(blobs[3]);
  })
}
img {
  border: 1px solid;
  display: inline-block;
}
body{margin: 0;}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<section>
  <img id="testing" src="">
  <img id="testing2" src="">
  <img id="testing3" src="">
  <img id="testing4" src="">
</section>

【讨论】:

  • 先生,您刚刚拯救了我的一天,我一直在努力让它工作好几天。太感谢了。实现纵横比保持的任何技巧?还是我应该改进我的代码?
猜你喜欢
  • 2023-03-03
  • 2015-10-12
  • 2021-11-27
  • 1970-01-01
  • 1970-01-01
  • 2020-05-30
  • 1970-01-01
  • 1970-01-01
  • 2013-09-29
相关资源
最近更新 更多