Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Give toDataURL() and toBlob() default parameter values #3477

Merged
merged 4 commits into from
Jan 30, 2019
Merged
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 23 additions & 16 deletions source
Original file line number Diff line number Diff line change
Expand Up @@ -59184,8 +59184,8 @@ interface <dfn>HTMLCanvasElement</dfn> : <span>HTMLElement</span> {

<span>RenderingContext</span>? <span data-x="dom-canvas-getContext">getContext</span>(DOMString contextId, optional any options = null);

USVString <span data-x="dom-canvas-toDataURL">toDataURL</span>(optional DOMString type, optional any quality);
void <span data-x="dom-canvas-toBlob">toBlob</span>(<span>BlobCallback</span> _callback, optional DOMString type, optional any quality);
USVString <span data-x="dom-canvas-toDataURL">toDataURL</span>(optional DOMString type = "image/png", optional any quality);
void <span data-x="dom-canvas-toBlob">toBlob</span>(<span>BlobCallback</span> _callback, optional DOMString type = "image/png", optional any quality);
<span>OffscreenCanvas</span> <span data-x="dom-canvas-transferControlToOffscreen">transferControlToOffscreen</span>();
};

Expand Down Expand Up @@ -59572,7 +59572,7 @@ callback <dfn>BlobCallback</dfn> = void (<span>Blob</span>? blob);</pre>

<li><p>Let <var>file</var> be <span data-x="a serialization of the bitmap as a file">a
serialization of this <code>canvas</code> element's bitmap as a file</span>, passing
<var>type</var> and <var>quality</var> if they were given.</p></li>
<var>type</var> and <var>quality</var> if given.</p></li>
annevk marked this conversation as resolved.
Show resolved Hide resolved

<li><p>If <var>file</var> is null then return "<code data-x="">data:,</code>".</p></li>

Expand Down Expand Up @@ -59603,8 +59603,8 @@ callback <dfn>BlobCallback</dfn> = void (<span>Blob</span>? blob);</pre>

<ol>
<li><p>If <var>result</var> is non-null, then set <var>result</var> to <span data-x="a
serialization of the bitmap as a file">a serialization of <var>result</var> as a file</span>,
with <var>type</var> and <var>quality</var> if they were given.</p></li>
serialization of the bitmap as a file">a serialization of <var>result</var> as a file</span>
with <var>type</var> and <var>quality</var> if given.</p></li>
annevk marked this conversation as resolved.
Show resolved Hide resolved

<li>
<p><span>Queue a task</span> to run these steps:</p>
Expand Down Expand Up @@ -64835,7 +64835,7 @@ dictionary <dfn>ImageBitmapRenderingContextSettings</dfn> {

dictionary <dfn>ImageEncodeOptions</dfn> {
DOMString <span data-x="image-encode-options-type">type</span> = "image/png";
unrestricted double <span data-x="image-encode-options-quality">quality</span> = 1.0;
unrestricted double <span data-x="image-encode-options-quality">quality</span>;
};

enum <dfn>OffscreenRenderingContextId</dfn> { "<span data-x="offscreen-context-type-2d">2d</span>", "<span data-x="offscreen-context-type-webgl">webgl</span>" };
Expand Down Expand Up @@ -65416,11 +65416,10 @@ interface <dfn>OffscreenCanvasRenderingContext2D</dfn> {
<div w-nodev>

<p>When a user agent is to create <!--en-GB--><dfn id="a-serialisation-of-the-bitmap-as-a-file">a
serialization of the bitmap as a file</dfn>, given an optional <var>type</var> and
<var>quality</var>, it must create an image file in the format given by <var>type</var>, or if
<var>type</var> was not supplied, in the PNG format. If an error occurs during the creation of
the image file (e.g. an internal encoder error), then the result of the serialization is null.
<ref spec=PNG></p>
serialization of the bitmap as a file</dfn>, given a <var>type</var> and an optional
annevk marked this conversation as resolved.
Show resolved Hide resolved
<var>quality</var>, it must create an image file in the format given by <var>type</var>. If an
error occurs during the creation of the image file (e.g. an internal encoder error), then the
result of the serialization is null. <ref spec=PNG></p>

<p>The image file's pixel data must be the bitmap's pixel data scaled to one image pixel per
coordinate space unit, and if the file format used supports encoding resolution metadata, the
Expand All @@ -65447,16 +65446,24 @@ interface <dfn>OffscreenCanvasRenderingContext2D</dfn> {
image composited onto a solid black background using the source-over operator.</p>

<p>If <var>type</var> is an image format that supports variable quality (such as
"<code>image/jpeg</code>") and <var>quality</var> is given, then, if <span
data-x="js-Type">Type</span>(<var>quality</var>) is Number, and <var>quality</var> is in the range
0.0 to 1.0 inclusive, the user agent must treat <var>quality</var> as the desired quality level.
If <span data-x="js-Type">Type</span>(<var>quality</var>) is not Number, or if <var>quality</var>
is outside that range, the user agent must use its default quality value, as if the
"<code>image/jpeg</code>"), <var>quality</var> is given, and <var>type</var> is not
annevk marked this conversation as resolved.
Show resolved Hide resolved
"<code>image/png</code>", then, if <span data-x="js-Type">Type</span>(<var>quality</var>) is
Number, and <var>quality</var> is in the range 0.0 to 1.0 inclusive, the user agent must treat
<var>quality</var> as the desired quality level. If <span
annevk marked this conversation as resolved.
Show resolved Hide resolved
data-x="js-Type">Type</span>(<var>quality</var>) is not Number, or if <var>quality</var> is
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if we should just use 1.0 here as well. @junov?

Copy link
Member

@junov junov Feb 19, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have reservations about this change. This is not backwards compatible and will cause regressions. Changing the default to 1.0 will cause all websites that currently use the default to suddenly create much larger files and to take more time than before. Currently the default is a sensible compromise between quality, compression ratio, and encoding performance. The reason the default value is not standardized is that different browsers use different encoder libraries that each have their own interpretation for this parameter. To overcome this problem, each browser gets to decide what its implementation-specific default should be. This provides web devs with a interoperable way of getting a reasonable quality/compression compromise.

In my opinion we should not specify a default parameter value unless we also standardize the interpretation of the parameter value. If we do go down that road, then we should set the default to something that is backwards compatible (not 1.0).

A way forward for the spec would be to select a reference open source implementation for each format that supports the quality parameter (e.g. libjpeg for image/jpeg), and to state that the interpretation of the quality parameter is the one defined by that reference implementation. Browsers that use a different encoder library may need to apply a conversion to the quality parameter in order to match the interpretation from the reference implementation. Then we could standardize the default parameter value in a backwards compatible way.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If that's the case why did you specify a default for OffscreenCanvas? Is that a bug that needs to be fixed?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OffscreenCanvas is a new API, so there is no backward compatibility issue.

PNG, which is the default format, can support a variable quality setting, but historically PNG has been used for lossless compression and developers have an expectation that PNG encoding should be lossless by default, and many browser implementation ignore the quality parameter when encoding PNGs. That is why I set the default to 1.0.

I realize now that there still problem... there's the issue of providing an interoperable quality/compression compromise for JPEG. I guess this needs more thought...

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It sounds like we should say that for "image/png" we set quality to 1.0 irrespective of its actual value and for other formats the default is user agent defined (and we don't fiddle with the value unless it's out of range or not a number). And we remove the 1.0 default from IDL for OffscreenCanvas and not add it here.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's see:

  1. Remove = 1.0 from IDL (including from the ImageEncodeOptions dictionary).
  2. Turn quality into an optional argument again. Only type is always given now. You will also need to change this in convertToBlob() (step 6.1).
  3. Change "If type is an image format that supports variable quality" to say something like "If type is an image format that supports variable quality, type is not "image/png", ..." so that even though image/png supports variable quality, quality is not taken into account for it.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would also be nice to have a non-normative note explaining that different implementations may have slightly different interpretations of "quality" and that when quality is not specified an implementation-specific default is used that represents a reasonable compromise between compression ratio, image quality and encoding time.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As an implementor, agree with @junov. A non-normative note would allow implementors some latitude e.g. to achieve said compromise in the case of the default. Was that added?

In the case on image/png, does opt_quality apply? If so, what does it mean given the image is losslessly encoded? It would be nice if opt_quality could be used to control the compression. 0 - minimal compression and so a fast encode. 1 - maximum compression and a slow encode. default - the implementation-specific compromise b/w compression & encoding time. Adios.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

https://bugs.chromium.org/p/chromium/issues/detail?id=179289 Request to control compression quality for .toDataURL "image/png".

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@noell that should be a separate issue as that would be a normative change to the standard (image/png has to ignore quality at the moment).

outside that range, the user agent must use its default quality value, as if the
<var>quality</var> argument had not been given.</p>
annevk marked this conversation as resolved.
Show resolved Hide resolved

<p class="note">The use of type-testing here, instead of simply declaring <var>quality</var> as
a Web IDL <code data-x="">double</code>, is a historical artifact.</p>

<!-- NON-NORMATIVE SECTION -->
annevk marked this conversation as resolved.
Show resolved Hide resolved

<p class="note">Different implementations can have slightly different interpretations of
"quality". When the quality is not specified, an implementation-specific default is used that
represents a reasonable compromise between compression ratio, image quality, and encoding
time.</p>

</div>
annevk marked this conversation as resolved.
Show resolved Hide resolved


Expand Down