Repeat an image as a background

edited June 2017 in How To...

Hey there! I am trying to find an easy way to use a square image as a background by repeating it all over the screen in a way that will work on multiple screen sizes without changing anything else but the window's size.

I am sort of new to processing, so it's most likely that I will not understand what to do if you will explain it without giving the code. However, I do not want to be spoon-fed, so please leave an explanation in case you want to give me the code.

Thanks.

Tagged:

Answers

  • edited June 2017 Answer ✓

    you put the background image in folder called data,
    load and show it like this ...

    PImage backgroundimage;
    void setup(){
      backgroundimage = loadImage("background.jpg");
    }
    void draw(){
      image(backgroundimage,0,0);
    }
    

    then you need to loop to repeat

    to find out how many times you need to loop you can add something like this...

    int cols;
    int rows;
    PImage backgroundimage;
    void setup(){
      backgroundimage = loadImage("background.jpg");
      cols = width/backgroundimage.width;
      rows = height/backgroundimage.height;
      if( width%backgroundimage.width> 0){cols++;}
      if( height%backgroundimage.height > 0){rows++;}
    }
    void draw(){
      image(backgroundimage,0,0);
    }
    

    and finally...

    int cols;
    int rows;
    PImage backgroundimage;
    void setup(){
     fullScreen();
      backgroundimage = loadImage("background.jpg");
      cols = width/backgroundimage.width;
      rows = height/backgroundimage.height;
      if( backgroundimage.width%width > 0){cols++;}
      if( backgroundimage.height%height > 0){rows++;}
      println(cols);
    }
    void draw(){
      for (int y=0; y<rows; y++){
        for (int x=0; x<cols; x++){
          image(backgroundimage,x*backgroundimage.width,y*backgroundimage.height);
        }
      }
    }
    
  • edited November 2017

    @SirCodalot -- to paraphrase the question and answer:

    Q: "How can I draw a grid of images onto the screen so that the size of the grid is based on the current width and height of the screen?"

    @prince_polka's answer:

    A: "Draw grids with nested for loops -- one for y rows, one for x columns. Use the processing built-ins width and height to calculate the number of rows or columns needed and those loops will change based on the current screen size.

  • Hi prince_polka, I follwed the above code. I thought it would equally distribute the image exactly within the window. When I ran it, it just was a very small square part of the image, not repeated. When I added a screen size of 1000,1000, the images did repeat, but not to fit equally. Did I miss somthing?

    Simon

  • @zymon the image isn't scaled so it may crop the way you described

  • @zymon -- the approach calculates the number of columns and rows. It assumes that you are providing:

    1. a screen size -- e.g. size(400,400)
    2. an image that is a perfect tile of that screen size, e.g. 100x100 or 10x10

    If you aren't, then you can either:

    1. change the screen size (212x212 image, 424x424 screen)
    2. resize the image in setup using .resize()
    3. use a very different approach, where instead you define the number of columns and rows and screen size, then you calculate what size you need to resize the image in order to fit within that grid.

    Aside: this is definitely not for beginners, but if someone approaching this problem wanted to use a shader approach, they might try ((PGraphics2D)g).textureWrap(Texture.REPEAT); -- see: https://forum.processing.org/two/discussion/15242/tiling-a-texture-for-a-glsl-shader

  • edited December 2017

    @jeremydouglas spot on explanation
    I agree that you need to specify how many rows and columns you want.
    I did not know about the ((PGraphics2D)g).textureWrap(Texture.REPEAT) feature and maybe it's a better approach than modulo but wrote a.
    This is not beginner friendly, but inlined the shader so it's easy to copy paste.

    PShader ps;
    PImage img;
    /*
    I don't write vert shaders just copied this
    */
    String[] vert= {
      "uniform mat4 transform;", 
      "in vec4 vertex;", 
      "void main() {", 
      "gl_Position = transform*vertex;", 
      "}"
    };
    String[] frag = {
      "uniform sampler2D img;", 
      "uniform vec2 imgres;", 
      "uniform vec2 resolution;", 
      "void main(){", 
      "vec2 pos = mod(gl_FragCoord.xy,imgres)/imgres;", 
      "gl_FragColor=texture2D(img,vec2(pos.x,1.0-pos.y));", 
      "}"
    /* 
    vec2(pos.x,1.0-pos.y) flips the image upside down.  
    Can be replaced with just 'pos' if you flip in vert, processing,
    or perhaps even want it upside down.    
    */
    };
    void repeat(float cols, float rows, float w, float h, String src) {
      img = loadImage(src);
      ps = new PShader(this, vert, frag);
      ps.set("img", img);
      ps.set("imgres", w/rows, h/cols);
      shader(ps);
      rect(0, 0, w, h);
      resetShader();
    }
    void setup() {
      fullScreen(P2D);
      repeat(10, 20, width, height, "background.jpg");
    }
    

    Probably OpenGL experts know of better ways to do this.

  • edited December 2017

    OFFTOPIC: @prince_polka
    Just a note: the shader is blinking as crazy on my windows machine. Does it work for you? would be interesting, - if that is an windows related bug.

    I thought that the shader needs to be placed inside the draw() method, becourse processing is Swaping buffers inside draw running in P2D/P3D mode.

  • @nabr It's not blinking for me, Windows too.

  • edited December 2017

    Hi,

    I did not understand what all this height%background was doing, but in messing arround I realised that I can specify numbe rof column/rows. As in the code below (very beginner stuff here).

    Unfortunaely I still dont realy understand how to make the images fit within the screen size without cutting off (unless I do the maths and make the screen the correct size).

    I commented out some code that was not doing anyting.

    int cols;
    int rows;
    
    PImage img;
    
    void setup (){
      size (1800,900);
      img = loadImage ("Route1_01sq.jpg");
      cols = 5;
      rows = 3;
      //if (width%backimage.width > 0) {cols++;}
      //if (height%backimage.height > 0) {rows++;}
      //println (cols);
    }
    void draw (){
      for (int y=0; y < rows; y++){
        for (int x = 0; x < cols; x++){
          image (img, x*img.width, y*img.height);
        }
      }
    }
    

    [mod edit: formatted above code]

  • Sorry but I dont know how to make the code look properly formatted in the window?

  • Edit post, highlight code, press ctrl-o to format

    The modulo thing is just adding another row or column to the loop of the image doesn't fit the screen exactly. Without it you'd have a gap at the right / bottom.

  • @nabr @prince_polka Not blinking on mine (Using a Win7 x64 atm). I have to say you should add an empty draw() function in your sketch as the sketch will not respond to the exit command (when you press ESC key) if you don't have it.

    void draw(){}
    

    Kf

  • edited January 2018

    @kfrajer
    Yeah, but what's your the definition of a bug ? Code working on one PC, has to be modified on a second, that is my definition of a bug.

    try {
           JOGL rect
         }
    successful ? 
    paint Java window rect  
    

    would fix it in my case. I'm waiting for the knight who implements it. Currently the time difference between Java painting Window and Jogl gets its startup is to big. My theory.

    Maybe some1 will also update the doc: https://processing.org/reference/
    if you have a notebook use draw in the startup.

    @zymon
    You have a window its usually a rectangle you have to calculate area width * height
    You have an image size usually a rectangle too, you have to calculate area width * height

    How many times you can put the (resized) imageRect(s) to match the windowRect ?

    Image you inviting your friends to a cool pajama party, play Nintendo Super Mario Bros and watch Scoby Doodo on VHS. Also you have prepared a cake, how you would slice it, so everyone get a piece of cake and no one piece is left.

    You have to modify the image size or the gap between the images

    Easy.

Sign In or Register to comment.