Closed Bug 1365549 Opened 7 years ago Closed 7 years ago

Javascript/ toDataURL PNG color inconsistency

Categories

(Core :: Graphics: Canvas2D, defect, P3)

53 Branch
defect

Tracking

()

RESOLVED INVALID

People

(Reporter: colormatch, Unassigned, NeedInfo)

Details

(Whiteboard: [gfx-noted])

Attachments

(3 files)

Attached image Firefox-problem-PNG.jpg
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)
Do you have a small testacse to repro the issue, please.
Flags: needinfo?(colormatch)
Component: Untriaged → Canvas: 2D
Product: Firefox → Core
(In reply to Loic from comment #1)
> Do you have a small testacse to repro the issue, please.

This web-app: https://kinoseed.com/ 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)
I still don't understand to reproduce the issue on https://kinoseed.com/

Could you give excat steps to reproduce the issue, please. Should I upload jpeg or png image?
Flags: needinfo?(colormatch)
(In reply to Loic from comment #3)
> I still don't understand to reproduce the issue on https://kinoseed.com/
> 
> 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:
https://developer.mozilla.org/en-US/docs/Web/API/HTMLCanvasElement/toDataURL


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:
https://developer.mozilla.org/en-US/Firefox/Releases/3.5/ICC_color_correction_in_Firefox

[2] More on the color-space of Portable Network Graphics (PNG) Specification:
https://www.w3.org/TR/PNG/#4Concepts.ColourSpaces

If you need information on what toDataURL does, or how to use it, it can be found here:
https://developer.mozilla.org/en-US/docs/Web/API/HTMLCanvasElement/toDataURL
Flags: needinfo?(colormatch)
comparison results
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] 
Firefox-problem-dataToURL.jpg
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]
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:

gfx.color_management.enablev4;false
gfx.color_management.mode;2
gfx.color_management.rendering_intent;0
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."
https://www.w3.org/TR/2011/WD-html5-20110405/the-canvas-element.html#color-spaces-and-color-correction



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.

cheers
(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: http://keyassets.timeincuk.net/inspirewp/live/wp-content/uploads/sites/13/2015/07/Leica-Q-sample-image-3.jpg
click on the "target image" box and load "Leica-Q-sample-image-3.jpg"

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:
https://kinoseed.com/Firefox-errors.jpg


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:
https://kinoseed.com/Firefox-bugs.zip
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.
Status: UNCONFIRMED → RESOLVED
Closed: 7 years ago
Resolution: --- → INVALID
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Creator:
Created:
Updated:
Size: