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

how to crop a polynomial shape from an image

我在网上搜索了这个问题,找到的方法是关于用 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);

如何构建此功能?

你必须为此使用 canvas。这是永久修改图像的唯一方法。这也需要满足 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
}