Javascript/ toDataURL PNG color inconsistency




a year ago
a year ago


(Reporter: colormatch, Unassigned, NeedInfo)


53 Branch

Firefox Tracking Flags

(Not tracked)


(Whiteboard: [gfx-noted])


(3 attachments)



a year ago
Created attachment 8868476 [details]

User Agent: Mozilla/5.0 (Windows NT 6.2; Win64; x64; rv:53.0) Gecko/20100101 Firefox/53.0
Build ID: 20170504105526

Steps to reproduce:

Analyzing colors of image generated by canvas.toDataURL('image/png') differs from canvas.toDataURL('image/jpeg').

Other browsers Chrome/Opera/Vivaldi match Firefox's jpeg result.
(see attached file)

tested on v53 and v55 (nightly built) with same results.

Actual results:

canvas.toDataURL('image/png') produces color corrected, or image with improper colorspace. 

Expected results:

canvas.toDataURL('image/png')  should have matched canvas.toDataURL('image/jpeg'), and Chrome/Opera/Vivaldi's results.
(see attached file)

Comment 1

a year ago
Do you have a small testacse to repro the issue, please.
Flags: needinfo?(colormatch)
Component: Untriaged → Canvas: 2D
Product: Firefox → Core

Comment 2

a year ago
(In reply to Loic from comment #1)
> Do you have a small testacse to repro the issue, please.

This web-app: creates resized samples of the loaded images, using "toDataURL" and the samples are "POST-ed" to the backend, which analyzes the sent color information and returns a solution for color-conversion.

When toDataURL('image/jpeg') is used (to send the samples), all browsers produce same results.
When toDataURL('image/png') is used, all other browsers still produce the same result, but Firefox's result differs.
Current implementation uses toDataURL('image/png'), so you should be able to see the difference.

I'm not familiar with PNG's file specification and structure to further narrow down the problem.

The simplest test will be:
Load a color-calibration image in a canvas, and compare the exported canvas.toDataURL('image/png') and  canvas.toDataURL('image/jpeg') in terms of color-reproduction.
Flags: needinfo?(colormatch)

Comment 3

a year ago
I still don't understand to reproduce the issue on

Could you give excat steps to reproduce the issue, please. Should I upload jpeg or png image?
Flags: needinfo?(colormatch)

Comment 4

a year ago
(In reply to Loic from comment #3)
> I still don't understand to reproduce the issue on
> Could you give excat steps to reproduce the issue, please. Should I upload
> jpeg or png image?

The problem/bug is not the loading part, it is in the javascript method toDataURL('image/png').

The HTMLCanvasElement.toDataURL() method returns a data URI containing a representation of the image in the format specified by the type parameter.

When the parameter is JPEG, or toDataURL('image/jpeg'), the created by the method image, matches the rest of the browsers.
When the parameter is PNG, or toDataURL('image/png'), the created by the method image by Firefox is different in colors from the one created by toDataURL('image/jpeg'), and from the rest of the browsers.

More information on what "toDataURL" does can be found here:

Steps to reproduce using the web-app:
Step 1: Click and select source image (you can use one from included set)
Step 2: Click and select target image (just not black and white, as the problem is with the colors)
Step 3: visually inspect the result, and compare with other browsers. The ones I tested were Opera/Chrome/Vivaldi.
(you can see the attached image file as an example of what to expect)

Finding based on:
If I use in my web-app's code toDataURL('image/jpeg'), all browsers, including Firefox produce the same result/colors.
If I use in my web-app's code toDataURL('image/png'), the rest of the browsers still show the same result, but Firefox's result is different, which means the generated by the method toDataURL PNG is either color-corrected[1] by Firefox (it shouldn't have been), or it has specified improper color-space[2], (or it has some other specification error).

[1] More information on color correction in Firefox can be found here:

[2] More on the color-space of Portable Network Graphics (PNG) Specification:

If you need information on what toDataURL does, or how to use it, it can be found here:
Flags: needinfo?(colormatch)

Comment 5

a year ago
Created attachment 8869645 [details]

comparison results

Comment 6

a year ago
It seems that the color-correction is not limited to the toDataURL('image/png')

Using toDataURL('image/jpeg',1.0) results in similar color corrections as toDataURL('image/png'), yet not exactly the same, and toDataURL('image/jpeg') starts showing similar (but not the same) color gamut as the rest of the browsers' uncompressed processing (which means even using toDataURL('image/jpeg',1.0) the results will not be the same). However the last result could be due to the color compression.

see attachment 8869645 [details] 
Hi Jeff,
Please see attachment 8869645 [details].
Only firefox shows the different color for toDataURL('image/png') and toDataURL('image/jpeg').
Is it related to the color management problem?
Flags: needinfo?(jmuizelaar)
Priority: -- → P3
Whiteboard: [gfx-noted]

Comment 8

a year ago
as the color-difference is seen both in Firefox's uncompressed png, and least compressed jpeg (@ 100% quality), it means the problem is not with broken PNG specification export, but most likely a color-correction applied on the canvas before being exported for processing by toDataURL.
(at least that's the only thing I can think of, that explains the situation)

Does Firefox apply color-correction on the canvas before sending it to toDataURL?

I'm using the default settings:


Comment 9

a year ago
The issue looks like it had to do with color spaces.

After forcing colorspace-transform of the generated data (by toDataURL) at the back-end, 
toDataURL('image/png') produced result as toDataURL('image/jpeg'), which is (almost*) the same as the other browsers.
(I didn't test  toDataURL('image/jpeg',1.0) as it is no longer relevant to my use)

While viewing those "toDataUrl" results in-browser looks "fine", note: 
"The toDataURL() method must not include color space information in the resource returned."

re: almost*
- this may be side-effect from the colorspace transforms, or subject to a different bug

I hope this information is helpful, and you investigate further to resolve those issues.


Comment 10

a year ago
Created attachment 8872112 [details]

(In reply to Jerry Shih[:jerry] (UTC+8) from comment #7)
> Is it related to the color management problem?

As test were done on Linux, more inconsistency showed up.

attached file: Firefox-problem-Win-Linux-dataToURL.jpg

examples are (in a row):
Windows: Firefox 53.0.3 64bit, Chrome, Vivaldi, Opera, Linux: Firefox  53.0.3 64bit for Ubuntu canonical-1.0, Chrome 58

First row is using toDataURL() output directly, without correcting for "color space" (as it is in the w3 specifications).

Second row is with correcting for color-space.
(notice that even then there is small difference between Firefox and Blink engine, and that difference is revered in Linux test - where Linux-Chrome's output matches Windows-Firefox's and Linux-Firefox matches Windows-Chrome)

To replicate the test: 
load the "source image" from the ones included in the app (it is in the list of samples), 
the target image is can be downloaded from here:
click on the "target image" box and load "Leica-Q-sample-image-3.jpg"

Comment 11

a year ago

Examining the generated canvas.toDataURL did not show any color profiles, however the errors persist.

Here you can see the error created in by firefox in image-2, and what is should be in image-3:

Original image-file was downloaded from facebook, it is my own image (I own the copyright), however I say this, as facebook recompresses the jpg.

If I load "original.jpg" if firefox - there is error. 
If I open "original.jpg" in photoshop, re-save it to "original-resaved-PS.jpg", and load "original-resaved-PS.jpg" in Firefox, there is no error. 
If I load the result of toDataURL created by firefox in Chrome - there is error.
If I load the result of toDataURL created by Chrome in firefox- there is no error.

Summary for Firefox loading:
original.jpg -> error
original-resaved-PS.jpg -> good
chrome-canvas.toDataURL.png -> good
firefox-canvas.toDataURL.png -> error

Summary for Chrome loading:
original.jpg -> good
original-resaved-PS.jpg -> good
chrome-canvas.toDataURL.png -> good
firefox-canvas.toDataURL.png -> error

The files used for testing, and the canvas.toDataURL can be downloaded here:

Comment 12

a year ago
The bug is encountered with images, which have embedded ICC.
toDataURL('image/png') creates png-file with ICC, which is contrary to W3 specifications.

note: the embedded ICC was not visible on inspection, which also may be indicative of poorly structured PNG (which was still interpreted by some software like Photoshop). 

When a problem PNG file are re-saved without ICC, and reloaded, the problem disappears.
When the same PNG is re-saved with embedded ICC, and reloaded, the problem persists.

To reproduce, the problem you can use the image files from the links above.


a year ago
Last Resolved: a year ago
Resolution: --- → INVALID
You need to log in before you can comment on or make changes to this bug.