Aby przeanalizować puste przestrzenie w obrazie, jedynym sposobem, wiem to, aby załadować ten obraz w 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';
Następnie użyj metody getImageData(). Ta metoda zwraca obiekt ImageData, którego można użyć do sprawdzenia danych każdego piksela (koloru).
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.
};
Szczerze mówiąc byłem w stanie przetestować ten kod za dobry powód: Natknąłem niesławnego „Nie można uzyskać dane obrazu z płótna, ponieważ płótno zostało skażone przez dane przekroju pochodzenia.” Wyjątek bezpieczeństwa .
To nie jest błąd, to zamierzona funkcja. Z specs:
The toDataURL(), toDataURLHD(), toBlob(), getImageData() i getImageDataHD() metody sprawdzenia flagi i rzuci SecurityError raczej wyjątek niż wyciek danych cross-origin .
Dzieje się tak, gdy drawImage()
ładuje pliki z domen zewnętrznych, co powoduje pochodzenie-Clean flagę płótna, który ma być ustawiona na false, co uniemożliwia dalsze manipulacje danymi.
obawiam trafisz na ten sam problem, ale mimo to, here is the code.
Nawet jeśli działa po stronie klienta, mogę sobie wyobrazić, jak będzie nieszczęśliwy wydajność mądry. Tak więc, jak powiedział Jan, jeśli można pobrać obrazy i wstępnie je przetworzyć po stronie serwera, byłoby lepiej.
Edit: Byłem ciekaw, czy mój kod będzie naprawdę przyciąć zdjęcie, i rzeczywiście tak jest.
Można to sprawdzić here
działa tylko w przypadku zdjęć z domeny, jak wspomniano wcześniej. Można wybrać własne zdjęcie z białym tłem i zmienić ostatni wiersz:
// define here an image from your domain
img.src = 'http://localhost/strawberry2.jpg';
Oczywiście, trzeba będzie uruchomić kod z domeny, a nie z jsFiddle.
Edit2: Jeśli chcesz przyciąć i skalowanie zachować takie same proporcje, a następnie zmienić
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);
do
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: Jeden szybki sposób przycinania obrazów w przeglądarce r, ma na celu zrównoleglenie obciążenia pracą poprzez użycie narzędzia Web Workers, co wyjaśnia ten excellent article.
Czy mogę zasugerować, że faktycznie dodajesz jedno ze zdjęć, na które pojawia się problem na twoje pytanie. Zapobiegnie to zamykaniu głosów, ponieważ skutecznie reklamujesz swoją witrynę. –
Możesz narysować obraz na płótnie i usunąć całe puste kolumny i wiersze, a następnie przeskalować obrazy do "tego samego" rozmiaru (zachowując proporcje). – Prusse
"Chcę używać javascript zamiast wstępnego przetwarzania obrazów" - Dlaczego? Dlaczego chcesz, aby przeglądarka użytkowników musiała usuwać białe spacje za każdym razem, gdy obraz jest wczytywany, zamiast po prostu robić to raz po stronie serwera, a następnie zapisywać obraz bez białych odstępów do wykorzystania w przyszłości? – h2ooooooo