分析圖像中的空白,我知道唯一的辦法就是到圖像加載到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