Skip to content

Instantly share code, notes, and snippets.

@nicoptere
Created June 7, 2015 09:59
Show Gist options
  • Star 6 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save nicoptere/18c2dc4bc05ed9d5b36a to your computer and use it in GitHub Desktop.
Save nicoptere/18c2dc4bc05ed9d5b36a to your computer and use it in GitHub Desktop.
performs a scale2x and scale3x operation on a HTML canvas
/*
JavaScript port of the following algorithm : 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;
}
var can2x = document.createElement( "canvas" );
var s2ctx = can2x.getContext("2d");
function scale2x( context )
{
var w = context.canvas.width;
var h = context.canvas.height;
var w2 = w * 2;
var inputImageData = context.getImageData( 0,0,w,h );
var inputData = inputImageData.data;
can2x.width = w * 2;
can2x.height = h * 2;
var outputImageData = s2ctx.getImageData( 0,0,w*2,h*2 );
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;
s2ctx.putImageData( outputImageData,0,0 );
return s2ctx;
}
var can3x = document.createElement( "canvas" );
var s3ctx = can3x.getContext("2d");
function scale3x( context )
{
var w = context.canvas.width;
var w3 = w * 3;
var h = context.canvas.height;
var h3 = h * 3;
var inputImageData = context.getImageData( 0,0,w,h );
var inputData = inputImageData.data;
can3x.width = w * 3;
can3x.height = h * 3;
var outputImageData = s3ctx.getImageData( 0,0,w*3,h*3 );
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;
s3ctx.putImageData( outputImageData,0,0 );
return s3ctx;
}
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