Chromium based browsers are displaying varying values when using canvas.getimagedata()

Update: The solution is to enable willReadFrequently: true on the canvas in Chromium so that getImageData() will consistently return values. Please refer to the answer below for more details.

Currently, I am working on a program that selects a pixel from a canvas where an image has been loaded using canvas.getImageData(), analyzes the RGB values of the pixel, and performs calculations based on the blue and red values.

I have noticed an unusual behavior only in Chrome, Chromium, and Edge browsers: when an image is loaded for the first time, the value returned for a specific pixel is RGB(181,1,1). However, if I reload the exact same image onto the canvas using canvas.drawImage() and select the same pixel multiple times using canvas.getImageData(), I now get RGB(181,1,2).

HTML:

<canvas id="canvas" width="500" height="500"></canvas>

JavaScript:

var ctx = document.getElementById("canvas").getContext("2d", {alpha: false,});
    
const IMG = new Image();
IMG.src = "myImage.jpg"

ctx.drawImage(IMG, 0, 0, 500, 500);
console.log("First image draw: " + ctx.getImageData(66, 27, 1, 1).data);

ctx.drawImage(IMG, 0, 0, 500, 500);
console.log("Second image draw: " + ctx.getImageData(66, 27, 1, 1).data);

ctx.drawImage(IMG, 0, 0, 500, 500);
console.log("Third image draw: " + ctx.getImageData(66, 27, 1, 1).data);

ctx.drawImage(IMG, 0, 0, 500, 500);
console.log("Fourth image draw: " + ctx.getImageData(66, 27, 1, 1).data);

ctx.drawImage(IMG, 0, 0, 500, 500);
console.log("Fifth image draw: " + ctx.getImageData(66, 27, 1, 1).data);

Results in Chrome:

"First image draw: 181,1,1,255"
"Second image draw: 181,1,1,255"
"Third image draw: 181,1,2,255"
"Fourth image draw: 181,1,2,255"
"Fifth image draw: 181,1,2,255"

Results in Firefox:

"First image draw: 181,1,2,255"
"Second image draw: 181,1,2,255"
"Third image draw: 181,1,2,255"
"Fourth image draw: 181,1,2,255"
"Fifth image draw: 181,1,2,255"

This behavior only occurs in Chromium-based browsers; in Webkit and Firefox, I consistently get RGB(181,1,2) regardless.

I have replicated this behavior on CodePen: open it in Chrome and Firefox to observe the difference: https://codepen.io/sh4kman/pen/qBgaNbe

Screenshot comparison

What I have tried:

  1. Disabling antialiasing (context.imageSmoothingEnabled = false)
  2. Clearing the canvas (canvas.clearRect()) before/after every getImageData() call

I understand that different browsers can render/round colors differently for images, but in this case, I am seeing different values on the same browser, consistently following the same pattern.

Answer №1

While I can't provide a definitive answer, after playing around with the willReadFrequently attribute of the canvas as indicated in the console warning, I noticed varying results on Chromium.

When the willReadFrequently attribute is set to true, multiple readback operations using getImageData in Canvas2D are faster. More information can be found at: https://html.spec.whatwg.org/multipage/canvas.html#concept-canvas-will-read-frequently

After forking the CodePen link, I experimented with changing the values to undefined (default), false, and true. Each setting resulted in different behaviors.

undefined

The default behavior can be seen https://i.sstatic.net/CBJU4.png

false

A consistent behavior where the 3rd value is 1 https://i.sstatic.net/0UYPQ.png

true

A consistent behavior where the 3rd value is 2 https://i.sstatic.net/cyobv.png

Link to the Codepen example: https://codepen.io/Danny2006/pen/vYbXJWR

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

A guide on exposing TypeScript classes globally through a WebPack bundle in JavaScript

Currently delving into TypeScript, my aim is to gradually replace JS with TS. However, due to having numerous JS files, my strategy involves creating new classes in TS and incorporating them into my existing JS files for the time being. Eventually, I plan ...

Once the user clicks on the download button, the backend should initiate the download process

I am seeking a solution where a download can be triggered in the background when a download button is clicked, without interrupting other tasks. Is there a way to achieve this in PHP? If so, what method can be used? I have attempted using the curl function ...

Ways to display URL parameters on an HTML page without using PHP

I'm currently working on a website using HTML (without PHP) and I'm facing an issue with displaying URL parameters on an appointment confirmation page. The appointment details are being successfully passed through the URL parameters, but I'm ...

Uh oh! You haven't set a QueryClient yet. Make sure to use QueryClientProvider to set

My first experience with React Query didn't go as planned when I encountered this error at the beginning of my React app: Even though I added QueryClientProvider to the top of my component tree, I kept getting: Error: No QueryClient set, use QueryCli ...

Executing Python and JavaScript with Selenium

I am encountering an issue while trying to run this code. The error message indicates that I may be missing a closing ) or using an illegal character. It seems like there might be confusion with inserting arguments where they are not needed. Could someon ...

Using Jquery ajax, I am interested in storing a single value into a variable for future use in JavaScript

I'm finally able to retrieve a JSON Get request, but I'm struggling with utilizing the information effectively. The array contains 9 items, but I only need one specific value - the id. I want to extract this id and save it in a variable for futur ...

What is the most effective way to compare two arrays of objects in JavaScript?

I'm working on a function that needs to return an array of elements based on certain filters. Here is the code for the function: filter_getCustomFilterItems(filterNameToSearch: string, appliedFilters: Array<any>) { let tempFilterArray = []; ...

I'm encountering an issue with VUEJS components including my show route in their get call. How can I make my journals/:id pages function properly without encountering a Mime

I encountered a MIME type error stating: Refused to apply style from 'http://localhost:8080/journals/assets/css/main.css' because its MIME type ('text/html') is not a supported stylesheet MIME type, and strict MIME checking is enabled. ...

Retrieve and showcase PHP results utilizing the power of jQuery/AJAX

I am working with a Leaflet map and a text input field. My goal is to extract the address from the text input, process it using a PHP script, and receive the results back via jQuery. Below is the form structure: <form id="mapcheck" method="POS ...

Using the React JS useState hook to toggle the state of a JSON object containing an array when a checkbox is clicked

When I submit my state as a stringified variable from a form to a POST request via a lamda server, it gets parsed and sent to sendgrid for templating. To loop over specific parts (multiple checkboxes) in JSON format, each with the same key but different va ...

Blazor Server: Seamless breadcrumb navigation updates with JavaScript on all pages

I have implemented a breadcrumb feature in my Blazor Server project within the AppLayout that functions for all pages: <ul id="breadcrumbs" class="breadcrumbs"> <li><a href="#">Home</a></li> ...

Create a JavaScript alert script devoid of any instances of double quotation marks

This snippet belongs to my webpage: <span onclick=alert('Name:$commenter_name <br>Email:$commenter_email <br> Rate:$commenter_rate <br>Comment time:$currentdate <br>Comment:$commenter_comment')>$commenter_name:$comm ...

Utilizing Next.js routing to accommodate two distinct subdomains on a single website

I am looking to develop a new platform using Next.js (React.js and React-router). The platform will have two distinct spaces - one for users and another for the owner to manage all users. To achieve this, I plan on splitting both areas into two subdomains: ...

How can I represent non-ASCII characters in Java Script using encoding?

Imagine if ch = á the desired result is = \u00e1 however the current output = %E1 when escape(ch) is used and current output = %C3%A1 when encodeURIComponent(ch) is used I am working with an API that supports Unicode characters. ...

Is it possible to authenticate a user in Firebase using Node.js without utilizing the client side?

Can I access Firebase client functions like signInWithEmailAndPassword in the Firebase SDK on the server side? Although SDKs are typically used for servers and clients use JavaScript, I need a non-JavaScript solution on the client side. I have set up the ...

What is the impact of util.inherits on the prototype chain in JavaScript?

Exploring this particular design: Function ConstrA () { EventEmitter.call(this); } util.inherits(ConstrA, EventEmitter); var obj = new ConstrA(); If util.inherits is omitted, ConstrA and obj will each establish their own distinct prototype chain. T ...

Unexpected outcomes when trying to sort and paginate React-Table

Experiencing unexpected results with react-table integration for pagination and sorting. Merged examples from the react-table repository. Encountering an issue where table hooks reset the page index on re-render, causing fetchData to be called twice during ...

Problem with Ionic 2 local storage: struggling to store retrieved value in a variable

Struggling to assign the retrieved value from a .get function to a variable declared outside of it. var dt; //fetching data this.local.get('didTutorial').then((value) => { alert(value); dt = value; }) console.log("Local Storage value: " ...

Issues with Adding Dynamic Rows to MySQL

Struggling with adding dynamic rows and posting to MySQL. The variables seem off, but the script works fine. Need help with MYSQL posting specifically. As a beginner, I seek your forgiveness... The Script is running smoothly! <script type='text/ ...

The SyntaxError is triggered by the React-Native FlatList component

As a newcomer to React Native, I am facing an issue with refreshing the component to load city names stored in async storage. The error occurs when I utilize the FlatList component for the first time. The specific error message I encountered is: SyntaxE ...