How to copy PImage into PImage with rotation and alpha

edited September 2016 in How To...

Hi , I want to use processing to generate big images (with alpha) for print (16000x16000 pixels). In that process, I use one small PImage (with alpha channel) as a pencil. I need to copy millions of times this small PImage at different places, rotations, sizes, colors and blends in a big PImage with a good anti-aliasing. I don't see any way to do that ... Any idea ? thanks

Answers

  • Answer ✓

    use an off-screen graphic created using createGraphics(). this can be a different size to the screen.

    you might run into memory issues if it's too big

    here's an example using rotated, semi-transparent rectangles rather than images, but i think you probably only need to change / add a couple of lines to get it to do what you want.

    PGraphics pg;
    
    void setup() {
      size(600, 600, P2D);
      // create offscreen graphics
      pg = createGraphics(1200, 1200, P2D);
    }
    
    void draw() {
      // do all your drawing to the offscreen graphic
      pg.beginDraw();
      pg.background(0);
      // move origin to middle
      pg.translate(pg.width / 2, pg.height / 2);
      pg.noStroke();
      for (int i = 0 ; i < 100 ; i++) {
        // random semi-opaque colour
        pg.fill(random(192, 256), random(192, 256), random(192, 256), 192);
        pg.pushMatrix();
        pg.rotate(random(TWO_PI));
        pg.rect(random(pg.width) / 2, random(pg.height) / 2, 50, 50);
        pg.popMatrix();
      }
      pg.endDraw();
      // save offscreen image
      pg.save("image.png");
      // copy offsceen to screen
      image(pg, 0, 0, width, height);
      noLoop();
    }
    
  • edited September 2016 Answer ✓

    Hopefully this will work in pure Processing as long as you have enough RAM available.

    However -- if you are specifically rendering for print, then if you encounter memory problems one suggestion I have is tiling and post-processing. This will work even for really extreme requirements (e.g. billions of pixels).

    1. Use two loops to walk through a set of x*y tiles (e.g. 16x16, 256 tiles of 1000x1000 pixels each).
    2. In each tile inner loop, translate() your sketch so that the current tile coordinates are lined up with the rendering window
    3. Render "pencil" data that appears in that tile only (plus/minus a border of nearby, overlapping objects).
    4. Save current sketch to a tile image named by loop position ( 02x04.png ).
    5. Clear everything from memory before moving to the next tile.

    When you are done you have a directory with 256 tiles. Use some post-processing montage program to assemble your mega-image -- it can write streams of pixels into a file and won't actually need to load everything at once. For example, imagemagick has a 'montage' command that will assemble all the png files in a directory into a 16x16 image like this:

    montage *.png -tile 16x16 -geometry 1000x1000+0+0 FinalMontage.jpg
    

    This approach might not work very well if you had lots of shapes all cutting across most of the tiles. However, you describe millions of very small shapes -- for that it should work extremely well.

Sign In or Register to comment.