SVG rotation based on pixel value

VELVEL
edited October 2016 in Questions about Code

Hi there,

I am very new to Processing. I have this image, and over it I am placing SVG's - who's width and height are based on the Greyscale value of the pixel underneath.

My problem - I am wanting the greyscale value to affect the rotation of the SVG; so the lower the Greyscale value the less rotated the SVG and the higher the value the more rotated. The problem is when I apply any sort of rotation within the code it rotates the whole grid! - How can I get each SVG to rotate within its each individual grid block?

Many thanks in advance,

Here is the code -


PShape myShape;
 PImage img ;


 void setup() {
    size(900, 600);
    img = loadImage("photo.png");
    myShape = loadShape("module_1.svg");
    noStroke();
 }

 void draw() {
    background(255);

     for (int gridX = 0; gridX< img.width; gridX++) {
        for (int gridY = 0; gridY < img.height; gridY++) {

          float tileWidth = width / (float)img.width ;
          float tileHeight = height / (float)img.height ;
          float posX = tileWidth*gridX ;
          float posY = tileHeight*gridY ;

       color c = img.pixels[gridY*img.width+gridX] ;
       int greyscale = round(red(c)*0.222+green(c)*0.707+blue(c)*0.071) ;

  pushMatrix();
     float w1  = map(greyscale, 0, 255, 3, 0.1); 
     resetMatrix();
     shape(myShape, posX, posY, w1, w1);
  popMatrix();


      }
    }
  }

Answers

  • not sure why the strange layout to the post

  • @VEL -- have you read the Processing Tutorial 2D Transformations? Look at the section "Rotating the Correct Way" for the basic concept. Does that help?

  • VELVEL
    edited October 2016

    @jeremydouglass

    Thanks for the reply, the documentation is very helpful , from what I understand I have added a 'translate' to set the start of the loop which makes the grid,then I have added another 'translate' pointing to the X and Y. However still no luck, I think it's missing something fundamental but don't know what , any thoughts?

    here's the code -

    `    PShape myShape;
        PImage img ;
    
    
    
    void setup() {
      size(900, 600);
      img = loadImage("pic.png");
      myShape = loadShape("module_1.svg");
      noStroke();
    }
    
    
    void draw() {
      background(255);
      translate(0, 0);  // where the loop that makes the grid would begin
    
      for (int gridX = 0; gridX< img.width; gridX++) {
      for (int gridY = 0; gridY < img.height; gridY++) {
    
        float tileWidth = width / (float)img.width ;
        float tileHeight = height / (float)img.height ;
        float posX = tileWidth*gridX ;
        float posY = tileHeight*gridY ;
    
    
        color c = img.pixels[gridY*img.width+gridX] ;
        int greyscale = round(red(c)*0.222+green(c)*0.707+blue(c)*0.071) ;
    
        pushMatrix();
    
        float w1  = map(greyscale, 0, 255, 3, 0.1);  
    
        translate(gridX, gridY); // rotate each individual tile
        rotate(w1);
        shape(myShape, posX, posY, w1, w1);
       popMatrix();
    
    
          }
        }`
    
  • an update...i've learned that I was using 'pushMatrix();' incorrectly. Here is an update with some progress but still not the desired result.


        PShape myShape;
        PImage img ;
    
    
    
        void setup() {
          size(900, 600);
          img = loadImage("pic.png");
          myShape = loadShape("module_1.svg");
          noStroke();
        }
    
        void draw() {
          background(255);
          translate(0, 0);
    
          for (int gridX = 0; gridX< img.width; gridX++) {
          for (int gridY = 0; gridY < img.height; gridY++) {
    
          pushMatrix();
    
            float tileWidth = width / (float)img.width ;
            float tileHeight = height / (float)img.height ;
            float posX = tileWidth*gridX ;
            float posY = tileHeight*gridY ;
    
            color c = img.pixels[gridY*img.width+gridX] ;
            int greyscale = round(red(c)*0.222+green(c)*0.707+blue(c)*0.071) ;
    
            popMatrix();
    
            float w1  = map(greyscale, 0, 255, 3, 0.1);  
    
            pushMatrix();
            translate(posX, posY);
            rotate(w1);
            shape(myShape, gridX, gridY, w1, w1);
            popMatrix();
    
    
              }
            }
          }
    
    
    
    `
    
  • It would help testing and feedback if you can provide links to pic.png / module_1.svg, or point to comparable files online.

    Or should the sketch work the same with any images of any size / type?

  • edited October 2016 Answer ✓

    Followup:

    For those interested in mapping shapes to a background image by a parameter, here is a working sketch based on the approach above.

    Source images:

    Sketch:

    /** 
     * SVG shapeRotation By Color
     * 2016-10-15 Processing 3.2.1
     * Press 1, 2 to toggle image layers.
     * Press 3, 4 to toggle rotation/scaling.
     *
     * https:// forum.processing.org/two/discussion/18443/0/#Form_Comment
     * Background image from https:// dheerajir.wordpress.com/2010/07/13/css-image-maps-with-change-map-color-on-rollover/
     * Pointer shape SVG from https:// www.svgimages.com/pointer-hand-gesture.html
     **/
    
    PImage sourceImage;
    PImage sourceMap;
    PImage outputImage;
    PShape nodeShape;
    
    boolean imageOn = true;
    boolean shapeOn = true;
    boolean rotateOn = true;
    boolean scaleOn = false;
    
    void setup() {
      size(800, 600);
      // load background
      sourceImage = loadImage("source_colormap.png");
      sourceImage.resize(width, height);
      // create small copy for computing grid values
      sourceMap = createImage(40, 30, RGB);
      sourceMap.copy(sourceImage, 0, 0, sourceImage.width, sourceImage.height, 0, 0, sourceMap.width, sourceMap.height);
      // load shape for shapeRotation / annotation
      nodeShape = loadShape("node_hand.svg");
      noStroke();
      noLoop();
    }
    
    void draw() {
      background(255);
      if (imageOn) {
        image(sourceImage, 0, 0);
      }
      markImage(sourceMap);
    }
    
    void keyPressed() {
      if (key=='1') { 
        imageOn=!imageOn;
      }
      if (key=='2') { 
        shapeOn=!shapeOn;
      }
      if (key=='3') { 
        rotateOn=!rotateOn;
      }
      if (key=='4') { 
        scaleOn=!scaleOn;
      }
      redraw();
    }
    
    void markImage(PImage gridImage) {
      float tileWidth, tileHeight;
      float posX, posY;
      color c;
      int greyscale;
      float shapeRotation;
      float shapeScale;
    
      tileWidth = width / (float)gridImage.width;
      tileHeight = height / (float)gridImage.height;
    
      // loop through grid positions
      for (int gridX = 0; gridX < gridImage.width; gridX++) {
        for (int gridY = 0; gridY < gridImage.height; gridY++) {
          // compute screen location
          posX = (gridX+.5) * tileWidth;
          posY = (gridY+.5) * tileHeight;
          // compute shape property based on map greyscale
          c = gridImage.pixels[gridY * gridImage.width + gridX];
          greyscale = round(red(c) * 0.222 + green(c) * 0.707 + blue(c) * 0.071) ;
          shapeRotation  = map(greyscale, 0, 255, 3, 0.1); 
          shapeScale = map(greyscale, 0, 255, 2, 1);
          if (shapeOn) {
            // draw shapes
            pushMatrix();
            translate(posX, posY);
            if (rotateOn) { 
              rotate(shapeRotation);
            }
            scale(0.06); // starting size
            if (scaleOn) { 
              scale(shapeScale);
            }
            shape(nodeShape, 0, 0);
            popMatrix();
          }
          if (!imageOn && !shapeOn) {
            // draw arrows
            pushMatrix();
            translate(posX, posY);
            if (rotateOn) { 
              rotate(shapeRotation);
            }
            fill(c);
            stroke(c);
            if (scaleOn) { 
              strokeWeight(shapeScale);
            }
            if (scaleOn) { 
              scale(shapeScale);
            }
            translate(0, 10);
            line(10, 0, 7, -3);
            line(0, 0, 10, 0);
            line(10, 0, 7, 3);
            popMatrix();
          }
        }
      }
    }
    

    Output:

    • rotation:
      svg_rotation
    • scale:
      svg_scale
    • rotation+scale (showing background):
      svg_rotation_scale_background
    • no svg, draw arrows:
      svg_nosvg_arrows
  • @jeremydouglass - god bless man! thanks for taking the time to do this, think other new people like myself will find this helpful too.

    Many thanks

Sign In or Register to comment.