Use Hermite resampling for comparator canvas previews
This commit is contained in:
parent
90810cc605
commit
a1c419dc71
|
@ -342,11 +342,12 @@ var OCdialogs = {
|
||||||
|
|
||||||
var crop = function(img) {
|
var crop = function(img) {
|
||||||
var canvas = document.createElement('canvas'),
|
var canvas = document.createElement('canvas'),
|
||||||
width = img.width,
|
targetSize = 96,
|
||||||
height = img.height,
|
width = img.width,
|
||||||
x, y, size;
|
height = img.height,
|
||||||
|
x, y, size;
|
||||||
|
|
||||||
// calculate the width and height, constraining the proportions
|
// Calculate the width and height, constraining the proportions
|
||||||
if (width > height) {
|
if (width > height) {
|
||||||
y = 0;
|
y = 0;
|
||||||
x = (width - height) / 2;
|
x = (width - height) / 2;
|
||||||
|
@ -356,14 +357,90 @@ var OCdialogs = {
|
||||||
}
|
}
|
||||||
size = Math.min(width, height);
|
size = Math.min(width, height);
|
||||||
|
|
||||||
// resize the canvas and draw the image data into it
|
// Set canvas size to the cropped area
|
||||||
canvas.width = 64;
|
canvas.width = size;
|
||||||
canvas.height = 64;
|
canvas.height = size;
|
||||||
var ctx = canvas.getContext("2d");
|
var ctx = canvas.getContext("2d");
|
||||||
ctx.drawImage(img, x, y, size, size, 0, 0, 64, 64);
|
ctx.drawImage(img, x, y, size, size, 0, 0, size, size);
|
||||||
|
|
||||||
|
// Resize the canvas to match the destination (right size uses 96px)
|
||||||
|
resampleHermite(canvas, size, size, targetSize, targetSize);
|
||||||
|
|
||||||
return canvas.toDataURL("image/png", 0.7);
|
return canvas.toDataURL("image/png", 0.7);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fast image resize/resample using Hermite filter with JavaScript.
|
||||||
|
*
|
||||||
|
* @author: ViliusL
|
||||||
|
*
|
||||||
|
* @param {*} canvas
|
||||||
|
* @param {number} W
|
||||||
|
* @param {number} H
|
||||||
|
* @param {number} W2
|
||||||
|
* @param {number} H2
|
||||||
|
*/
|
||||||
|
var resampleHermite = function (canvas, W, H, W2, H2) {
|
||||||
|
W2 = Math.round(W2);
|
||||||
|
H2 = Math.round(H2);
|
||||||
|
var img = canvas.getContext("2d").getImageData(0, 0, W, H);
|
||||||
|
var img2 = canvas.getContext("2d").getImageData(0, 0, W2, H2);
|
||||||
|
var data = img.data;
|
||||||
|
var data2 = img2.data;
|
||||||
|
var ratio_w = W / W2;
|
||||||
|
var ratio_h = H / H2;
|
||||||
|
var ratio_w_half = Math.ceil(ratio_w / 2);
|
||||||
|
var ratio_h_half = Math.ceil(ratio_h / 2);
|
||||||
|
|
||||||
|
for (var j = 0; j < H2; j++) {
|
||||||
|
for (var i = 0; i < W2; i++) {
|
||||||
|
var x2 = (i + j * W2) * 4;
|
||||||
|
var weight = 0;
|
||||||
|
var weights = 0;
|
||||||
|
var weights_alpha = 0;
|
||||||
|
var gx_r = 0;
|
||||||
|
var gx_g = 0;
|
||||||
|
var gx_b = 0;
|
||||||
|
var gx_a = 0;
|
||||||
|
var center_y = (j + 0.5) * ratio_h;
|
||||||
|
for (var yy = Math.floor(j * ratio_h); yy < (j + 1) * ratio_h; yy++) {
|
||||||
|
var dy = Math.abs(center_y - (yy + 0.5)) / ratio_h_half;
|
||||||
|
var center_x = (i + 0.5) * ratio_w;
|
||||||
|
var w0 = dy * dy; //pre-calc part of w
|
||||||
|
for (var xx = Math.floor(i * ratio_w); xx < (i + 1) * ratio_w; xx++) {
|
||||||
|
var dx = Math.abs(center_x - (xx + 0.5)) / ratio_w_half;
|
||||||
|
var w = Math.sqrt(w0 + dx * dx);
|
||||||
|
if (w >= -1 && w <= 1) {
|
||||||
|
//hermite filter
|
||||||
|
weight = 2 * w * w * w - 3 * w * w + 1;
|
||||||
|
if (weight > 0) {
|
||||||
|
dx = 4 * (xx + yy * W);
|
||||||
|
//alpha
|
||||||
|
gx_a += weight * data[dx + 3];
|
||||||
|
weights_alpha += weight;
|
||||||
|
//colors
|
||||||
|
if (data[dx + 3] < 255)
|
||||||
|
weight = weight * data[dx + 3] / 250;
|
||||||
|
gx_r += weight * data[dx];
|
||||||
|
gx_g += weight * data[dx + 1];
|
||||||
|
gx_b += weight * data[dx + 2];
|
||||||
|
weights += weight;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
data2[x2] = gx_r / weights;
|
||||||
|
data2[x2 + 1] = gx_g / weights;
|
||||||
|
data2[x2 + 2] = gx_b / weights;
|
||||||
|
data2[x2 + 3] = gx_a / weights_alpha;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
canvas.getContext("2d").clearRect(0, 0, Math.max(W, W2), Math.max(H, H2));
|
||||||
|
canvas.width = W2;
|
||||||
|
canvas.height = H2;
|
||||||
|
canvas.getContext("2d").putImageData(img2, 0, 0);
|
||||||
|
};
|
||||||
|
|
||||||
var addConflict = function($conflicts, original, replacement) {
|
var addConflict = function($conflicts, original, replacement) {
|
||||||
|
|
||||||
var $conflict = $conflicts.find('.template').clone().removeClass('template').addClass('conflict');
|
var $conflict = $conflicts.find('.template').clone().removeClass('template').addClass('conflict');
|
||||||
|
|
Loading…
Reference in New Issue