如何从图像中裁剪多项式形状

时间:2015-03-26 08:21:34

标签: javascript drawing

我在互联网上搜索了这个问题,我找到的方法是用CSS裁剪图像或用JavaScript裁剪矩形。我想要的是使用JavaScript裁剪多项式。

我有一个笛卡尔点Arr=[{x:x1,y:y1},{x:x2,y:y2},{x:x3,y:y3}]数组,它是一个多项式。数组中的第一个元素等于数组中的最后一个元素。

使用函数crop,我想使用此数组从图片imageObj裁剪多项式并将其保存在imageObj2中。

var imageObj = new Image();
var imageObj2 = new Image();
var arr=[];
arr.push({x:x1,y:y1});
arr.push({x:x2,y:y2});
arr.push({x:x3,y:y3});
imageObj.src = 'link of imageObj';
crop(arr[],imageObj);

如何构建此功能?

1 个答案:

答案 0 :(得分:0)

你必须使用画布。这是永久修改图像的唯一方法。这也需要履行CORS。

由于图像加载是异步的,因此需要使用Promises(在IE中不支持)或回调来处理。对于下面的示例,我将使用回调。

第一部分是加载过程以及正确处理回调。

第二部分(cropImage())显示了裁剪图像的完整过程,最后得到了裁剪尺寸的新图像。

它假设点相对于原始图像大小进行缩放(提示:您不需要关闭点,即结束点=第一点,因为fill()会自动为您关闭路径)。



var srcImage = new Image();           // create image object
srcImage.onload = crop;               // set callback
srcImage.crossOrigin = "";            // for demo: =anonymous crossOrigin usage
srcImage.src = "http://i.imgur.com/U9X0n84.jpg";

document.body.appendChild(srcImage);  // add original to DOM for comparsion

function crop() {
  // - image is loaded and is represented as "this" inside this callback
  
  // some "random" points for demo
  var arr = [{x: 10, y: 90}, {x: 70, y: 10}, {x: 400, y: 200}, {x: 200, y: 220}];
  
  // do the cropping, provide callback
  cropImage(this, arr, function(img) {
      // img is the cropped image - add to DOM for demo
      document.body.appendChild(img);
  })
}

function cropImage(image, arr, callback) {
  
  // create a canvas element, and get 2D context for it:
  var canvas = document.createElement("canvas"),
      ctx = canvas.getContext("2d"),
      i, minx = 10000, miny = 10000, maxx = -1, maxy = -1;
  
  // find min max of array points here:
  for(i = 0; i < arr.length; i++) {
    if (arr[i].x < minx) minx = arr[i].x;
    if (arr[i].x > maxx) maxx = arr[i].x;
    if (arr[i].y < miny) miny = arr[i].y;
    if (arr[i].y > maxy) maxy = arr[i].y;
  }
  
  // set proper size:
  canvas.width = maxx - minx;
  canvas.height = maxy - miny;
  
  // translate context so corner of clip is (0,0)
  ctx.translate(-minx, -miny);
  
  // draw in image;
  ctx.drawImage(image, 0, 0);
  
  // create a clip path:
  ctx.moveTo(arr[0].x, arr[0].y);
  for(i = 1; i < arr.length; i++) ctx.lineTo(arr[i].x, arr[i].y);
  
  // set comp. mode so image within path is kept:
  ctx.globalCompositeOperation = "destination-atop";
  ctx.fill();
  
  // done, create an image object:
  var dstImage = new Image();
  dstImage.onload = function() {callback(this)};
  dstImage.src = canvas.toDataURL();     // saves PNG in this case as data-uri
}
&#13;
&#13;
&#13;