Html5 canvas drawImage: how to apply antialiasing -


please have @ following example:

http://jsfiddle.net/mlgr4/47/

    var canvas=document.getelementbyid("canvas");     var ctx=canvas.getcontext("2d");      img=new image();     img.onload=function(){         canvas.width=400;         canvas.height=150;         ctx.drawimage(img,0,0,img.width,img.height,0,0,400,150);     }     img.src="http://openwalls.com/image/1734/colored_lines_on_blue_background_1920x1200.jpg"; 

as see, image not anti-aliased although said drawimage applies anti aliasing automatically. tried many different ways doesn't seem work. please tell me how can anti-aliased image? thanks.

cause

some images hard down-sample , interpolate such 1 curves when want go large size small.

browsers appear typically use bi-linear (2x2 sampling) interpolation canvas element rather bi-cubic (4x4 sampling) (likely) performance reasons.

if step huge there not enough pixels sample reflected in result.

from signal/dsp perspective see low-pass filter's threshold value set high, may result in aliasing if there many high frequencies (details) in signal.

solution

update 2017: there new property defined in specs setting resampling quality:

context.imagesmoothingquality = "low|medium|high" 

it's supported in chrome. actual methods used per level left vendor decide, it's reasonable assume lanczos "high" or equivalent in quality. means step-down may skipped altogether, or larger steps can used fewer redraws, depending on image size , browser. until then..:
end of transmission

the solution use step-down proper result. step-down means reduce size in steps allow limited interpolation range cover enough pixels sampling.

this allow results bi-linear interpolation (it behaves bi-cubic when doing this) , overhead minimal there less pixels sample in each step.

the ideal step go half resolution in each step until set target size (thanks joe mabel mentioning this!).

modified fiddle

using direct scaling in original question:

normal down-scaled image

using step-down shown below:

down-stepped image

in case need step down in 3 steps:

in step 1 reduce image half using off-screen canvas:

/// step 1 - create off-screen canvas var oc   = document.createelement('canvas'),     octx = oc.getcontext('2d');  oc.width  = img.width  * 0.5; oc.height = img.height * 0.5;  octx.drawimage(img, 0, 0, oc.width, oc.height); 

step 2 reuses off-screen canvas , draws image reduced half again:

/// step 2 octx.drawimage(oc, 0, 0, oc.width * 0.5, oc.height * 0.5); 

and draw once more main canvas, again reduced to half final size:

/// step 3 ctx.drawimage(oc, 0, 0, oc.width * 0.5, oc.height * 0.5,                   0, 0, canvas.width,   canvas.height); 

tip:

you can calculate total number of steps needed, using formula (it includes final step set target size):

steps = math.ceil(math.log(sourcewidth / targetwidth) / math.log(2)) 

Comments

Popular posts from this blog

curl - PHP fsockopen help required -

HTTP/1.0 407 Proxy Authentication Required PHP -

c# - Resource not found error -