如何从图像中裁剪多项式形状
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
}
我在网上搜索了这个问题,找到的方法是关于用 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
}