how to do Flip Canvas Horizontal to an image and save???

edited December 2016 in How To...

as the title asked

Answers

  • edited March 2014

    I guess this might work: :-/

    scale(-1, 1);
    image(img, -(x + img.width), y);
    
  • edited March 2014

    try

    scale(1,-1);

    to flip

    save - see reference

    line(20, 20, 80, 80);
    // Saves a TIFF file named "diagonal.tif"
    save("diagonal.tif");
    // Saves a TARGA file named "cross.tga"
    line(80, 20, 20, 80);
    save("cross.tga");
    

    http://processing.org/reference/save_.html

  • edited March 2014
    PImage photo, maskIMG, outIMG, diaIMG;
    
    void setup() {
      size(900, 900);
      background(0);
      noStroke();
      smooth(8);
      photo = loadImage("test.jpg");
      maskIMG = loadImage("mask.jpg");
      image(photo,-1000,-1500);
      outIMG = get(0, 0, 140, 163);
      outIMG.mask(maskIMG);
      diaIMG = outIMG.get(0, 0, 140, 163);
      diaIMG.save("d" + ".png");
      clear();
      photo=loadImage("d.png");
      scale(-1,1);
      image(photo,0,500);
      diaIMG = outIMG.get(0, 0, 140, 163);
      diaIMG.save("d2" + ".png");
    }
    

    as the effect the code show ,seems scale no effect,any tips???

  • here...

    PImage photo;
    
    void setup() {
      size(900, 900);
      background(0);
      noStroke();
      smooth(8);
      photo = loadImage("test.png");
    
      //maskIMG = loadImage("mask.jpg");
    }
    
    void draw() {
    
      noLoop();
    
      scale( -1, 1);
    
      image(photo, -photo.width, 0);
    }
    
  • PImage photo, maskIMG, outIMG, diaIMG;
    
    void setup() {
      size(900, 900);
      background(0);
      noStroke();
      smooth(8);
      photo = loadImage("test.jpg");
      maskIMG = loadImage("mask.jpg");
      image(photo,-1000,-1500);
      outIMG = get(0, 0, 140, 163);
      //outIMG.mask(maskIMG);
      diaIMG = outIMG.get(0, 0, 140, 163);
      diaIMG.save("d" + ".png");
      clear();
      photo=loadImage("d.png");
      image(photo,-photo.width,0); or scale(-1 , 1)
      outIMG = get(0, 0, 140, 163);
      diaIMG = outIMG.get(0, 0, 140, 163);
      diaIMG.save("d2" + ".png");
    }
    

    there seems some problem in the code , can somebody figure it out??? no correct image show but the black......

  • edited March 2014

    I think with scale you rotate the image out of the canvas

    bring it back in with image(photo, -photo.width, 0); like in my code above

  • Or simply write yourself an flipImage() function:

    PImage someImage;
    
    void setup() {
        someImage = loadImage("http" + "://upload.wikimedia.org/wikipedia/commons/thumb/5/59/Processing_Logo_Clipped.svg/256px-Processing_Logo_Clipped.svg.png");
        size(someImage.width, someImage.height, P2D);
    }
    
    void draw() {
        flipImageH(someImage, 0, 0);
    }
    
    void flipImageH(PImage image, float x, float y) {
        beginShape(QUADS);
        texture(image);
        vertex(0, 0, width, 0);
        vertex(width, 0, 0, 0);
        vertex(width, height, 0, height);
        vertex(0, height, width, height);
        endShape();
    }
    
  • edited March 2014

    there's anther question here: why after loading the image the coordinate of the image is minus X +) , minus Y(+) for example image(photo,-1000,-1500); is choosing a part from downstairs

  • edited March 2014

    Function scale() belongs to Processing's transformation group. That is, it changes the whole PGraphics coordinate system!

    By default, coordinates (0,0) at the far top-left is the point of origin. Coords. go from left to right and up to down.
    But when we issue a scale(-1, -1), the (0, 0) is transported to the far down-right! And it's now from right to left and down to up!

    However, if we wanna place a mirrored image at the very same place, we gotta compensate the coordinate change.
    I've devised a simple math for it when I've tweaked a "Bouncing Angry Bird" program.
    It's bugged online! You gotta copy it to run offline though: :-&

    http://studio.processingtogether.com/sp/pad/export/ro.9lSicL0a3WMfi/latest

    Here's a simple sketch demoing that: :bz

    /**
     * Mirror Positioning Calc (v1.01)
     * by GoToLoop (2014/Mar)
     *
     * forum.processing.org/two/discussion/3439/
     * how-to-do-flip-canvas-horizontal-to-an-image-and-save
     */
    
    static final String URL  = "http://" + "upload.wikimedia.org" + 
    "/wikipedia/commons/thumb/5/59/" + "Processing_Logo_Clipped.svg/";
    static final String NAME = "256px-Processing_Logo_Clipped.svg.png";
    
    static final int NUM = 4;
    final PVector[] sigs = new PVector[NUM];
    
    static final int X = 80, Y = 50;
    int w, h;
    
    PImage img;
    
    void setup() {
      size(600, 400, JAVA2D);
      frameRate(.25);
      smooth(4);
      imageMode(CORNER);
      background(0200);
    
      img = loadImage(URL + NAME);
      //img = loadImage(NAME);
    
      w = img.width;
      h = img.height;
    
      sigs[0] = new PVector(-1, -1);
      sigs[1] = new PVector(1, 1);
      sigs[2] = new PVector(1, -1);
      sigs[3] = new PVector(-1, 1);
    }
    
    void draw() {
      final int idx  = frameCount % NUM;
      final int sigX = (int) sigs[idx].x, sigY = (int) sigs[idx].y;
    
      frame.setTitle("sigX = " + sigX + "\tsigY = " + sigY);
    
      scale(sigX, sigY);
      image(img, X*sigX + w*(sigX>>1), Y*sigY + h*(sigY>>1));
    }
    
  • how to '' compensate the coordinate change.'' ??? by adding '-'??? (i am not good at math and new to Processing,so i can't understand some part of your code)

  • edited March 2014

    Look @ line #47: image(img, x*sigX + w*(sigX>>1), y*sigY + h*(sigY>>1));

    • img is the PImage;
    • x & y are the coordinates we wanna place the img at canvas;
    • w & h are the PImage's dimensions. That is: img.width & img.height;
    • sigX & sigY are either +1 or -1. +1 is no modification. While -1 is mirroring.

    When there's no mirror, that is sigX or sigY is +1, we don't subtract neither w nor h from x*sigX or x*sigX.
    There's nothing to compensate!

    On the other hand, when it's -1, we gotta do x*sigX - w or y*sigY - h. In short: -x - w or -(x + w).
    B/c the canvas coordinate origin's direction is backwards. That is, it's now from right to left or bottom to top!
    It's as if the whole canvas (PGraphics) was transported to another quadrant Cartesian plane! @-)

    That's when it comes in w*(sigX>>1) or h*(sigY>>1). When it's +1, sig >> 1 returns 0, nullifying w or h!
    However, when it's -1, >> 1 returns the very same -1. This time w or h's subtraction against x or y kicks in! :ar!

    Just ask again if you haven't understood some point! ;;)

  • PImage photo, maskIMG, outIMG, diaIMG,photo_compound_1,photo_compound_2;
    
    void setup() {
      size(900, 900);
      background(0);
      noStroke();
      smooth(8);
      photo = loadImage("test.jpg");
      maskIMG = loadImage("mask.jpg");
      image(photo,-1000,-1500);
      outIMG = get(0, 0, 140, 163);
      outIMG.mask(maskIMG);
      diaIMG = outIMG.get(0, 0, 140, 163);
      diaIMG.save("Basic_Part" + ".png");
      clear();
      photo=loadImage("Basic_Part.png");
      //for(int i=0;i<3;i++){
        rotate(radians(60),140,163,0);
        image(photo,photo.width,0);
    
    }
    

    rotate is not available with this renderer. ???? why it show me this???

  • edited March 2014

    @GoToLoop: what's this 4 array definitioned for

    sigs[0] = new PVector(-1, -1);
    sigs[1] = new PVector(1, 1);
    sigs[2] = new PVector(1, -1);
    sigs[3] = new PVector(-1, 1);
    

    final int sigX = (int) sigs[idx].x

    what's .x meaning and the 'final' type

  • edited March 2014

    rotate() is not available with this renderer?

    Processing 2+ got 4 rendering engines:

    1. JAVA2D;
    2. P2D;
    3. P3D or OPENGL;
    4. PDF.

    JAVA2D, which is the default, uses raster rendering. The next 2 are OpenGL based!
    Many Processing functions would only make sense in a 3D context!

    http://processing.org/reference/size_.html

  • edited March 2014

    In order to represent the signum values +1, -1 for the 4 (x, y) coordinate pairs, there were at least 2 obvious choices:

    1. Instantiate 2 byte arrays. 1 for the sigX and the other for the sigY.
    2. Or instantiate just 1 PVector array. PVector class got 3 fields -> x, y & z anyways.

    Obviously, a PVector[] is more easy visually. Just outta curiosity, check out how the byte[] way would be:

    final byte[] sigX = {-1, 1, 1, -1}, sigY = {-1, 1, -1, 1};
    

    processing.org/reference/PVector.html

  • What's .x meaning and the final type.

    That's the dot operator, which lets us access methods & fields from an object through its reference.

    http://processing.org/reference/dot.html

    In that case sigs[idx].x, sigs[idx] provides the reference for a PVector object, while the x is the field we wanna access!

    Keyword final isn't a data type! It just means a variable can't be changed anymore until the end of its scoped lifespan:

    http://processing.org/reference/final.html

  • @GoToLoop : image(img, XsigX + w(sigX>>1), YsigY + h(sigY>>1)); why the x parameter is XsigX + w(sigX>>1) and the y is YsigY + h(sigY>>1) , where this math expression coming from ??

  • edited March 2014

    I can rotate a shape with JAVA2D Why can't rotate the image??? what's wrong with the image function??? and the solution please , thanks!

  • edited March 2014

    ... where this math expression's coming from?

    Actually I've "invented" it while pursuing the "fastest" way to display "Bouncing Angry Bird", either it's flying to right or to left!

    http://studio.processingtogether.com/sp/pad/export/ro.9lSicL0a3WMfi/latest

    The other 1 I've got is the optimized pick a random opaque color -> (int) random(#000000),
    rather than the clumsy common 1 we see around -> (int) random(256), (int) random(256), (int) random(256).

    You see, when the bird is flying towards the right side, we display its unaltered sprite. Its x coordinate placement is intact.
    But when it bounces towards the left side, we gotta use scale(-1, 0) in order to display its horizontal mirrored sprite.

    Problem is, scale() alters the whole canvas, transporting its matrix coordinate system even to another quadrant! @-)
    Therefore, the value of x isn't the same anymore! So in order to display the sprite at the same place, we gotta find its new x.

    sigX = -1;
    scale(sigX, 0);
    x = x*sigX + img.width*(sigX>>1);
    

    sigX is either -1 or 1, representing whether it's horizontally mirroring or not.
    And x is the original x coordinate we wanna place the sprite at the canvas.

    So when sigX = 1, x stays the same -> x * 1 = x. While 1 >> 1 results 0. Thus img.width*(0) = 0.
    Final result is the very same x! =:) . And that's the aim, since there's no scale() changes -> scale(0, 0);

    Now w/ sigX = -1, x becomes negative -> x * -1 = -x. And -1 >> 1 returns the very same -1.
    This time, img.width*(-1) = -img.width, rather than 0. That's a small additional adjustment to the x value though.

    Take notice that expression math is for when we got a dynamic sigX or sigY. When they keep swapping +1 & -1 states.
    Otherwise, when we wanna display an always horizontally mirrored image, simply use: (*)

    scale(-1, 0);
    image(img, -(x + img.width), y);
    

    A more easier to understand, but slower & bigger alternative version:

    sigX *= -1;
    
    if (sigX == 1)  image(img, x, y);
    
    else {
      scale(-1, 0);
      image(img, -(x + img.width), y);
    }
    
  • I can rotate a shape with JAVA2D Why can't rotate the image??? what's wrong with the image function??? and the solution please , thanks!

    can u give me some more tips with the problem??? @GoToLoop

    for example I can use point rect line to create a shape , and can rotate it ,but why can't the image ???

  • edited December 2016

    Sorry I can't help you out w/ 3D stuff. No good at it at all! :(
    Anyways, I've managed to use rotate() in my example w/ JAVA2D:

    /**
     * Mirror Positioning Calc (v1.14)
     * by GoToLoop (2014/Mar)
     *
     * forum.Processing.org/two/discussion/3439/
     * how-to-do-flip-canvas-horizontal-to-an-image-and-save#Item_21
     *
     * forum.Processing.org/two/discussion/3548/
     * loading-image-from-url-lags-in-js
     *
     * OpenProcessing.org/sketch/139280
     */
    
    static final boolean ONLINE = 1/2 == 1/2.;
    
    static final String URL  = "http://" + "upload.Wikimedia.org" + 
    "/wikipedia/commons/thumb/5/59/" + "Processing_Logo_Clipped.svg/";
    static final String NAME = "256px-Processing_Logo_Clipped.svg.png";
    
    static final int X = 150, Y = 50;
    static final int NUM = 4;
    final PVector[] sigs = new PVector[NUM];
    
    PImage img;
    
    void setup() {
      size(600, 400);
      frameRate(.25);
      smooth(4);
      imageMode(CORNER);
      background(0200);
    
      if (ONLINE)  img = requestImage(URL + NAME);
      else         img = loadImage(URL + NAME);
    
      //img = requestImage(NAME);
    
      sigs[0] = new PVector(-1, -1);
      sigs[1] = new PVector(1, 1);
      sigs[2] = new PVector(1, -1);
      sigs[3] = new PVector(-1, 1);
    }
    
    void draw() {
      if (img.width == 0)  return;
    
      final int idx  = frameCount % NUM;
      final int sigX = (int) sigs[idx].x, sigY = (int) sigs[idx].y;
    
      if (!ONLINE)  frame.setTitle("sigX = " + sigX + "\tsigY = " + sigY);
    
      rotate(QUARTER_PI*.25);
      scale(sigX, sigY);
      //img.mask(img);
    
      image(img, X*sigX + img.width*(sigX>>1), Y*sigY + img.height*(sigY>>1));
    }
    
  • idx = frameCount % NUM;

    what's the meaning of it???

  • hey GotoLoop : all code is the same but this changed : rotate(QUARTER_PI/4,1,1,0); and you rotate will fail why can't rotate with a another point ?

  • edited March 2014

    final int idx = frameCount % NUM;

    Variable frameCount is the # of times draw() was invoked:
    http://processing.org/reference/frameCount.html

    NUM is a constant for the # of PVector[] objects. That is, the length of that array.

    Arithmetic operator modulo % is the remainder of a division:
    http://processing.org/reference/modulo.html

    In short, it makes sure that idx is in the range of 0 up to NUM-1, no matter the current value of frameCount. B-)

  • rotate(QUARTER_PI/4, 1, 1, 0);

    I don't even know what those extra 3 arguments do. Processing's reference doesn't even explain that overloaded case:

    http://processing.org/reference/rotate_.html

  • there is another question : how to judge odd number or not , does Processing has the function??

  • Answer ✓

    maybe like this. The % sign means modulo

    if (number % 2 == 0) {
      // not odd
    }
    else {
     // odd
    }
    
  • edited March 2014

    @GoToLoop: rotate(angle, x, y, z) mimics glRotate(angle, x, y, z). x, y and z are just multipliers for the equally named axes. rotate(TWO_PI, 0.5, 0.25, 0.0) for example will rotate the transformation matrix by PI around the x axis, by HALF_PI around the y axis and by 0 around the z axis.

    @Chrisir: In case number is an boolean/byte/char/short/int/long (/Boolean/Byte/etc.) use bitwise and, it's much faster than modulo:

    int number = 4;
    if ((number & 1) == 0) {
        println(number + "is not odd");
    } else {
        println(number + "is odd");
    }
    
  • edited March 2014

    I try to use bitwise AND all the time, as long the divisor is a power of 2:

    static final int NUM = 1<<5;  // 2^5 = 32
    final PImage[] imgs = PImage[NUM];
    
    void draw() {
      final int idx =  frameCount & NUM-1;  // same as frameCount % NUM
      set(0, 0, imgs[idx]);
    }
    

    In case number is an int/long...

    To be fairer, don't forget that byte, short, char are also whole types as well! :-h
    Even though Java coerces them to int before executing the operation. But at least it's auto! :-@

    And thx for the 4-parameter rotate() explanation, @Poersch ! =D>

  • edited March 2014

    @GoToLoop: You are right! Totally forgot to mention those! It was way to late while I wrote this. Updated my last post. :D

    I guess you already know this page, but just in case you don't and for anyone else of course: Bit Twiddling Hacks

    It's a great site about all kinds of usefull bitwise operations you should know about. ;)

  • Thx for the link! I was learning some bitwise tricks along the way! :bz

Sign In or Register to comment.