Skip to content

"pixels" array cannot be reassigned #4993

@limzykenneth

Description

@limzykenneth
Member

Most appropriate sub-area of p5.js?

  • Accessibility (Web Accessibility)
    Build tools and processes
    Color
    Core/Environment/Rendering
    Data
    DOM
    Events
    Friendly error system
    Image
    IO (Input/Output)
    Localization
    Math
    Unit Testing
    Typography
    Utilities
    WebGL
    Other (specify if possible)

Details about the bug:

  • p5.js version: 1.2.0
  • Web browser and version: Firefox 84.0.2 (should apply to all supported browsers)
  • Operating System: Linux Pop_OS 20.10
  • Steps to reproduce this:

Visit this example sketch. The initial expected behaviour is a blank canvas because the img.pixels array has been assigned with the .map function to be all 0 but the image is still drawn. Replacing the .map with a for loop works as expected.

Filing this as a bug because this behaviour is different from the canvas itself (see by uncommenting code at the end of the draw() function), which reassigning the pixels array with .map still works.

The problem seems to be outdated variable referencing in p5.Image, possibly affecting p5.Graphics as well but I didn't test.

Activity

limzykenneth

limzykenneth commented on Jan 13, 2021

@limzykenneth
MemberAuthor

Actually it seems to affect the canvas's pixels array as well.

rt1301

rt1301 commented on Jan 14, 2021

@rt1301
Contributor

@limzykenneth I would like to work on this. Can you suggest me how to get started with it?

limzykenneth

limzykenneth commented on Jan 14, 2021

@limzykenneth
MemberAuthor

This one is potentially a bit complicated and it still need to be determined as an actual bug first, ie. the behaviour is something that should be fixed and not something that's intended. To fix this will require looking at how updatePixels() is getting the pixels array to update in the relevant canvas image data array.

changed the title [-]"pixels" array of p5.Image cannot be reassigned while canvas one can[/-] [+]"pixels" array of p5.Image cannot be reassigned[/+] on Jan 14, 2021
changed the title [-]"pixels" array of p5.Image cannot be reassigned[/-] [+]"pixels" array cannot be reassigned[/+] on Jan 14, 2021
stalgiag

stalgiag commented on Jan 19, 2021

@stalgiag
Contributor

When I test on Mac OS 10.15.7 with Firefox 84.0.2 the image is transparent with the .map modification of its pixels. For example in this slight modification of your example, I only see blue. Am I missing something?

limzykenneth

limzykenneth commented on Jan 20, 2021

@limzykenneth
MemberAuthor

@stalgiag If I change the second to last line in your modified sketch and instead of mapping all values to 0, map all to 255, I still only see blue where I'm expecting a white square on blue background.

stalgiag

stalgiag commented on Jan 20, 2021

@stalgiag
Contributor

Definitely should be a white square and yes it seems to happen on both the canvas and the image when using map.

limzykenneth

limzykenneth commented on Jan 20, 2021

@limzykenneth
MemberAuthor

My theory is that pixels is setup to be a reference to the underlying image data array and by reassigning it the reference is replaced and updatePixels() is still looking at the underlying image data instead of the pixels variable. I haven't look much into the code base so can't say much about what the fix could be though.

ahujadivyam

ahujadivyam commented on Jan 30, 2021

@ahujadivyam
Contributor

@limzykenneth Yes, this seems to be the case.
pixels is just reference to imageData data and reassigning it will just reassign the reference not change the actual data.

pixelsState._setProperty('pixels', imageData.data);

this.drawingContext.putImageData(pixelsState.imageData, x, y, 0, 0, w, h);

amanMahendroo

amanMahendroo commented on Feb 23, 2021

@amanMahendroo

Hi. This does not seem to be a bug in the code. The reason that the pixel update doesn't work is that the img.pixels array is a UInt8ClampedArray and not a regular javascript array. Hence it doesn't have the Array.prototype.map() function associated with it. You can update the image's pixels by using a for-loop or by using the set() function in the p5.js library.
The blue screen that appears on using the for loop seems to be a bug in the p5.js web editor as this doesn't seem to happen in other editors or in the browser.
Hope this helped 😊

limzykenneth

limzykenneth commented on Feb 23, 2021

@limzykenneth
MemberAuthor

UInt8ClampedArray does have a map method but that is not the key for this issue. Even not using map() (which is my original use case but it's too complicated to share), I can create a new Uint8ClampedArray say called newPixels, if I assign pixels = newPixels, updatePixels() will not populate the canvas with the values I set in newPixels.

ahujadivyam

ahujadivyam commented on Feb 23, 2021

@ahujadivyam
Contributor

UInt8ClampedArray does have a map method but that is not the key for this issue. Even not using map() (which is my original use case but it's too complicated to share), I can create a new Uint8ClampedArray say called newPixels, if I assign pixels = newPixels, updatePixels() will not populate the canvas with the values I set in newPixels.

@limzykenneth As I mentioned in above comment #4993 (comment) , I think pixels (property / variable ) is just a reference to image data array which renderer is using internally and updating using that, and reassigning pixels array with map() or something else just makes pixels reference to other array and internal image data array is not getting affected

limzykenneth

limzykenneth commented on Feb 23, 2021

@limzykenneth
MemberAuthor

@divyamahuja Yes, that's what I was saying.

19 remaining items

Loading
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

    Participants

    @limzykenneth@stalgiag@Qianqianye@amanMahendroo@ahujadivyam

    Issue actions

      "pixels" array cannot be reassigned · Issue #4993 · processing/p5.js