W3C home > Mailing lists > Public > public-html@w3.org > June 2008

Re: <canvas> JPEG quality

From: Philip Taylor <pjt47@cam.ac.uk>
Date: Thu, 05 Jun 2008 16:47:33 +0100
Message-ID: <48480A95.6000709@cam.ac.uk>
To: Anne van Kesteren <annevk@opera.com>
CC: HTML WG <public-html@w3.org>

Anne van Kesteren wrote:
> At Opera we're planning on adding support to <canvas> for JPEG as export 
> format. To make the file size reasonable there needs to be a way to set 
> the quality level of the JPEG. [...]
> One simple solution to this which is reasonably consistent with the rest 
> of the <canvas> API is to add a jpegQuality DOM attribute to the 
> <canvas> element which takes an integer in the range 0-1 (similar to 
> globalAlpha). [...]

The spec already suggests a mechanism for this:

   "Arguments other than the type must be ignored, and must not cause 
the user agent to raise an exception (as would normally occur if a 
method was called with the wrong number of arguments). A future version 
of this specification will probably allow extra parameters to be passed 
to toDataURL() to allow authors to more carefully control compression 
settings, image metadata, etc."

So this would be

   toDataURL('image/jpeg', 0.75);

which seems nicer to me, since it keeps the parameter-setting and 
parameter-using code in one place (hence making the code easier to 
understand, with fewer invisible dependencies), and there's only this 
single parameter for JPEG and shouldn't be any more in the future (and 
so there isn't a real danger of the function-parameter API getting 
horribly long).

Firefox 2/3 violates the spec 
(https://bugzilla.mozilla.org/show_bug.cgi?id=401795) and throws a 
security exception when there's an extra argument to toDataURL, so 
actually you'd have to write a try/catch block and fall back if the call 
fails; but you'll have to use try/catch anyway, even with 
ctx.jpegQuality, because Firefox always throws if the first argument is 
not image/png (instead of falling back to PNG as per spec). So the real 
code would be more like:

   var data;
   try {
     data = ctx.toDataURL('image/jpeg', 0.75);
   } catch (e) {
     try {
       data = ctx.toDataURL();
     } catch (e) {
       alert('Sorry, your browser does not support saving this image.');

(and using .jpegQuality would have the same exception-handling 
complexity, so there's no real difference.)

Philip Taylor
Received on Thursday, 5 June 2008 15:48:18 UTC

This archive was generated by hypermail 2.4.0 : Saturday, 9 October 2021 18:44:32 UTC