Problems with imagedata

I’ve been having problems plotting points using getImageData and setImageData. Specifically, it sometimes works, but for no apparent reason, sometimes it doesn’t. For example, consider the following code :

createCanvas(“1”, 320, 450);
setFillColor(“black”);
rect(0, 0, 320, 450);

setStrokeColor(rgb(xcurrent * reddelta, greendelta * i, (450 - ycurrent) * bluedelta));
//Plot a point
line(xcurrent, ycurrent, xcurrent, ycurrent);

The above works. But, If I replace the above with the equivalent imageData code :

createCanvas(“1”, 320, 450);
setFillColor(“black”);
rect(0, 0, 320, 450);
var Sieveimage = getImageData(0, 0, 320, 450);

setRGB(Sieveimage, xcurrent, ycurrent, xcurrent * reddelta, greendelta * i, (450 - ycurrent) * bluedelta, 255);

putImageData(Sieveimage, 0, 0);

The above does not work – nothing ever gets displayed on the screen.

I’ve written code that works fine with imageData but for some reason it’s not working now.

Might anyone know what the problem is? Any help would be greatly appreciated.

Thanks,

jdb2

I don’t have an answer but it’s always better if you share a link to the code so people can see and play with it a bit. If you believe it’s a bug in the system then I recommend sending an email to support@code.org

Sorry… Here’s the code : https://studio.code.org/projects/applab/F0XSqg8Um7SqCRl75RxeeJFTmaXjXzv_Bfhi5jTdOzI

Thanks,

jdb2

All the code I’ve created that uses imageData now no longer works, except this :

https://studio.code.org/projects/applab/-JNF0YyucRzNuIvdgnHc-JgphVE47L9vzkxxIyswQ54

jdb2

Well, it appears that the values supplied to setRGB or setRed, setGreen, setBlue or setAlpha have to be integers. Using Math.round() solves the problem.

Regards,

Jonathan

This seems to be a bug in Code.org as the description of the above kludge isn’t mentioned in the Code.org documentation of the above functions : The documentation just mentions that the variables have type “number”, which they did have, when the code wasn’t working.

Jonathan

Actually, the above “fix” breaks the functionality of the code and I get an incorrect plot where x values that are less then zero or greater than 320 somehow get plotted anyway.

Don’t know what to quite do about it…

Jonathan

Well, a bounds check before rounding solves the problem, but it’s still a huge kludge and it appears to be a bug in Code.org .

jdb2

Hi @jdb2 - this looks like quite the app! It seems like you determined it was a bug, so I would recommend contacting support@code.org - they can confirm that for you and add it to their “to-do list”

@kaitie_o_bryan Thanks! :grinning: I’m teaching my nephew how to program using fractal plotting algorithms as examples. :grinning: I did contact Code dot org support via e-mail but they said I should post to the forums, and to which I responded that I already had :neutral_face: The link to the working version of the code is here : https://studio.code.org/projects/applab/veHFot7XHW2oJofYloVOzxJZ3IpzpALIrBm3gdxJaFI . The other app that uses imageData is here : https://studio.code.org/projects/applab/mL3VZrVjLHuAa1KYQOw8basjjluZ5gxUe3uNLTBo26I

I remember coding these fractal plotting algorithms on my HP48GX when I was 10 or 11 years old in Junior high :grinning: Since my nephew is almost 12, I thought that fractals would be a suitable example :grinning:

Regards,

jdb2

@ kaitie_o_bryan Well, the actual program code on Code dot org is just Javascript. Almost all of the functions that take pixel values as arguments work even if the pixel values are floating point numbers. Now we enter the imageData functions, which, like most of the functions / methods on Code dot org, are just Javascript wrapper functions. The problem here is that the wrapper functions fail if, for the imageData case, if the pixel inputs are not integers, which is inconsistent with all the other functions on Code dot org which take pixel inputs. This is just bad software design and an example of non-graceful failure – you’d expect the wrapper functions to just transparently round their arguments but issue a warning to the console. Also, the imageData wrapper functions seem to “wrap” their pixel inputs, modulo the canvas width and height of any pixel input that exceeds said width and height, which is another bug.

Regards,

Jonathan

Another possible bug that I discovered relates to the behavior of the drawImageURL() function. Specifically, even without a clearCanvas() function call, and even if the target image has a white, completely opaque background, there is horrible flicker when the drawImageURL() function is called in quick succession. Mozilla Firefox and Google Chrome, in Linux and on Windows, both exhibit this behavior, but, strangely, Microsoft’s Windows 10 Edge browser shows no flickering.

Regards,

jdb2

I’ve been working on some infinite zooming Mandelbrot set plotting code for my nephew and I’ve run into more problems with imageData. Specifically, clearCanvas() doesn’t appear to work. I have to manually set each pixel in the canvas to white or else the drawImageURL() background image isn’t erased. Curiously, even though clearCanvas() seems to do nothing, leaving it out and doing the manual white clear using the imageData functions results in nothing being erased on the screen.

Here is the code :

https://studio.code.org/projects/applab/cEyijaeeYso9vvWitqqgDVhr4ujq8JfOkYL7VmALrJ8

Does anyone have an idea of what the problem might be?

Thanks,

jdb2

I have been working on an “infinite zooming” Mandelbrot set plotter for my nephew, but, I’ve been having problems with the drawImageURL() function. Specifically, after I draw a background image with said function, and then, when I try to draw something on top of the background, what I try to draw never shows up. Here is the code :

createCanvas("1", 320, 450);
var image1;
var image2;
image1 = getImageData(0, 0, 320, 450);
image2 = image1;
//drawImageURL("https://i209.photobucket.com/albums/bb286/wqo2/Code%20dot%20org/mandelbrot_zpshdyinvkd.png");
//setStrokeColor("white");
//setFillColor("white");
setStrokeColor("black");
setFillColor("black");
rect(0, 0, 160, 225);
//createCanvas("2", 320, 450);
//putImageData(image2, 0, 0);

You can also find the code here :

https://studio.code.org/projects/applab/GAFJieOESJ02H2H5b8MOEmq_ftQWMiQpOXO1_BnglSY

Without the above code working, I can’t save the imageData for the current canvas and let the user select another region into which to zoom in the current plot.

Does anyone know what the problem might be?

Thanks and regards,

jdb2

I was able to get the image below - is this what you are looking to create?

That is what my code created initially, before I added zooming :slight_smile: Now that I have infinite zoom capability, I initially load that image from my Photobucket acount using drawImageURL(). The problem is that the only way to clear the screen after using drawImageURL() is to manually use setRGB() to set each pixel to white.

Regards,

jdb2

I’ve been working on an infinite zoom Mandelbrot set plotter for my nephew. Even though I have a highly optimized inner loop, with only three multiplications, the code on Code dot org is extremely slow. In fact, it’s slower than it is on my 24+ year old 3.68MHz HP48GX calculator!

I’m thinking that the problem lies with Code dot org’s “interpreter within an interpreter” with regard to some of the Javascript wrapper functions. The inner loop is :

while ((rsquare + isquare) <= 4 && (temp >= 1)) {
      temp = temp - 1;
      rsquare = r*r;
      isquare = i*i;
      zrsquare = (r + i)*(r + i);
      r1 = rsquare - isquare + y;
      i = zrsquare - rsquare - isquare + x;
      r = r1;
}

Here is a link to the code :

https://studio.code.org/projects/applab/cEyijaeeYso9vvWitqqgDVhr4ujq8JfOkYL7VmALrJ8

Could anyone shed some light on why this code is so slow?

Thanks,

jdb2

Hi @jdb2 - That’s quite a project you are working on! Most of what you are doing here is outside of the scope of what App Lab is designed to do well, which is to help students learn to program while creating mobile apps. Most likely this explains the slow-down issues you are experiencing.

Have you or your nephew worked through any of the curricula? For his age, I would recommend checking out Game Lab, in particular Unit 3 of Computer Science Discoveries.

Best wishes!
~ Hannah

@hannah Thanks for the reply :slight_smile: I’ve had to migrate some of my code which uses Code dot org’s sandboxed Javascript to Javascript proper, using the Canvas API. I implemented the setRGB() function as follows :

function setRGB(image, width1, x1, y1, r, g, b, a) {
  var t1 = y1*width1*4 + x1*4;
  image.data[t1] = r;
  image.data[t1 + 1] = g;
  image.data[t1 + 2] = b;
  image.data[t1 + 3] = a;
 }

The above setRGB function is about at least 1000x faster than the Code dot org version. In a modified version of the backend function on Code dot org’s App Lab, the “width1” parameter would need to be global, and, as such, wouldn’t need to be included in the setRGB() function as a parameter.

Perhaps you can pass along my advice to the dev team?

Thanks,

jdb2

Here’s a setRGB() function with graceful failure that automatically uses the active canvas dimensions :

var canvas = document.getElementById('activeCanvas');
var ctx = canvas.getContext('2d');
var width = canvas.width;
var height = canvas.height;
var canvasImage = ctx.getImageData(0, 0, width-1, height-1);

...

function setRGB(imageData, x1, y1, r, g, b, a) {
  var t2 = (x1 - Math.floor(x1)) + (y1 - Math.floor(y1)) + (r - Math.floor(r)) +(g - Math.floor(g)) + (b - Math.floor(b)) + (a - Math.floor(a));
  var x1;
  var y2;
  var r2;
  var g2;
  var b2;
  var a2;
  if ( t2 != 0 ) {
    console.log("Warning : Non-integer parameter detected -- rounding");
    x2 = Math.round(x1);
    y2 = Math.round(y1);
    r2 = Math.round(r);
    g2 = Math.round(g);
    b2 = Math.round(b);
    a2 = Math.round(a);
  }
  else {
    x2 = x1;
    y2 = y1;
    r2 = r;
    g2 = g;
    b2 = b;
    a2 = a;
  }
  var t1 = y2*(width - 1)*4 + x2 * 4;
  imageData.data[t1] = r2;
  imageData.data[t1 + 1] = g2;
  imageData.data[t1 + 2] = b2;
  imageData.data[t1 + 3] = a2;
 }

jdb2