Dav*_*tch 23 javascript jquery image
我有100,000张不受我控制的图像.这些图像中的一些是优秀的,因为图像延伸到边界,而一些图像具有过量的白色空间.
当存在过多的空白时,它会使页面看起来很糟糕,并且意味着屏幕上的图像看起来都是不同的大小.
你可以在这里看到我的意思:
http://www.fitness-saver.com/uk/shop/mountain-bikes/
我一直在寻找的是一种jQuery方法,用于裁剪图像并自动删除空白.
1)每个图像中的空白量是不同的2)图像的比例是不同的3)我想使用javascript而不是预处理图像.
希望你能帮忙!
编辑:这是一个示例图像 - http://images.productserve.com/preview/3395/128554505.jpg.请注意,图片来自各个联盟网站,绝对来自不同的域名.
Jos*_*tos 46
要分析图像中的空白区域,我知道的唯一方法是将该图像加载到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';
Run Code Online (Sandbox Code Playgroud)
接下来,使用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.
};
Run Code Online (Sandbox Code Playgroud)
坦率地说,我无法测试这段代码是有充分理由的:我遇到了臭名昭着的" 无法从画布中获取图像数据,因为画布已经受到跨源数据的污染. "安全例外.
这不是一个错误,它是一个预期的功能.从规格:
toDataURL(),toDataURLHD(),toBlob(),getImageData()和getImageDataHD()方法检查标志并抛出SecurityError异常而不是泄漏跨源数据.
drawImage()从外部域加载文件时会发生这种情况,这会导致画布的origin-clean标志设置为false,从而阻止进一步的数据操作.
我担心你会遇到同样的问题,但无论如何,这是代码.
即使这在客户端起作用,我也可以想象在性能方面会有多么悲惨.所以,正如Jan所说,如果您可以下载图像并在服务器端预处理它们,那就更好了.
编辑:我很想知道我的代码是否会真正裁剪图像,事实确实如此.

你可以在这里查看
它仅适用于您域中的图像,如前所述.您可以选择自己的白色背景图像并更改最后一行:
// define here an image from your domain
img.src = 'http://localhost/strawberry2.jpg';
Run Code Online (Sandbox Code Playgroud)
显然,您需要从域中运行代码,而不是从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);
Run Code Online (Sandbox Code Playgroud)
至
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);
Run Code Online (Sandbox Code Playgroud)
Edit3:在浏览器上裁剪图像的一种快捷方法是通过使用Web Workers来并行化工作负载,正如这篇优秀的文章所解释的那样.
Moh*_*nna 14
基于提供的优秀答案Jose Rui Santos,我已将其代码更改为仅使用image对象而无需加载jQuery库.
该函数的返回是要在图像元素中直接使用的裁剪图像数据URL.
/*
Source: http://jsfiddle.net/ruisoftware/ddZfV/7/
Updated by: Mohammad M. AlBanna
Website: MBanna.info
Facebook: FB.com/MBanna.info
*/
var myImage = new Image();
myImage.crossOrigin = "Anonymous";
myImage.onload = function(){
var imageData = removeImageBlanks(myImage); //Will return cropped image data
}
myImage.src = "IMAGE SOURCE";
//-----------------------------------------//
function removeImageBlanks(imageObject) {
imgWidth = imageObject.width;
imgHeight = imageObject.height;
var canvas = document.createElement('canvas');
canvas.setAttribute("width", imgWidth);
canvas.setAttribute("height", imgHeight);
var context = canvas.getContext('2d');
context.drawImage(imageObject, 0, 0);
var imageData = context.getImageData(0, 0, imgWidth, imgHeight),
data = imageData.data,
getRBG = function(x, y) {
var offset = imgWidth * y + x;
return {
red: data[offset * 4],
green: data[offset * 4 + 1],
blue: data[offset * 4 + 2],
opacity: data[offset * 4 + 3]
};
},
isWhite = function (rgb) {
// many images contain noise, as the white is not a pure #fff white
return rgb.red > 200 && rgb.green > 200 && rgb.blue > 200;
},
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++) {
var rgb = getRBG(x, y);
if (!isWhite(rgb)) {
if (fromTop) {
return y;
} else {
return Math.min(y + 1, imgHeight);
}
}
}
}
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++) {
var rgb = getRBG(x, y);
if (!isWhite(rgb)) {
if (fromLeft) {
return x;
} else {
return Math.min(x + 1, imgWidth);
}
}
}
}
return null; // all image is white
};
var cropTop = scanY(true),
cropBottom = scanY(false),
cropLeft = scanX(true),
cropRight = scanX(false),
cropWidth = cropRight - cropLeft,
cropHeight = cropBottom - cropTop;
canvas.setAttribute("width", cropWidth);
canvas.setAttribute("height", cropHeight);
// finally crop the guy
canvas.getContext("2d").drawImage(imageObject,
cropLeft, cropTop, cropWidth, cropHeight,
0, 0, cropWidth, cropHeight);
return canvas.toDataURL();
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
20105 次 |
| 最近记录: |