# Is it possible to construct PDFs by merging many PGraphics?

**URL:** <https://discourse.processing.org/t/is-it-possible-to-construct-pdfs-by-merging-many-pgraphics/2522>\
**Category:** Processing\
**Created:** [August 10, 2018, 2:25am UTC](https://discourse.processing.org/t/is-it-possible-to-construct-pdfs-by-merging-many-pgraphics/2522 "2018-08-10T02:25:35Z")\
**Posts on this page:** 16\
**Page:** 1

<div class="post-metadata">

**Author:** ![PerryJohnson](https://avatars.discourse-cdn.com/v4/letter/p/57b2e6/32.png) [@PerryJohnson](https://discourse.processing.org/u/PerryJohnson)\
**Post date:** [August 10, 2018, 2:25am UTC](https://discourse.processing.org/t/is-it-possible-to-construct-pdfs-by-merging-many-pgraphics/2522/1 "2018-08-10T02:25:35Z")

</div>

I’m writing a program with undo/redo functionality. It works fine using image() method to the screen renderer but I lose vector data if I use that technique in PDF.  
Is there a way to merge PGraphics, preserving the vector data so I can write a PDF/SVG?

---

<div class="post-metadata">

**Author:** ![Kevin](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/kevin/32/2297_2.png) [@Kevin](https://discourse.processing.org/u/Kevin)\
**Post date:** [August 10, 2018, 3:15am UTC](https://discourse.processing.org/t/is-it-possible-to-construct-pdfs-by-merging-many-pgraphics/2522/2 "2018-08-10T03:15:14Z")

</div>

What do you mean by merging PGraphics? Can you give an example of what you’re trying to do?

---

<div class="post-metadata">

**Author:** ![PerryJohnson](https://avatars.discourse-cdn.com/v4/letter/p/57b2e6/32.png) [@PerryJohnson](https://discourse.processing.org/u/PerryJohnson)\
**Post date:** [August 10, 2018, 3:18am UTC](https://discourse.processing.org/t/is-it-possible-to-construct-pdfs-by-merging-many-pgraphics/2522/3 "2018-08-10T03:18:43Z")

</div>

simply layering one on top of the other

---

<div class="post-metadata">

**Author:** ![Kevin](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/kevin/32/2297_2.png) [@Kevin](https://discourse.processing.org/u/Kevin)\
**Post date:** [August 10, 2018, 6:28pm UTC](https://discourse.processing.org/t/is-it-possible-to-construct-pdfs-by-merging-many-pgraphics/2522/4 "2018-08-10T18:28:28Z")

</div>

Then sure, that’s possible.

```auto
image(graphicsOne, 0, 0);
image(graphicsTwo, 0, 0);

```

Can you please post a simplified example that shows what you’re trying to do? See this guide for more info:

> [@Guidelines—Asking Questions](https://discourse.processing.org/t/guidelines-tips-on-asking-questions/2147):
>
> Summary (TL;DR) Ask complete questions to get better answers! Be specific. For example: I want to load an image. I tried using createImg() , and I expected the image to be on canvas, but what happened instead was the image showing up below the canvas. Isolate your problem and work in small steps. Share only the code directly related to your problem if it is part of a bigger project, and if something isn’t working, try the smallest code that could do the thing you want. Can we run your code to …

---

<div class="post-metadata">

**Author:** ![PerryJohnson](https://avatars.discourse-cdn.com/v4/letter/p/57b2e6/32.png) [@PerryJohnson](https://discourse.processing.org/u/PerryJohnson)\
**Post date:** [August 10, 2018, 7:49pm UTC](https://discourse.processing.org/t/is-it-possible-to-construct-pdfs-by-merging-many-pgraphics/2522/5 "2018-08-10T19:49:27Z")

</div>

Yes, and that may be fine for low resolution screen display, but image() rasterizes the PGraphic.

 ![pdfExport](https://canada1.discourse-cdn.com/flex036/uploads/processingfoundation1/original/2X/1/1993180ec61bd0e9d0a8ae093cc6e7deff2a84dc.png)

Here’s the code for that sketch.

```auto
import processing.pdf.*;

void setup() {
  beginRecord(PDF, "export.pdf");
  size(500, 500);
}
void draw() {
  ellipse(100,50,100,100);
  PGraphics graphicOne = createGraphics(500,500);
  graphicOne.beginDraw();
  graphicOne.ellipse(50,50,100,100);
  graphicOne.endDraw();
  
  image(graphicOne,0,0);
}

void keyPressed(){
  if(key == 'p'){
    endRecord();
    exit();
  }
}

```

---

<div class="post-metadata">

**Author:** ![Kevin](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/kevin/32/2297_2.png) [@Kevin](https://discourse.processing.org/u/Kevin)\
**Post date:** [August 10, 2018, 7:52pm UTC](https://discourse.processing.org/t/is-it-possible-to-construct-pdfs-by-merging-many-pgraphics/2522/6 "2018-08-10T19:52:52Z")

</div>

Have you tried using the `noSmooth()` function?

---

<div class="post-metadata">

**Author:** ![PerryJohnson](https://avatars.discourse-cdn.com/v4/letter/p/57b2e6/32.png) [@PerryJohnson](https://discourse.processing.org/u/PerryJohnson)\
**Post date:** [August 10, 2018, 8:09pm UTC](https://discourse.processing.org/t/is-it-possible-to-construct-pdfs-by-merging-many-pgraphics/2522/7 "2018-08-10T20:09:50Z")

</div>

No, but I did just now. It removes the anti-aliasing, but it’s still a raster graphic.  
 ![noSmooth](https://canada1.discourse-cdn.com/flex036/uploads/processingfoundation1/original/2X/1/1fad90acf7a29fd30c35a983135f38b74ff70f44.png)

---

<div class="post-metadata">

**Author:** ![PerryJohnson](https://avatars.discourse-cdn.com/v4/letter/p/57b2e6/32.png) [@PerryJohnson](https://discourse.processing.org/u/PerryJohnson)\
**Post date:** [August 10, 2018, 8:24pm UTC](https://discourse.processing.org/t/is-it-possible-to-construct-pdfs-by-merging-many-pgraphics/2522/8 "2018-08-10T20:24:05Z")

</div>

By the way, I’m working on a painting tool with undo/redo. `PGraphics` are stored in an ArrayList so an undo operation just reconstructs the whole image by looping through the array and imaging them all to the window. Maybe there’s a better way.

---

<div class="post-metadata">

**Author:** ![Kevin](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/kevin/32/2297_2.png) [@Kevin](https://discourse.processing.org/u/Kevin)\
**Post date:** [August 10, 2018, 8:31pm UTC](https://discourse.processing.org/t/is-it-possible-to-construct-pdfs-by-merging-many-pgraphics/2522/9 "2018-08-10T20:31:30Z")

</div>

You could store your shapes in a data structure that allows you to draw them on command instead of storing the pixels directly. Something like a `Shape` class, and then an `ArrayList` of `Shape` instances.

---

<div class="post-metadata">

**Author:** ![PerryJohnson](https://avatars.discourse-cdn.com/v4/letter/p/57b2e6/32.png) [@PerryJohnson](https://discourse.processing.org/u/PerryJohnson)\
**Post date:** [August 10, 2018, 8:41pm UTC](https://discourse.processing.org/t/is-it-possible-to-construct-pdfs-by-merging-many-pgraphics/2522/10 "2018-08-10T20:41:06Z")

</div>

I’ve tried something like that but I must confess my ignorance. I don’t know how to even make a line or ellipse store into and redraw from a PShape container.

---

<div class="post-metadata">

**Author:** ![Kevin](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/kevin/32/2297_2.png) [@Kevin](https://discourse.processing.org/u/Kevin)\
**Post date:** [August 10, 2018, 8:50pm UTC](https://discourse.processing.org/t/is-it-possible-to-construct-pdfs-by-merging-many-pgraphics/2522/11 "2018-08-10T20:50:03Z")

</div>

No I don’t mean `PShape`, I mean a custom `Shape` class. Something like this:

```auto
interface Shape{
  void drawShape();
}

class Circle implements Shape{
  float x;
  float y;
  float radius;

  void drawShape(){
    ellipse(x, y, radius, radius);
  }
}

ArrayList<Shape> myShapes = new ArrayList<Shape>();
myShapes.add(new Circle(x, y, radius));

for(Shape shape: myShapes){
  shape.drawShape();
}

```

This is just an example, but hopefully it gets the idea across. This approach would allow you to draw the shapes directly instead of storing a bunch of `PGraphics` buffers in memory.

Shameless self-promotion: here is a guide on creating classes in Processing:

> **[Creating Classes](https://happycoding.io/tutorials/processing/creating-classes)**
>
> Learn how to create classes in Processing.

---

<div class="post-metadata">

**Author:** ![PerryJohnson](https://avatars.discourse-cdn.com/v4/letter/p/57b2e6/32.png) [@PerryJohnson](https://discourse.processing.org/u/PerryJohnson)\
**Post date:** [August 10, 2018, 8:57pm UTC](https://discourse.processing.org/t/is-it-possible-to-construct-pdfs-by-merging-many-pgraphics/2522/12 "2018-08-10T20:57:55Z")

</div>

Okay!! Thank you! It’ll take me some time to wrap my head around this, as a drawing tool, but there is hope!

---

<div class="post-metadata">

**Author:** ![PerryJohnson](https://avatars.discourse-cdn.com/v4/letter/p/57b2e6/32.png) [@PerryJohnson](https://discourse.processing.org/u/PerryJohnson)\
**Post date:** [August 11, 2018, 5:52pm UTC](https://discourse.processing.org/t/is-it-possible-to-construct-pdfs-by-merging-many-pgraphics/2522/13 "2018-08-11T17:52:33Z")

</div>

Alright, I’m not sure what I’m missing here.I’m getting a Constructor does not exist error. Here’s the .pde I’m working with.

```auto
ArrayList<Shape> myShapes = new ArrayList<Shape>();

interface Shape {
  void drawShape();
}

class Circle implements Shape{
  float x;
  float y;
  float radius;

  void drawShape(){
    ellipse(x, y, radius, radius);
  }
}

void setup() {
  size(500, 500);
}
void draw() {
}

void mousePressed() {
  myShapes.add(new Circle(mouseX, mouseY, 50));
}

void keyPressed() {
  if (key == 'd') {
    for (Shape shape : myShapes) {
      shape.drawShape();
    }
  }
}

```

---

<div class="post-metadata">

**Author:** ![PerryJohnson](https://avatars.discourse-cdn.com/v4/letter/p/57b2e6/32.png) [@PerryJohnson](https://discourse.processing.org/u/PerryJohnson)\
**Post date:** [August 11, 2018, 9:10pm UTC](https://discourse.processing.org/t/is-it-possible-to-construct-pdfs-by-merging-many-pgraphics/2522/14 "2018-08-11T21:10:26Z")

</div>

I think I figured it out! This has the PDF export too.

```auto
import processing.pdf.*;

import java.util.*; // lets us use Deque - Double ended queue

Deque<Shape> undoQ = new LinkedList<Shape>();
Deque<Shape> redoQ = new LinkedList<Shape>();
PGraphicsPDF pdf;

void setup() {
  size(500, 500);
  pdf = (PGraphicsPDF) createGraphics(width, height, PDF, "export.pdf");
}
void draw() {
}
interface Shape {
  void drawShape();
  void drawShapePDF();
}
class Circle implements Shape {
  float x;
  float y;
  float radius;
  Circle(float xpos, float ypos, float r) {
    x = xpos;
    y = ypos;
    radius = r;
  }
  void drawShape() {
    ellipse(x, y, radius, radius);
  }
  void drawShapePDF() {
    pdf.ellipse(x, y, radius, radius);
  }
}

void mousePressed() {
  undoQ.add(new Circle(mouseX, mouseY, 50));
  undoQ.peekLast().drawShape();
}

void keyPressed() {
  if (key == 'z') {
    if (undoQ.size()>0) {
      redoQ.add(undoQ.removeLast());
      g.background(205);
      for (Shape i : undoQ) {
        i.drawShape();
      }
    }
  } else if (key == 'y') {
    if (redoQ.size()>0) {
      undoQ.add(redoQ.removeLast());
      for (Shape i : undoQ) {
        i.drawShape();
      }
    }
  } else if (key == 'p') {
    pdf.beginDraw();
    for (Shape i : undoQ) {
      i.drawShapePDF();
    }
    pdf.endDraw();
    pdf.dispose();
  }
}

```

---

<div class="post-metadata">

**Author:** ![Kevin](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/kevin/32/2297_2.png) [@Kevin](https://discourse.processing.org/u/Kevin)\
**Post date:** [August 13, 2018, 10:38pm UTC](https://discourse.processing.org/t/is-it-possible-to-construct-pdfs-by-merging-many-pgraphics/2522/15 "2018-08-13T22:38:13Z")

</div>

Awesome! Did this fix your problem of shapes being pixelated?

---

<div class="post-metadata">

**Author:** ![PerryJohnson](https://avatars.discourse-cdn.com/v4/letter/p/57b2e6/32.png) [@PerryJohnson](https://discourse.processing.org/u/PerryJohnson)\
**Post date:** [August 13, 2018, 10:40pm UTC](https://discourse.processing.org/t/is-it-possible-to-construct-pdfs-by-merging-many-pgraphics/2522/16 "2018-08-13T22:40:57Z")

</div>

Yes! it looks like I didn’t paste the Shape class. Here’s that.

```auto
interface Shape {
  void drawShape();
}
class Circle implements Shape {
  float x;
  float y;
  float radius;
  String group;
  boolean visibility;
  Circle(float xpos, float ypos, float r, String grp, boolean v) {
    x = xpos;
    y = ypos;
    radius = r;
    group = grp;
    visibility = v;
  }
  void drawShape() {
    if(saving){
      pdf.ellipse(x, y, radius, radius);
    }else{
      ellipse(x, y, radius, radius);
    }
  }
}
class Square implements Shape {
  float x;
  float y;
  float xx;
  float yy;
  String group;
  boolean visibility;
  Square(float xpos, float ypos, float xxpos, float yypos, String grp, boolean v) {
    x = xpos;
    y = ypos;
    xx = xxpos;
    yy = yypos;

    group = grp;
    visibility = v;
  }
  void drawShape() {
    if(saving){
      pdf.rect(x, y, xx, yy);
    }else{
      rect(x, y, xx, yy);
    }
  }
}

class Line implements Shape {
  float x;
  float y;
  float px;
  float py;
  String group;
  boolean visibility;
  Line(float xpos, float ypos, float pxpos, float pypos, String grp, boolean v) {
    x = xpos;
    y = ypos;
    px = pxpos;
    py = pypos;
    group = grp;
    visibility = v;
  }
  void drawShape() {
    if(saving){
      pdf.line(px, py, x, y);
    }else{
      line(px, py, x, y);
    }
  }
}

```
