P5js How to load an image and subsequently alter it?

I am having issues loading an image from my sprites folder, which is in the same directory as my index.html.

    function draw() {
        background(255);
        image(loadImage("sprites/running0.png"), 0, 0);
    }

I'm receiving this error:

p5.js says: It looks like there was a problem loading your image. Try checking if the file path [file:///C:/Users/Pradeep/Documents/.../.../src/sprites/running0.png] is correct, hosting the image online, or running a local server.[https://github.com/processing/p5.js/wiki/Local-server] >

The source is correct so I have no idea what to do next since I think I'm correctly pointing it the file? Do I really have to run a private local server to circumnavigate security blocks? What are these security blocks that disable me from loading images if any?

Finally, once an image is loaded, is it possible to alter its pixel values, such as draw vertical and horizontal white lines across its entire image-width/image-length using simple for loops? I'm trying to do the same with a Python script (dependencies = matplotlib, scipy, numpy) but matplotlib saving figures is extremely awkward if you're just "editing images" rather than plotting mathematical stuff. If anyone knows any form of coding image pixel manipulation that is simpler please let me know! No I will not draw over my image using Paint. ;)

Ultimately I would like to load images such that my sprite (8 images) seems to run over draw:

    var i = 0;
    function draw() {
        background(255);
        image(loadImage("sprites/running" + i + ".png"), 0, 0);
        i++;
        if (i == 8) {
            i = 0;
        }
    }

Answers

  • edited October 2017

    I've made the following changes according to those links!

    "use strict";
    
    const SPRITES = 'sprites/';
    let running0, running1, running2, running3, running4, running5, running6, running7;
    
    function preload() {
        running0 = loadImage(SPRITES + "running0.png");
        running1 = loadImage(SPRITES + "running1.png");
        running2 = loadImage(SPRITES + "running2.png");
        running3 = loadImage(SPRITES + "running3.png");
        running4 = loadImage(SPRITES + "running4.png");
        running5 = loadImage(SPRITES + "running5.png");
        running6 = loadImage(SPRITES + "running6.png");
        running7 = loadImage(SPRITES + "running7.png");
    }
    
    function draw() {
        background(255);
        image(running0, 0, 0);
    }
    

    However, the same issue occurs. I also tried running0.loadPixels() in setup(), but that seems to do nothing as well.

  • Answer ✓

    @codedanddied - you don't mention how you're running the sketch; though it doesn't sound like you're using a local server. Try using Firefox: if it works there then the problem is definitely a security restriction in the browser you're using. In that case I'd personally recommend persevering with a local server; or using an editor that provides one - like Brackets...

    In answer to the other part of your question: yes you can alter the image in p5.js; but you're likely to have the same testing issues whatever library you use so solve that first ;)

  • edited October 2017

    @blindfish - I am running the sketch as a script connected to an index.html displayed in browser, namely Chrome.

    You were right! I could run the above code on Firefox and running0.png will show!

    Now, if I would like to draw a different sprite frame every call to draw() to make it seem like it's moving, I can do something like:

    var running = [running0, running1, running2, running3, running4, running5, running6, running7]
    
    function draw() {
        background(255);
        image(running[i], 0, 0); // Line 37
        i++
        if (i == 8) {
            i = 0;
        }
    }
    

    This, however, does not work, and spits out this error:

    TypeError: img is undefined [76]</p5.prototype.image file:///C:/Users/.../src/libraries/p5.js:54538:7 self-hosted:947:17 draw file:///C:/Users/.../src/sketch.js:37:5 [66]</p5.prototype.redraw file:///C:/Users/.../src/libraries/p5.js:49679:7 p5/this._draw< file:///C:/Users/.../src/libraries/p5.js:44342:7 self-hosted:941:17 p5/this._runIfPreloadsAreDone file:///C:/Users/.../src/libraries/p5.js:44249:7 p5/this._decrementPreload file:///C:/Users/.../src/libraries/p5.js:44257:7 [76]</p5.prototype.loadImage/img.onload file:///C:/Users/.../src/libraries/p5.js:54432:5

    Line sketch.js:37:5 is where the P5js keyword 'image' is called.

  • Hard to say without seeing the full code: e.g. are you sure you've defined variables in the correct scope in order to access them in draw()? Do you run setup()? It's not included in your original example code and I have a vague recollection that p5.js expects to find it - even if it doesn't actually do anything...

    Actually been a while since I touched p5 - but I still lurk here occasionally :ar!

  • edited October 2017 Answer ✓
    "use strict";
    
    const FOLDER = 'sprites/', FILE = 'running', EXT = '.png',
          PATH = FOLDER + FILE,
          FPS = 2, SPRITES = 8, frames = Array(SPRITES);
    
    let idx = 0;
    
    function preload() {
      for (let i = 0; i < SPRITES; ++i)  frames[i] = loadImage(PATH + i + EXT);
    }
    
    function setup() {
      const frame = frames[idx];
      createCanvas(frame.width, frame.height);
      frameRate(FPS);
    }
    
    function draw() {
      background(frames[idx++]);
    }
    
Sign In or Register to comment.