Saya menggunakan elemen kanvas html5 untuk mengubah ukuran gambar di browser saya. Ternyata kualitasnya sangat rendah. Saya menemukan ini: Nonaktifkan Interpolasi saat Melakukan Penskalaan <kanvas> tetapi tidak membantu meningkatkan kualitas.
Di bawah ini adalah kode css dan js saya serta gambar yang dipindai dengan Photoshop dan diskalakan di kanvas API.
Apa yang harus saya lakukan untuk mendapatkan kualitas optimal saat menskala gambar di browser?
Catatan: Saya ingin memperkecil gambar besar menjadi kecil, memodifikasi warna di kanvas dan mengirim hasilnya dari kanvas ke server.
CSS:
canvas, img {
image-rendering: optimizeQuality;
image-rendering: -moz-crisp-edges;
image-rendering: -webkit-optimize-contrast;
image-rendering: optimize-contrast;
-ms-interpolation-mode: nearest-neighbor;
}
JS:
var $img = $('<img>');
var $originalCanvas = $('<canvas>');
$img.load(function() {
var originalContext = $originalCanvas[0].getContext('2d');
originalContext.imageSmoothingEnabled = false;
originalContext.webkitImageSmoothingEnabled = false;
originalContext.mozImageSmoothingEnabled = false;
originalContext.drawImage(this, 0, 0, 379, 500);
});
Ukuran gambar dengan photoshop:
Ukuran gambar di kanvas:
Edit:
Saya mencoba membuat downscaling dalam lebih dari satu langkah seperti yang diusulkan dalam:
Mengubah ukuran gambar di kanvas HTML5 dan kanvas gambar Html5 drawImage: cara menerapkan antialiasing
Ini adalah fungsi yang saya gunakan:
function resizeCanvasImage(img, canvas, maxWidth, maxHeight) {
var imgWidth = img.width,
imgHeight = img.height;
var ratio = 1, ratio1 = 1, ratio2 = 1;
ratio1 = maxWidth / imgWidth;
ratio2 = maxHeight / imgHeight;
// Use the smallest ratio that the image best fit into the maxWidth x maxHeight box.
if (ratio1 < ratio2) {
ratio = ratio1;
}
else {
ratio = ratio2;
}
var canvasContext = canvas.getContext("2d");
var canvasCopy = document.createElement("canvas");
var copyContext = canvasCopy.getContext("2d");
var canvasCopy2 = document.createElement("canvas");
var copyContext2 = canvasCopy2.getContext("2d");
canvasCopy.width = imgWidth;
canvasCopy.height = imgHeight;
copyContext.drawImage(img, 0, 0);
// init
canvasCopy2.width = imgWidth;
canvasCopy2.height = imgHeight;
copyContext2.drawImage(canvasCopy, 0, 0, canvasCopy.width, canvasCopy.height, 0, 0, canvasCopy2.width, canvasCopy2.height);
var rounds = 2;
var roundRatio = ratio * rounds;
for (var i = 1; i <= rounds; i++) {
console.log("Step: "+i);
// tmp
canvasCopy.width = imgWidth * roundRatio / i;
canvasCopy.height = imgHeight * roundRatio / i;
copyContext.drawImage(canvasCopy2, 0, 0, canvasCopy2.width, canvasCopy2.height, 0, 0, canvasCopy.width, canvasCopy.height);
// copy back
canvasCopy2.width = imgWidth * roundRatio / i;
canvasCopy2.height = imgHeight * roundRatio / i;
copyContext2.drawImage(canvasCopy, 0, 0, canvasCopy.width, canvasCopy.height, 0, 0, canvasCopy2.width, canvasCopy2.height);
} // end for
// copy back to canvas
canvas.width = imgWidth * roundRatio / rounds;
canvas.height = imgHeight * roundRatio / rounds;
canvasContext.drawImage(canvasCopy2, 0, 0, canvasCopy2.width, canvasCopy2.height, 0, 0, canvas.width, canvas.height);
}
Inilah hasilnya jika saya menggunakan ukuran 2 langkah turun:
Inilah hasilnya jika saya menggunakan ukuran 3 langkah turun:
Ini hasilnya jika saya menggunakan ukuran 4 langkah:
Inilah hasilnya jika saya menggunakan ukuran 20 langkah turun:
Catatan: Ternyata dari 1 langkah ke 2 langkah ada peningkatan besar dalam kualitas gambar tetapi semakin banyak langkah yang Anda tambahkan ke proses semakin fuzzy gambar menjadi.
Apakah ada cara untuk menyelesaikan masalah sehingga gambar menjadi lebih kabur, semakin banyak langkah yang Anda tambahkan?
Sunting 2013-10-04: Saya mencoba algoritma dari GameAlchemist. Ini hasilnya dibandingkan dengan Photoshop.
Gambar PhotoShop:
Algoritma GameAlchemist: