Re: Help, please: Having trouble with canvas

Discussion in 'HTML' started by Ben Bacarisse, Oct 5, 2013.

  1. Ed Jay <> writes:

    > I've created a canvas and drawn an image to it. I have three routines. Two
    > are called up in one function, the other is called by a 2nd function. Each
    > routine does something to canvas pixels. Basic structure is:
    >
    > //Draw image to canvas
    > //Create command and establish 'what'
    > //Call function process_image(what)
    >
    > function process_image(what) {
    >
    > if (what == xx) {
    > process2(what);
    > return; //returns to waiting for new 'what' command
    > }
    > else {
    > process1(what);
    > process2(what);
    > }
    > }
    >
    > function process1(what) {
    >
    > start 2 x forloop to loop through canvas
    >
    > //routine1
    > if (what == 'sti') {
    > grab a pixel from canvas
    > modify pixel
    > put modified pixel back to canvas
    > }
    > //routine2
    > if (what == 'seg') {
    > grab the pixel from canvas
    > modify the pixel
    > put modified pixel back to canvas
    > }
    > end 2x forloop
    > }
    >
    > function process2(what) {
    > start 2 x forloop
    > if (what == 'res') {
    > grab a pixel from canvas
    > modify the pixel
    > put modified pixel back to canvas
    > end loop
    > }
    >
    > I run process1(), all works fine.
    >
    > If I run function process2() after process1, the routine works, but the
    > information that was on the canvas from previously running process1 no
    > longer is visible. I am not erasing or modifying the data on canvas, so it
    > should still be on canvas. I have verified the data is on canvas...I can
    > see it, but when I return to waiting for a command, the process1 data is
    > gone.
    >
    > WTH am I doing or thinking wrong?


    The problem may well be nothing to do with the outline -- it might be a
    detail. You are more likely to get help if you show real code that
    people can run (as cut-down as you can), or post a link to where we can
    see the real code.

    --
    Ben.
    Ben Bacarisse, Oct 5, 2013
    #1
    1. Advertising

  2. Ed Jay <> writes:
    <snip>
    > The real code is enormous and much of it proprietary, so I can't show or
    > link to it.


    Ah, you are probably out of luck here then. Debugging hidden code is
    next to impossible.

    > I've gone over the code with a fine-tooth comb and don't see any issues.
    > Additionally, all the routines have been tested...and all work
    > properly.


    Unfortunately the style of the code links all of the functions together
    to an extreme degree. They seem to reply almost entirely on global (or
    at least shared) variables to operate. This greatly increases the
    chance that one function can interfere with another. This is probably
    what's, happening since you say the functions work on their own.

    Also, I can't help but point out that the code is organised around the
    idea that lots of variables affect when the functions do. This is
    generally regarded as a Bad Idea and is very hard to scale (you do say
    that the code is enormous). You may not feel like re-writing it, but
    sometimes that is the only way.

    > At any rate, here's some abbreviated code:
    >
    > final_image =document.getElementById('final_canvas').getContext('2d');
    >
    > if (what == 'bri' || what == 'con' || what == 'neg' || what == 'clr' ) {
    > process2(what);
    > output_result();
    > return;
    > }
    > else {
    > process1(what);
    > process2(what);
    > output_result();
    > }
    > *****
    > function process1(what) {
    > if (sti == 'true') {
    >
    > for (var x = 0; x < width; x++) {
    > for (var y = 0; y < height; y++) {
    >
    > pixel_up = final_image.getImageData(x,y-depth,1,1).data[0];
    > etc...for 8 neighboring pixels
    > do something proprietary to pixel et al
    > final_image.putImageData(read_pixel, x, y);
    > }
    > if (segmentation == 'true'){
    > var pixel_gray = final_image.getImageData(x, y, 1, 1);
    > do something proprietary to pixel et al
    > final_image.putImageData(read_pixel, x, y);
    > }
    > }} //end loop
    > }
    > ****
    > function process2(what) {
    > for (var x = 0; x < width; x++) {
    > for (y = 0; y < height; y++) {
    > read_pixel2 = final_image.getImageData(x, y, 1, 1);
    >
    > img_brightness(what);
    > img_contrast(what);
    > img_color(what);
    > img_negate(what);
    >
    > read_pixel_data2[0] = red_data2;
    > read_pixel_data2[1] = green_data2;
    > read_pixel_data2[2] = blue_data2;
    > final_image.putImageData(read_pixel2, x, y);
    >
    > }} //end loop1
    > }
    > //sample subroutine for process2
    >
    > function img_negate(what) {
    > if (negate == 'true') {//alert("negate");
    > red_data2 = 255 - red_data2;
    > green_data2 = 255 - green_data2;
    > blue_data2 = 255 - blue_data2;
    > }
    > }


    Showing this just makes things worse for me. It has so many missing
    parts that all I can see is potential problems. There is a key function
    -- output_result() -- not shown, and all the fragments do nothing as
    they are written. If I assume that the hidden code gives the key global
    objects the right values in time, I am, in effect, assuming that there
    is no problem but you tell me that there is! Even 'y' one of the loop
    controls is global in one of the functions. It could be being changed
    by any of the unseen code at any time.

    > As I see it, in process1 I grab each pixel, modify each, and place the
    > result back to the final_image (canvas). Depending on which switches are
    > set, I can do this 0, 1 or 2 times. When running process2, I'm simply
    > looping through 'final_image,' grabbing and changing its pixels, and again
    > returning the result to final_image.


    I have to take your word for this which is a terrible way to debug a
    program. You need to find someone who is allowed to look at the code,
    and will do so with a sceptical eye. Someone who will *not* have to
    take your word for the code does.

    --
    Ben.
    Ben Bacarisse, Oct 5, 2013
    #2
    1. Advertising

  3. Ed Jay <> writes:
    <snip>
    > function process2(what) {
    > for (var x = 0; x < width; x++) {
    > for (y = 0; y < height; y++) {


    This 'y' is not local to the function. Even though I mentioned it in
    passing, this is so weird that I thought I'd flag it up specifically.
    Fix this before anything else -- you never know, some other function
    might be doing the same and hence messing up this loop!

    <snip>
    --
    Ben.
    Ben Bacarisse, Oct 5, 2013
    #3
  4. Ben Bacarisse

    Ben C Guest

    On 2013-10-05, Ed Jay <> wrote:
    [...]
    > As I see it, in process1 I grab each pixel, modify each, and place the
    > result back to the final_image (canvas). Depending on which switches are
    > set, I can do this 0, 1 or 2 times. When running process2, I'm simply
    > looping through 'final_image,' grabbing and changing its pixels, and again
    > returning the result to final_image.


    My guess would be that the data you put with putImage hasn't been
    flushed out yet. If you try just writing and reading back immediately
    afterwards (in the same function), and that doesn't work, that would
    confirm this.

    http://www.whatwg.org/specs/web-app...nvas-element.html#dom-context-2d-putimagedata

    Speaks of a "scratch bitmap", which has a "commit" method. You could try
    calling that.

    It sounds to me from that documentation that you should be writing and
    reading the scratch bitmap, so it ought to work without a commit (that
    should update the "output bitmap" from the scratch bitmap). But a commit
    would certainly flush out all drawing.

    But I haven't read it very thorougly.

    It's quite common in general in graphics for drawing operations not to
    happen at once because often they go faster if they can be buffered up
    together, and there's plenty of scope for bugs in this area. How many
    browsers have you tried?
    Ben C, Oct 6, 2013
    #4
  5. Ben Bacarisse

    Ben C Guest

    On 2013-10-06, Ed Jay <> wrote:
    > Ben C wrote:

    [...]
    >>My guess would be that the data you put with putImage hasn't been
    >>flushed out yet. If you try just writing and reading back immediately
    >>afterwards (in the same function), and that doesn't work, that would
    >>confirm this.

    [...]
    > Apparently, you nailed it. A racing issue.


    So when you say racing do you mean just timing? i.e. the writes happen,
    but not in time for the reads?

    You could prove that (well, almost prove it) by doing the read in a
    setTimeout.

    > I tested by writing to a temp canvas, then writing the temp canvas
    > back to the 'final_canvas,' and the problem ceased.


    There are other operations there that might cause the drawing to be
    flushed out.

    > As I'm striving to maximize image processing speed, I'll play with
    > this solution and do it all with a single write. Thanks!!!
    >
    > I'll do the above after I finish following Ben B's observations re local
    > variables. ;-)


    Yeah JavaScript has a few traps with those to watch out for.
    Ben C, Oct 7, 2013
    #5
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. KK
    Replies:
    2
    Views:
    556
    Big Brian
    Oct 14, 2003
  2. Askari
    Replies:
    2
    Views:
    709
    Askari
    Aug 30, 2004
  3. PhilC
    Replies:
    2
    Views:
    885
    PhilC
    Oct 25, 2004
  4. Ben
    Replies:
    17
    Views:
    229
  5. Replies:
    10
    Views:
    261
    Rick Johnson
    Mar 15, 2013
Loading...

Share This Page