分析图像中的空白,我知道唯一的办法就是到图像加载到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.
};
坦白说,我无法测试此代码一个很好的理由:我穿过了臭名昭著的“ 无法因为帆布已经被跨域数据污点从画布上获得的图像数据”安全例外来。
这不是一个错误,它是一个预期的功能。从specs:
的toDataURL(),toDataURLHD(),toBlob(),getImageData(),和 getImageDataHD()方法检查标志,并会抛出一个SecurityError 例外,而不是泄漏跨域数据。
这种情况发生时从外部域,这会导致画布起源清洁标志drawImage()
将文件加载到被设置为false,防止进一步的数据操作。
我怕你会遇到同样的问题,但无论如何,here is the code.
即使这个工作在客户端,我可以想像是多么痛苦将是性能代价。所以,正如Jan所说,如果你可以下载图像并在服务器端对它们进行预处理,那会更好。
编辑:我很好奇,看看我的代码真的裁剪图像,而事实上它。
你可以检查出来here
它仅适用于从您的域的图像,如前所述。您可以选择使用白色背景自己的形象,改变最后一行:
// define here an image from your domain
img.src = 'http://localhost/strawberry2.jpg';
显然,你需要从你的域中运行的代码,而不是从的jsfiddle。
EDIT2:如果您想裁剪和扩大保持相同的纵横比,然后改变这种
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:在浏览器上裁剪图像的一种快速方法r是通过使用Web Workers来并行化工作负载,如excellent article所解释的那样。
我可以建议您实际添加问题发生在您的问题的图像之一。它会阻止投票结束,因为您有效地宣传您的网站。 –
您可以在画布上绘制图像并移除整个空白列和行,并将图像重新缩放至“相同”尺寸(保持宽高比)。 – Prusse
“我想使用JavaScript而不是预处理图像” - 为什么?为什么要让用户浏览器在每次加载图片时都必须删除空白区域,而不是仅仅在服务器端执行一次,然后将图片保留为未使用白色间距以供将来使用? – h2ooooooo