gpt4 book ai didi

javascript - 使用 jQuery 自动裁剪图像空白

转载 作者:行者123 更新时间:2023-12-03 21:38:28 26 4
gpt4 key购买 nike

我有 100,000 张不受我控制的图像。其中一些图像非常出色,因为图像延伸到边界,而另一些则具有过多的空白。

当空白过多时,页面看起来很糟糕,并且屏幕上的图像看起来尺寸都不同。

你可以在这里明白我的意思:

http://www.fitness-saver.com/uk/shop/mountain-bikes/

我一直在寻找一种自动裁剪图像并删除空白的 jQuery 方法。

1) 每个图像中的空白量都不同2)图像比例不同3)我想使用javascript而不是预处理图像。

希望对您有帮助!

编辑:这是一个示例图像 - http://images.productserve.com/preview/3395/128554505.jpg 。请注意,这些图像来自各个附属网站,并且肯定来自不同的域。

最佳答案

要分析图像中的空白,我知道的唯一方法是将图像加载到 Canvas 中:

var img = new Image(),
$canvas = $("<canvas>"), // create an offscreen canvas
canvas = $canvas[0],
context = canvas.getContext("2d");

img.onload = function () {
context.drawImage(this, 0, 0); // put the image in the canvas
$("body").append($canvas);
removeBlanks(this.width, this.height);
};

// test image
img.src = 'http://images.productserve.com/preview/1302/218680281.jpg';

接下来,使用getImageData()方法。此方法返回一个 ImageData 对象,您可以使用该对象检查每个像素数据(颜色)。

var removeBlanks = function (imgWidth, imgHeight) {
var imageData = context.getImageData(0, 0, canvas.width, canvas.height),
data = imageData.data,
getRBG = function(x, y) {
return {
red: data[(imgWidth*y + x) * 4],
green: data[(imgWidth*y + x) * 4 + 1],
blue: data[(imgWidth*y + x) * 4 + 2]
};
},
isWhite = function (rgb) {
return rgb.red == 255 && rgb.green == 255 && rgb.blue == 255;
},
scanY = function (fromTop) {
var offset = fromTop ? 1 : -1;

// loop through each row
for(var y = fromTop ? 0 : imgHeight - 1; fromTop ? (y < imgHeight) : (y > -1); y += offset) {

// loop through each column
for(var x = 0; x < imgWidth; x++) {
if (!isWhite(getRBG(x, y))) {
return y;
}
}
}
return null; // all image is white
},
scanX = function (fromLeft) {
var offset = fromLeft? 1 : -1;

// loop through each column
for(var x = fromLeft ? 0 : imgWidth - 1; fromLeft ? (x < imgWidth) : (x > -1); x += offset) {

// loop through each row
for(var y = 0; y < imgHeight; y++) {
if (!isWhite(getRBG(x, y))) {
return x;
}
}
}
return null; // all image is white
};


var cropTop = scanY(true),
cropBottom = scanY(false),
cropLeft = scanX(true),
cropRight = scanX(false);
// cropTop is the last topmost white row. Above this row all is white
// cropBottom is the last bottommost white row. Below this row all is white
// cropLeft is the last leftmost white column.
// cropRight is the last rightmost white column.
};

坦白说,我无法测试此代码有一个很好的原因:我遇到了臭名昭著的“无法从 Canvas 获取图像数据,因为 Canvas 已被跨源数据污染。”安全性异常。

这不是一个错误,而是一个预期的功能。来自 specs :

The toDataURL(), toDataURLHD(), toBlob(), getImageData(), and getImageDataHD() methods check the flag and will throw a SecurityError exception rather than leak cross-origin data.

drawImage() 从外部域加载文件时会发生这种情况,这会导致 Canvas 的 origin-clean 标志设置为 false,从而阻止进一步的数据操作。

恐怕你也会遇到同样的问题,但无论如何,here is the code.

即使这在客户端有效,我也可以想象性能会有多糟糕。所以,正如Jan所说,如果你能下载图像并在服务器端对其进行预处理,那就更好了。

<小时/>

编辑:我很好奇我的代码是否真的会裁剪图像,而且确实如此。 enter image description here

您可以查看一下here

如前所述,它仅适用于来自您域的图像。您可以选择自己的白色背景图像并更改最后一行:

// define here an image from your domain
img.src = 'http://localhost/strawberry2.jpg';

显然,您需要从您的域运行代码,而不是从 jsFiddle 运行代码。

<小时/>

编辑2:如果您想裁剪并放大以保持相同的纵横比,请更改此设置

var $croppedCanvas = $("<canvas>").attr({ width: cropWidth, height: cropHeight });

// finally crop the guy
$croppedCanvas[0].getContext("2d").drawImage(canvas,
cropLeft, cropTop, cropWidth, cropHeight,
0, 0, cropWidth, cropHeight);

var $croppedCanvas = $("<canvas>").attr({ width: imgWidth, height: imgHeight });

// finally crop the guy
$croppedCanvas[0].getContext("2d").drawImage(canvas,
cropLeft, cropTop, cropWidth, cropHeight,
0, 0, imgWidth, imgHeight);
<小时/>

Edit3:在浏览器上裁剪图像的一种快速方法是通过使用Web Workers来并行化工作负载,如excellent article解释。

关于javascript - 使用 jQuery 自动裁剪图像空白,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12175991/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com