-
-
Save samme/a1581d7a577a8ae59e78176178e54e50 to your computer and use it in GitHub Desktop.
Performs a scale2x and scale3x operation on a HTML canvas
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
JavaScript port of <http://scale2x.sourceforge.net/algorithm.html> | |
*/ | |
var scaleX = (function (exports) { | |
function getPixel32(data, x, y, w) { | |
var id = (x + y * w) * 4; | |
return (data[id] << 16) | (data[id + 1] << 8) | data[id + 2]; | |
} | |
function setPixel32(data, x, y, w, value) { | |
var id = (x + y * w) * 4; | |
data[id] = (value >> 16) & 0xff; | |
data[id + 1] = (value >> 8) & 0xff; | |
data[id + 2] = value & 0xff; | |
data[id + 3] = 0xff; | |
} | |
function scale2x(source, out) { | |
var w = source.canvas.width; | |
var h = source.canvas.height; | |
var w2 = w * 2; | |
var h2 = h * 2; | |
var inputImageData = source.getImageData(0, 0, w, h); | |
var inputData = inputImageData.data; | |
console.assert(out.canvas.width === w2); | |
console.assert(out.canvas.height === h2); | |
var outputImageData = out.getImageData(0, 0, w2, h2); | |
var outputData = outputImageData.data; | |
var E, E0, E1, E2, E3, B, D, F, H, i, j, i2, j2; | |
for (i = 0; i < w; i++) { | |
for (j = 0; j < h; j++) { | |
E = getPixel32(inputData, i, j, w); | |
//edges handling | |
if (i == 0 || j == 0 || i == w - 1 || j == h - 1) { | |
E0 = E; | |
E1 = E; | |
E2 = E; | |
E3 = E; | |
} else { | |
B = getPixel32(inputData, i, j - 1, w); | |
D = getPixel32(inputData, i - 1, j, w); | |
F = getPixel32(inputData, i + 1, j, w); | |
H = getPixel32(inputData, i, j + 1, w); | |
if (B != H && D != F) { | |
E0 = D == B ? D : E; | |
E1 = B == F ? F : E; | |
E2 = D == H ? D : E; | |
E3 = H == F ? F : E; | |
} else { | |
E0 = E; | |
E1 = E; | |
E2 = E; | |
E3 = E; | |
} | |
} | |
i2 = i * 2; | |
j2 = j * 2; | |
setPixel32(outputData, i2, j2, w2, E0); | |
setPixel32(outputData, i2 + 1, j2, w2, E1); | |
setPixel32(outputData, i2, j2 + 1, w2, E2); | |
setPixel32(outputData, i2 + 1, j2 + 1, w2, E3); | |
} | |
} | |
outputImageData.data = outputData; | |
out.putImageData(outputImageData, 0, 0); | |
return out; | |
} | |
function scale3x(source, out) { | |
var w = source.canvas.width; | |
var h = source.canvas.height; | |
var w3 = w * 3; | |
var h3 = h * 3; | |
var inputImageData = source.getImageData(0, 0, w, h); | |
var inputData = inputImageData.data; | |
console.assert(out.canvas.width === w3, 'Output canvas width', out.canvas.width, w3); | |
console.assert(out.canvas.height === h3, 'Output canvas height', out.canvas.height, h3); | |
var outputImageData = out.getImageData(0, 0, w3, h3); | |
var outputData = outputImageData.data; | |
var E, E0, E1, E2, E3, E4, E5, E6, E7, E8, A, B, C, D, F, G, H, I, i, j, i3, j3; | |
for (i = 0; i < w; i++) { | |
for (j = 0; j < h; j++) { | |
E = getPixel32(inputData, i, j, w); | |
// edges handling | |
if (i == 0 || j == 0 || i == w - 1 || j == h - 1) { | |
E0 = E; | |
E1 = E; | |
E2 = E; | |
E3 = E; | |
E4 = E; | |
E5 = E; | |
E6 = E; | |
E7 = E; | |
E8 = E; | |
} else { | |
A = getPixel32(inputData, i - 1, j - 1, w); | |
B = getPixel32(inputData, i, j - 1, w); | |
C = getPixel32(inputData, i, j + 1, w); | |
D = getPixel32(inputData, i - 1, j, w); | |
F = getPixel32(inputData, i + 1, j, w); | |
G = getPixel32(inputData, i - 1, j + 1, w); | |
H = getPixel32(inputData, i, j + 1, w); | |
I = getPixel32(inputData, i + 1, j + 1, w); | |
if (B != H && D != F) { | |
E0 = D == B ? D : E; | |
E1 = (D == B && E != C) || (B == F && E != A) ? B : E; | |
E2 = B == F ? F : E; | |
E3 = (D == B && E != G) || (D == H && E != A) ? D : E; | |
E4 = E; | |
E5 = (B == F && E != I) || (H == F && E != C) ? F : E; | |
E6 = D == H ? D : E; | |
E7 = (D == H && E != I) || (H == F && E != G) ? H : E; | |
E8 = H == F ? F : E; | |
} else { | |
E0 = E; | |
E1 = E; | |
E2 = E; | |
E3 = E; | |
E4 = E; | |
E5 = E; | |
E6 = E; | |
E7 = E; | |
E8 = E; | |
} | |
} | |
i3 = i * 3; | |
j3 = j * 3; | |
setPixel32(outputData, i3, j3, w3, E0); | |
setPixel32(outputData, i3 + 1, j3, w3, E1); | |
setPixel32(outputData, i3 + 2, j3, w3, E2); | |
setPixel32(outputData, i3, j3 + 1, w3, E3); | |
setPixel32(outputData, i3 + 1, j3 + 1, w3, E4); | |
setPixel32(outputData, i3 + 2, j3 + 1, w3, E5); | |
setPixel32(outputData, i3, j3 + 2, w3, E6); | |
setPixel32(outputData, i3 + 1, j3 + 2, w3, E7); | |
setPixel32(outputData, i3 + 2, j3 + 2, w3, E8); | |
} | |
} | |
outputImageData.data = outputData; | |
out.putImageData(outputImageData, 0, 0); | |
return out; | |
} | |
exports.scale2x = scale2x; | |
exports.scale3x = scale3x; | |
return exports; | |
})({}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment