"Move Pixels" function

edited July 2016 in Questions about Code
PGraphics pg1;

int size;
color [] ccc;
float rotAngle = 0;
color col = 0;
color colour;
color rand;



void setup()   
{
  size(900,600);
  background(0);
  frameRate (100);
  smooth();
  noStroke();

  pg1 = createGraphics(width,height,JAVA2D);


  size = 20;
  ccc = new color[size*size];
  colour = color(random(255), random(255), random(255));
  rand = color(random(-50, 50), random(-50, 50), random(-50, 50));


  for (int i=0; i<1500;i=i+30)
  {
    fill(col);
    rect(i,0,30,600);

    col = col+5;
  }

  for (int i = 0; i < size*size; i++)
  {
    rand = rand+int(random(-10,10));
    ccc[i] = colour+rand;
  }
} 



void draw()
{
  if (mousePressed)
  {
    brush01();
  }

  image(pg1,0,0);
}



void brush01()
{

  int i;
  float brush_X = 0;
  float brush_Y = 0;

  for (i =1; i<size*size; i++)
  {

    if (mouseX != pmouseX || mouseY != pmouseY)
    {
      rotAngle = atan2(mouseY - pmouseY, mouseX - pmouseX);
    }

    pg1.beginDraw();
    pg1.pushMatrix();
    pg1.rectMode(CENTER);
    pg1.translate(mouseX, mouseY);
    pg1.rotate(rotAngle);
    pg1.translate(0-size/2, 0-size/2);
    pg1.fill(ccc[i]);
    pg1.noStroke();
    pg1.rect(brush_X, brush_Y, 1, 1);
    pg1.popMatrix();
    pg1.endDraw();



    brush_X ++;
    if (brush_X > size)
    {
      brush_X = 0;
      brush_Y ++;
    }
  }
}



void mouseReleased()
{
  colour = color(random(255), random(255), random(255));
  rand = color(random(-50, 50), random(-50, 50), random(-50, 50));

  for (int i = 0; i < size*size; i++)
  {
    rand = rand+int(random(-10,10));
    ccc[i] = colour+rand;
  }
}

Here is my code. Please, draw some strokes on a canvas. The strokes are creating on a separate PGraphics layer. And the question is - how to create something like Move Function, to be able to move layer with strokes, using left mouse button + drag.

Tagged:

Answers

  • Do you want to move the entire layer, in line 53?

    replace 0,0 with layerX, layerY and when mouse change those

  • I thought there is a way to move a pixels of a layer, because if I move entire layer, the next strokes will be not in the place where I draw it, isn't it?

  • here is version (without PGraphics though)

    in drag mode you can move existing rects

    (non optimized code)

    ;-)

    // Flags 
    boolean boolDragMode = false; 
    
    // Mouse 
    boolean hold = false;
    
    int selected=-1; 
    
    // ArrayList OF RECTS
    ArrayList<RectClass> rects = new ArrayList();
    
    // RECTS Width
    int lineWidth = 9;
    
    // array of colors
    color [] myNiceColors = { 
      color (255, 0, 0), 
      color (0, 255, 0), 
      color (0, 0, 255), 
      color (255, 0, 255), 
      color (255, 255, 255)
    };
    
    // current color 
    int colorPointer = 2; 
    
    // -------------------------------------
    
    void setup () {
      size(850, 600);
    }
    
    void draw () {
      background(255);
      addNewRect();
      drawLines();
    
      if (boolDragMode&&hold&&selected!=-1) {
        // 
        RectClass currentRect = rects.get(selected);
        currentRect.x+=mouseX-pmouseX;
        currentRect.y+=mouseY-pmouseY;
      }
    
      // help text -----------------------
      fill(0); 
      text("0 to 4 for colors. Backspace to remove last rectangle. D mode to drag on / off. Drag is " 
        + strOnOffFromboolean(boolDragMode) 
        + ".", 10, 20);
      if (boolDragMode) {
        fill(255, 2, 2); 
        text("Drag mode: Drag and drop to move a rect. While dragging hit delete to remove it. Hit D to quit drag mode.", 10, 40);
      }//if
    } 
    
    String strOnOffFromboolean(boolean value) {
      if (value)
        return "On";
      else 
      return "Off";
    }
    
    // -------------------------------------
    
    // this tab gets all the Inputs 
    
    void keyPressed() {
      if (key == 'w' || key == 'W') {
        // delete all
        rects.clear();
      } else if (key == 'd'|| key == 'D') {
        // toggle
        boolDragMode=!boolDragMode;
        // reset 
        hold = false;
        selected = -1;
      } else if (key == DELETE) {
        //
        if (boolDragMode&&hold&&selected!=-1) {
          rects.remove(selected);
          selected=-1; 
          hold=false;
        }//if
      } else if (key == BACKSPACE) {
        int lastOne = rects.size()-1;
        if (lastOne>=0) {
          // Items can be deleted with remove()
          rects.remove(lastOne);
        }
      } else if (key == '+') {
        lineWidth++;
      } else if (key == '-') {
        lineWidth--;
        if (lineWidth<=1) {
          lineWidth=1;
        }
      } else if (key == '0' || key == '1' || key == '2'  || key == '3'  || key == '4') {
        int val1 = int(key);
        colorPointer = val1-48;
        println(colorPointer);
      }
    } // func  
    
    void mousePressed() {
      hold = true;
      selected = -1;
    
      if (boolDragMode) {
        for (int i = rects.size()-1; i >= 0; i--) {
          RectClass currentRect = rects.get(i);
          if (currentRect.mouseOver()) {
            // mouse
            selected = i;
            break;
          }
        }
      }
    } // func 
    
    void mouseReleased() {
      hold=false;
    } // func 
    
    // tab for rects when drawing free hand 
    
    void addNewRect() {
      // add new 
      if ((!boolDragMode) && hold && (mouseX!=pmouseX||mouseY!=pmouseY)) {    
        rects.add(new RectClass(mouseX, mouseY, lineWidth, myNiceColors[colorPointer] ));
      }
    }
    
    //
    
    void drawLines () {
      // show all  
      // 
      for (int i = rects.size()-1; i >= 0; i--) {
        RectClass currentRect = rects.get(i);
        currentRect.display();
      }
    }
    
    // ------------------------------------------------------
    
    class RectClass {
    
      float x;
      float y;
      //float x2;
      //float y2;
      color myColor;
      float w; // width 
      // float life = 255;
    
      RectClass(float tempX, float tempY, 
        float tempW, 
        color tempmyColor1) {
    
        x = tempX;
        y = tempY;
        //x2 = tempX2;
        //y2 = tempY2;
        w = tempW;
        myColor=tempmyColor1;
      }
    
      void display() {
        stroke (0);
        fill(myColor); 
        rect (x, y, w, w);
      }
    
      boolean mouseOver() {
        if (dist(mouseX, mouseY, x, y)<20) {
          return true;
        } else {
          return false;
        }
      }//
    } // class
    //
    
    
    //
    
  • This code is interesting and informative, but thats not what I wanted. I want every pixel inside my PGraphics move the same direction follow a mouse, when left button is pressed. So, I want to create something like move function in Adobe Photoshop.

  • oh boy, really...

    you have to work on describing better what you mean...

    This is now the 3rd totally different thing you are asking for....

  • sorry for misunderstanding, maybe my english is not very good

  • You are already using the left mouse button to draw the strokes so using it to move the layer is going to be difficult. Effectively you need a drawr mode and a move mode.

  • Quark, I understand that move function requires an addintional button to be pressed, or different mode. The question is how to move all the pixels inside PGraphics in one direction (using mouse).

  • So, I want to create something like move function in Adobe Photoshop.

    I am not very familiar with Photoshop but most graphics programs use a combination of vector graphics and pixel graphics. Vector graphics can easily be selected and moved but pixel graphics (which is what you are doing) are generally drawn to separate layers and you move the pixels by moving the layer containing the pixels you want to move. It does NOT move the pixels within the layer.

    Which is what chrisir was suggesting in his first post.

    The pixel colour data in a PGraphic is stored in an array, to move the colour data means shifting a large amount of data inside the array which is possible but very inefficient.

    You should consider using multiple PGraphic(s) objects to simulate layers one of which would be your background.

  • In Adobe Photoshop I use brush to draw pixel strokes on canvas, and then I can use move tool to move those pixels on canvas. The layer stands still, and the pixels are moving. I don't think it is inefficient. In Processing, if I move entire layer by moving "image(pg1, this_coordinate, and_this_coordinate)", there are two problems - my next strokes are not in wanted positions, and the limit coordinates of PGraphics is shifting, so I can't draw in some sides of canvas. So, the question is still the same - how to move all the pixels inside PGraphics, not the image with PGraphics.

  • Answer ✓

    As I said I am unfamiliar with Photoshop, I use GIMP which works as I described.

    I have modified your sketch to do what you want (at least I hope so).

    The sketch has 1) a separate graphic for the gradient background
    2) 2 modes DRAW and MOVE (Press 'd' for draw and 'm' for move)

    To try it out

    run the sketch (it starts in DRAW mode)
    draw some strokes
    draw some more strokes
    press 'm' to go into MOVE mode
    click and drag the mouse to move the strokes
    press 'd' to enter DRAW mode
    draw some more strokes.
    
    
    PGraphics pg1, bg;
    PImage temp;
    
    int size;
    color [] ccc;
    float rotAngle = 0;
    color col = 0;
    color colour;
    color rand;
    
    final int DRAW = 0;
    final int MOVE = 1;
    int mx, my, pg1x = 0, pg1y = 0;
    
    int mode = DRAW;
    boolean useBrush = false;
    
    void setup() {
      size(900, 600);
      //background(0);
      frameRate (100);
      //smooth();
      //noStroke();
    
      pg1 = createGraphics(width, height, JAVA2D);
      bg = createGraphics(width, height, JAVA2D);
    
      size = 20;
      ccc = new color[size*size];
      colour = color(random(255), random(255), random(255));
      rand = color(random(-50, 50), random(-50, 50), random(-50, 50));
    
      bg.beginDraw();
      for (int i=0; i<1500; i=i+30) {
        bg.fill(col);
        bg.rect(i, 0, 30, 600);
    
        col = col+5;
      }
      bg.endDraw();
      for (int i = 0; i < size*size; i++) {
        rand = rand+int(random(-10, 10));
        ccc[i] = colour+rand;
      }
    } 
    
    void draw() {
      image(bg, 0, 0);
    
      if (useBrush) {
        brush01();
      }
      image(pg1, pg1x, pg1y);
    }
    
    void keyTyped() {
      switch(key) {
      case 'd':
        mode = DRAW;
        useBrush = true;
        break;
      case 'm':
        useBrush = false;
        mode = MOVE;
        break;
      }
    }
    
    void mousePressed() {
      switch(mode) {
      case DRAW:
        useBrush = true;
        break;
      case MOVE:
        temp = pg1.get();
        break;
      }
    }
    
    void mouseDragged() {
      switch(mode) {
      case DRAW:
        break;
      case MOVE:
        pg1x = pg1x + (mouseX - pmouseX);
        pg1y = pg1y + (mouseY - pmouseY);
        println(pg1x, pg1y);
      }
    }
    
    void mouseReleased() {
      switch(mode) {
      case DRAW:
        useBrush = false;
        colour = color(random(255), random(255), random(255));
        rand = color(random(-50, 50), random(-50, 50), random(-50, 50));
    
        for (int i = 0; i < size*size; i++) {
          rand = rand+int(random(-10, 10));
          ccc[i] = colour+rand;
        }
        break;
      case MOVE:
        pg1.beginDraw();
        pg1.clear();
        pg1.image(temp, pg1x, pg1y);
        pg1x = pg1y = 0;
        pg1.endDraw();
        break;
      }
    }
    
    void brush01() {
      int i;
      float brush_X = 0;
      float brush_Y = 0;
    
      for (i =1; i<size*size; i++) {
        if (mouseX != pmouseX || mouseY != pmouseY) {
          rotAngle = atan2(mouseY - pmouseY, mouseX - pmouseX);
        }
        pg1.beginDraw();
        pg1.pushMatrix();
        pg1.rectMode(CENTER);
        pg1.translate(mouseX, mouseY);
        pg1.rotate(rotAngle);
        pg1.translate(0-size/2, 0-size/2);
        pg1.fill(ccc[i]);
        pg1.noStroke();
        pg1.rect(brush_X, brush_Y, 1, 1);
        pg1.popMatrix();
        pg1.endDraw();
    
        brush_X ++;
        if (brush_X > size) {
          brush_X = 0;
          brush_Y ++;
        }
      }
    }
    
  • This is close to what I wanted, thanks! But there is a little issue - I've noticed that strokes are loosing their color bit by bit and become black, if I move a few times. Is there a possibility to fix this?

  • change line 114 to

    pg1.background(255,0); // transparent white

  • edited July 2016

    after I canged "pg1.clear()" on "pg1.background(255,0)", the pixels become white : (

  • Worked for me!

  • Sorry forget that they got lighter for me too. Don't know why.

  • All I can suggest is that when calculating the color to use for the brush you are introducing transparency (i.e. alpha channel < 255)

  • thanks for your help! I will try to solve this by myself.

Sign In or Register to comment.