# PGraphics not exporting to PDF

**URL:** <https://discourse.processing.org/t/pgraphics-not-exporting-to-pdf/42081>\
**Category:** Libraries\
**Created:** [May 26, 2023, 5:54pm UTC](https://discourse.processing.org/t/pgraphics-not-exporting-to-pdf/42081 "2023-05-26T17:54:24Z")\
**Posts on this page:** 17\
**Page:** 1

<div class="post-metadata">

**Author:** ![travis.stdenis](https://avatars.discourse-cdn.com/v4/letter/t/67e7ee/32.png) [@travis.stdenis](https://discourse.processing.org/u/travis.stdenis)\
**Post date:** [May 26, 2023, 5:54pm UTC](https://discourse.processing.org/t/pgraphics-not-exporting-to-pdf/42081/1 "2023-05-26T17:54:24Z")

</div>

I have a sketch that I am trying to export to PDF so it can be plotted. I can export to SVG, but it doesn’t preserve any of the underlying vectors graphics, only exports embedded images so it isn’t much use for this application.

Here is the code snippets in question. Full code in a response post below.

I define the size with P2D  
`size(1300, 850, P2D);`

This utility to export to PDF

```auto
if(makePDF){
  docName = timeStamp(docBase);
  beginRecord(PDF, "pdf/" + docName + ".pdf");
}

```

This to define the PGraphics  
`PGraphics img = createGraphics(imgSize, imgSize);`

With these defined I get the expected visual results:

 ![voronoi_arcs_expected_output](https://canada1.discourse-cdn.com/flex036/uploads/processingfoundation1/original/3X/c/5/c53a11ce2430dc9ac46e7516a95798e90ede5a9c.jpeg)

but the following error when I attempt PDF export:

```auto
ClassCastException: class sun.java2d.SunGraphics2D cannot be cast to class java.awt.Image (sun.java2d.SunGraphics2D and java.awt.Image are in module java.desktop of loader 'bootstrap')
ClassCastException: class sun.java2d.SunGraphics2D cannot be cast to class java.awt.Image (sun.java2d.SunGraphics2D and java.awt.Image are in module java.desktop of loader 'bootstrap')

```

If I change the PDF function to the following, the visual is still correct, and the PDF executes without error but the resulting file is blank.

```auto
if(makePDF){
  docName = timeStamp(docBase);
  beginRaw(PDF, "pdf/" + docName + ".pdf");
} 

```

When I change the PGraphics definition to:  
`PGraphics img = createGraphics(imgSize, imgSize, P2D);`

I get this visual result which exports to PDF but obviously useless.

 ![voronoi_arcs_BW_output](https://canada1.discourse-cdn.com/flex036/uploads/processingfoundation1/original/3X/c/a/cacaeec2578c2efe689728383936f5e1afeace1d.jpeg)

So I am at a loss for how to proceed and could use any guidance the community has to offer. Unfortunately, I’ve had to use PGraphics because of the mask feature (arcs clipped by underlying voronoi cell shape), but if there is another way to accomplish the same effect and will export properly, I’m open to that. But for now, I’m hoping to solve for the PDF export.

---

<div class="post-metadata">

**Author:** ![travis.stdenis](https://avatars.discourse-cdn.com/v4/letter/t/67e7ee/32.png) [@travis.stdenis](https://discourse.processing.org/u/travis.stdenis)\
**Post date:** [May 26, 2023, 5:57pm UTC](https://discourse.processing.org/t/pgraphics-not-exporting-to-pdf/42081/2 "2023-05-26T17:57:20Z")

</div>

```auto
import toxi.math.conversion.*;
import toxi.geom.*;
import toxi.math.*;
import toxi.geom.mesh2d.*;
import toxi.util.datatypes.*;
import toxi.util.events.*;
import toxi.geom.mesh.subdiv.*;
import toxi.geom.mesh.*;
import toxi.math.waves.*;
import toxi.util.*;
import toxi.math.noise.*;
import toxi.processing.*;

ToxiclibsSupport gfx;
Voronoi voronoi;

import processing.svg.*;
boolean makeSVG = false;
import processing.pdf.*;
boolean makePDF = false;
String docBase = "voronoi_arcs";
String docName = "";

color bg = color(243, 242, 234);
color[] colorArray = {
  color(39, 225, 193),
  color(14, 162, 147),
  color(47, 15, 93),
  color(65, 42, 98),
  color(107, 36, 95)
};

ArrayList<PVector> pointsList;
ArrayList<Cell> voronCells;
float cellSpace = 100;

void setup() {
  size(1300, 850, P2D);
  background(bg);
  
  gfx = new ToxiclibsSupport(this);
  
  // make a list of the points, evenly distributed around the canvas
  pointsList = new ArrayList<PVector>();
  pointsList = poissonDiskSampling(cellSpace, 30);
  voronCells = new ArrayList<Cell>();
  voronoi = new Voronoi();
  makeVoronoi();
   
  smooth(8);
  //noLoop();
}

void draw() {
  background(bg);
  
  if(makeSVG){
    docName = timeStamp(docBase);
    beginRecord(SVG, "svg/" + docName + ".svg");
  } else{ docName = ""; }
  if(makePDF){
    docName = timeStamp(docBase);
    beginRecord(PDF, "pdf/" + docName + ".pdf");
  } else{ docName = ""; }
  
  for(Cell c : voronCells){
    c.render();
  }
  
if(makeSVG){
    endRecord();
    makeSVG = false;
    saveImage();
  }
  if(makePDF){
    endRecord();
    makePDF = false;
  }
}

void makeVoronoi() {
  // for each of those points now make a voronoi shape then make a corresponding voronoi cell
  for(PVector vec : pointsList){
    voronoi.addPoint(new Vec2D(vec.x, vec.y));
  } 
  
  for(Polygon2D polygon : voronoi.getRegions()) {
    Vec2D polyV = polygon.getCentroid();
    PVector vec = new PVector(0,0);
    if(polyV.x <= 0 || polyV.x >= width || polyV.y <= 0 || polyV.y >= height){
      for(Vec2D v : voronoi.getSites()){
        if(polygon.containsPoint(v)){
          vec.set(v.x, v.y);
        }
      }
    } else{
      vec.set(polyV.x, polyV.y);
    }
    color clr = colorArray[floor(random(colorArray.length))];
    voronCells.add(new Cell(vec, polygon, cellSpace, clr));
  }
}

void keyPressed() {
  if(key == ' ') reset();
  if(key == 'a') saveImage();
  if(key == 's') svgExport();
  if(key == 'd') pdfExport();
}

void reset() {
  background(bg);
  pointsList.clear();
  voronCells.clear();
  
  pointsList = new ArrayList<PVector>();
  pointsList = poissonDiskSampling(cellSpace, 30);
  voronCells = new ArrayList<Cell>();
  voronoi = new Voronoi();
  makeVoronoi();
  //redraw();  
}

void saveImage() {
  if(docName == ""){
    docName = timeStamp(docBase);
  } 
  saveFrame("png/" + docName + ".png");
}

void svgExport() {
  makeSVG = true;
  //redraw();
}

void pdfExport() {
  makePDF = true;
  //redraw();
}

String timeStamp(String name) {
  return name + "-" + year() + nf(month(), 2) + nf(day(), 2) +
    "-" + nf(hour(), 2) + nf(minute(), 2) + nf(second(), 2);
}

class Cell {
  PVector midPt;
  float radius;
  color clrSelect;
  float angle;
  PVector outerPt;
  PVector drawPt;
  PVector boxPt;
  int imgSize;
  float boxCornerRad;
  PGraphics curves;
  PGraphics masker;
  Polygon2D voron;
  
  Cell(PVector thePos, Polygon2D theVoron, float theRad, color theClr) {
    midPt = thePos;
    voron = theVoron;
    radius = theRad;
    clrSelect = theClr;
    angle = random(TWO_PI);
    outerPt = PVector.fromAngle(angle).setMag(radius).add(midPt);
    drawPt = PVector.fromAngle(angle).setMag((radius/2)-5).add(outerPt);
    imgSize = int(radius * 2)+5;
    boxCornerRad = (imgSize * sqrt(2)) / 2;
    boxPt = PVector.fromAngle(PI+QUARTER_PI).setMag(boxCornerRad).add(midPt);
    curves = makeCurves();
    masker = makeMask();
  }

  void render() {
    curves.mask(masker);
    pushMatrix();
    translate(drawPt.x, drawPt.y);
    rotate(angle + HALF_PI + QUARTER_PI);
    image(curves, 0,0);
    popMatrix();
  }
  
  PGraphics makeCurves() {
    PGraphics img = createGraphics(imgSize, imgSize);
    img.beginDraw();
    img.clear();
    img.background(bg);
    img.noFill();
    img.stroke(clrSelect);
    img.strokeWeight(2);
    for(int i=0; i<10; i++){
      float currRad = 40 + (i * 15);
      pushMatrix();
      translate(outerPt.x, outerPt.y);
      img.arc((radius/4), (radius/4), currRad*2, currRad*2, -QUARTER_PI, HALF_PI+QUARTER_PI);
      popMatrix();
    }
    img.endDraw();
    
    return img;
  }
  
  PGraphics makeMask() {
    ArrayList<PVector> voronPositions = new ArrayList<PVector>();
    PVector originOffsetPt = PVector.sub(midPt, boxPt);
    for(int i=0; i<voron.vertices.size(); i++){
      PVector currPt = new PVector(voron.vertices.get(i).x, voron.vertices.get(i).y);
      float distFromCenter = PVector.dist(midPt, currPt) - 5;
      PVector fromCenterPt = PVector.sub(midPt, currPt);
      pushMatrix();
      translate(midPt.x, midPt.y);
      float cornerAng = fromCenterPt.heading();
      popMatrix();
      float xPos = cos(cornerAng + PI - angle - HALF_PI - QUARTER_PI) * distFromCenter;
      float yPos = sin(cornerAng + PI - angle - HALF_PI - QUARTER_PI) * distFromCenter;
      voronPositions.add(new PVector(xPos, yPos));
    }
    
    PGraphics msk = createGraphics(imgSize, imgSize);
    msk.beginDraw();
    msk.clear();
    msk.translate(originOffsetPt.x, originOffsetPt.y);
    msk.beginShape();
    for(int j=0; j<voronPositions.size(); j++){
      msk.vertex(voronPositions.get(j).x, voronPositions.get(j).y);
    }
    msk.endShape(CLOSE);
    msk.endDraw();
    
    return msk;
  }
}

```

---

<div class="post-metadata">

**Author:** ![svan](https://avatars.discourse-cdn.com/v4/letter/s/82dd89/32.png) [@svan](https://discourse.processing.org/u/svan)\
**Post date:** [May 27, 2023, 6:44am UTC](https://discourse.processing.org/t/pgraphics-not-exporting-to-pdf/42081/3 "2023-05-27T06:44:56Z")

</div>

Your posted demo code will not run on my system; `pointsList = poissonDiskSampling(cellSpace, 30);` is not defined.

---

<div class="post-metadata">

**Author:** ![travis.stdenis](https://avatars.discourse-cdn.com/v4/letter/t/67e7ee/32.png) [@travis.stdenis](https://discourse.processing.org/u/travis.stdenis)\
**Post date:** [May 27, 2023, 3:02pm UTC](https://discourse.processing.org/t/pgraphics-not-exporting-to-pdf/42081/4 "2023-05-27T15:02:02Z")

</div>

```auto
// utilities for the point placement
ArrayList<PVector> poissonDiskSampling(float radius, int k) {
  int N = 2;
  /* The final set of points to return */
  ArrayList<PVector> points = new ArrayList<PVector>();
  /* The currently "active" set of points */
  ArrayList<PVector> active = new ArrayList<PVector>();
  /* Initial point p0 */
  PVector p0 = new PVector(random(width), random(height));
  PVector[][] grid;
  float cellsize = floor(radius/sqrt(N));

  /* Figure out no. of cells in the grid for our canvas */
  int ncells_width = ceil(width/cellsize) + 1;
  int ncells_height = ceil(width/cellsize) + 1;

  /* Allocate the grid an initialize all elements to null */
  grid = new PVector[ncells_width][ncells_height];
  for (int i = 0; i < ncells_width; i++)
    for (int j = 0; j < ncells_height; j++)
      grid[i][j] = null;

  insertPoint(grid, cellsize, p0);
  points.add(p0);
  active.add(p0);

  while (active.size() > 0) {
    int random_index = int(random(active.size()));
    PVector p = active.get(random_index);
    
    boolean found = false;
    for (int tries = 0; tries < k; tries++) {
      float theta = random(TWO_PI);
      float new_radius = random(radius, 2*radius);
      float pnewx = p.x + new_radius * cos(theta);
      float pnewy = p.y + new_radius * sin(theta);
      PVector pnew = new PVector(pnewx, pnewy);
      
      if (!isValidPoint(grid, cellsize,
                        ncells_width, ncells_height,
                        pnew, radius))
        continue;
      
      points.add(pnew);
      insertPoint(grid, cellsize, pnew);
      active.add(pnew);
      found = true;
      break;
    }
    
    /* If no point was found after k tries, remove p */
    if (!found)
      active.remove(random_index);
  }

  return points;
}

boolean isValidPoint(PVector[][] grid, float cellsize,
                     int gwidth, int gheight,
                     PVector p, float radius) {
  /* Make sure the point is on the screen */
  if (p.x < 0 || p.x >= width || p.y < 0 || p.y >= height)
    return false;

  /* Check neighboring eight cells */
  int xindex = floor(p.x / cellsize);
  int yindex = floor(p.y / cellsize);
  int i0 = max(xindex - 1, 0);
  int i1 = min(xindex + 1, gwidth - 1);
  int j0 = max(yindex - 1, 0);
  int j1 = min(yindex + 1, gheight - 1);

  for (int i = i0; i <= i1; i++)
    for (int j = j0; j <= j1; j++)
      if (grid[i][j] != null)
        if (dist(grid[i][j].x, grid[i][j].y, p.x, p.y) < radius)
          return false;

  /* If we get here, return true */
  return true;
}

void insertPoint(PVector[][] grid, float cellsize, PVector point) {
  int xindex = floor(point.x / cellsize);
  int yindex = floor(point.y / cellsize);
  grid[xindex][yindex] = point;
}

// function to find the intersection points of circles to define arcs for each cell
// https://gist.github.com/jupdike/bfe5eb23d1c395d8a0a1a4ddd94882ac
PVector[] intersectTwoCircles(float x1, float y1, float r1, float x2, float y2, float r2) {
  PVector[] coords = new PVector[2];
  float centerdx = x1 - x2;
  float centerdy = y1 - y2;
  float R = sqrt(centerdx * centerdx + centerdy * centerdy);
  if(!(abs(r1 - r2) <= R && R <= r1 + r2)){ // no intersection
    return coords; // empty list of results
  }
  // intersection(s) should exist

  float R2 = R*R;
  float R4 = R2*R2;
  float a = (r1*r1 - r2*r2) / (2 * R2);
  float r2r2 = (r1*r1 - r2*r2);
  float c = sqrt(2 * (r1*r1 + r2*r2) / R2 - (r2r2 * r2r2) / R4 - 1);

  float fx = (x1+x2) / 2 + a * (x2 - x1);
  float gx = c * (y2 - y1) / 2;
  float ix1 = fx + gx;
  float ix2 = fx - gx;

  float fy = (y1+y2) / 2 + a * (y2 - y1);
  float gy = c * (x1 - x2) / 2;
  float iy1 = fy + gy;
  float iy2 = fy - gy;
  
  coords[0] = new PVector(ix1, iy1);
  coords[1] = new PVector(ix2, iy2);

  // note if gy == 0 and gx == 0 then the circles are tangent and there is only one solution
  // but that one solution will just be duplicated as the code is currently written
  return coords;
}

```

---

<div class="post-metadata">

**Author:** ![travis.stdenis](https://avatars.discourse-cdn.com/v4/letter/t/67e7ee/32.png) [@travis.stdenis](https://discourse.processing.org/u/travis.stdenis)\
**Post date:** [May 27, 2023, 3:02pm UTC](https://discourse.processing.org/t/pgraphics-not-exporting-to-pdf/42081/5 "2023-05-27T15:02:27Z")

</div>

Apologies. I forgot to copy over the point sampling utilities.

---

<div class="post-metadata">

**Author:** ![svan](https://avatars.discourse-cdn.com/v4/letter/s/82dd89/32.png) [@svan](https://discourse.processing.org/u/svan)\
**Post date:** [May 27, 2023, 6:15pm UTC](https://discourse.processing.org/t/pgraphics-not-exporting-to-pdf/42081/6 "2023-05-27T18:15:02Z")

</div>

The following works on my system:

```auto
  if (key == 'd') {
    beginRecord(PDF, "/Users/xxxxx/Desktop/frame-####.pdf");
    saveFrame("data/" + "curvy" + ".png");
    PImage img = loadImage("curvy.png");
    image(img, 0, 0);
    endRecord();
  }

```

---

<div class="post-metadata">

**Author:** ![glv](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/glv/32/18785_2.png) [@glv](https://discourse.processing.org/u/glv)\
**Post date:** [May 27, 2023, 8:39pm UTC](https://discourse.processing.org/t/pgraphics-not-exporting-to-pdf/42081/7 "2023-05-27T20:39:22Z")

</div>

Hello @travis.stdenis,

This worked with your code and Processing 4.2 on W10:

```auto
PGraphics makeCurves() {
    PGraphics img = createGraphics(imgSize, imgSize, P2D);
    
// Add these two lines:
    img.beginDraw();
    img.endDraw();
    
    img.beginDraw();
    // Your code
    img.endDraw();
    
    return img;
  }

```

Reference explains above additions to code:

> <https://github.com/processing/processing4/issues/641>
>
> \## Description
> Stumbled upon this just now - seems like beginDraw() / endDraw()… clear the canvas of a PGraphics object when that object is created with the P2D renderer.
> 
> \## Expected Behavior
> I expect the beginDraw() method not to change anything in the PGraphics object it's called on.
> 
> \## Current Behavior
> Calling beginDraw() on a PGraphics object created with P2D and populated previously will clear it.
> 
> \## Steps to Reproduce
> 1. Create PGraphics object with P2D renderer
> 2. Draw into the PGraphics object, finish with endDraw()
> 3. Call beginDraw() & endDraw() on the same object again
> 
> \`\`\`
> PGraphics pg;
> 
> void setup()
> {
> size(500, 500, P2D);
> frameRate(60);
>     
> //pg = createGraphics(width, height); // works as expected
> pg = createGraphics(width, height, P2D); // bug with beginDraw()/endDraw(), see below
>   
> pg.beginDraw();
> pg.background(0, 255, 0); // green
> pg.endDraw();
>   
> // this 'empties' the pg object in P2D mode
> pg.beginDraw();
> pg.endDraw();  
>   
> background(255, 0, 0); // red
>   
> // PG w/ P2D: renders transparent image,
> // PG w/ standard renderer: draws the original pg created in setup
> image(pg, 0, 0); 
> }
> \`\`\`
> 
> \## Your Environment
> \* Processing version: 3.5.4
> \* Operating System and OS version: macOS Big Sur 11.4 (20F71)
> \* Other information:

I got the ToxicLibs library directly from link in here:

> <https://github.com/postspectacular/toxiclibs/issues/10>
>
> the issue is as the title.

`:)`

---

<div class="post-metadata">

**Author:** ![travis.stdenis](https://avatars.discourse-cdn.com/v4/letter/t/67e7ee/32.png) [@travis.stdenis](https://discourse.processing.org/u/travis.stdenis)\
**Post date:** [May 28, 2023, 2:33pm UTC](https://discourse.processing.org/t/pgraphics-not-exporting-to-pdf/42081/8 "2023-05-28T14:33:08Z")

</div>

> Please try using createGraphics() in a standalone function to create a pdf file: `PGraphics pdf = createGraphics(width, height, PDF, "/Users/xxxx/Desktop/output.pdf");` Reference: [[PDF Export / Libraries / Processing.org](https://processing.org/reference/libraries/pdf/index.html)] ([PDF Export / Libraries / Processing.org](https://processing.org/reference/libraries/pdf/index.html)) It does not crash on my system. Try to draw the entire final image inside this call.  
> **Addendum:**  
> The following works on my system:

```auto
  if (key == 'd') {
    beginRecord(PDF, "/Users/xxxxx/Desktop/frame-####.pdf");
    saveFrame("data/" + "curvy" + ".png");
    PImage img = loadImage("curvy.png");
    image(img, 0, 0);
    endRecord();
  }

```

Tried this and while the error disappears, the exported PDF is a blank document. Was this the only change you made or did you also change the P2D parameter on the createGraphics() call or something else?

---

<div class="post-metadata">

**Author:** ![travis.stdenis](https://avatars.discourse-cdn.com/v4/letter/t/67e7ee/32.png) [@travis.stdenis](https://discourse.processing.org/u/travis.stdenis)\
**Post date:** [May 28, 2023, 2:35pm UTC](https://discourse.processing.org/t/pgraphics-not-exporting-to-pdf/42081/9 "2023-05-28T14:35:09Z")

</div>

> This worked with your code and Processing 4.2 on W10:

```auto
PGraphics makeCurves() {
    PGraphics img = createGraphics(imgSize, imgSize, P2D);
    
// Add these two lines:
    img.beginDraw();
    img.endDraw();
    
    img.beginDraw();
    // Your code
    img.endDraw();
    
    return img;
  }

```

This worked perfectly. Just to clarify for anyone else seeing this, it is adding the beginDraw() and endDraw() along with the addition of P2D as a parameter to the createGraphics() call.

---

<div class="post-metadata">

**Author:** ![svan](https://avatars.discourse-cdn.com/v4/letter/s/82dd89/32.png) [@svan](https://discourse.processing.org/u/svan)\
**Post date:** [May 28, 2023, 3:10pm UTC](https://discourse.processing.org/t/pgraphics-not-exporting-to-pdf/42081/10 "2023-05-28T15:10:47Z")

</div>

That’s all that I did; no other changes. Works well on my Mac. It works by saving the window frame to a .png image saved into a sketch folder called ‘data’ and then immediately loading the .png into a PImage and recording it into a .pdf. My output is below:

 ![curvy](https://canada1.discourse-cdn.com/flex036/uploads/processingfoundation1/original/3X/e/2/e275c4f7d92864247d182069eb6fb3eb0c37952f.jpeg)

When I tried the Windows fix on my Mac, it changed the background color to pure white instead of the off colored yellow of the original code.

Just curious; what happens if you try to run this code:

```auto
import processing.pdf.*;

void setup() {
  size(500, 500);
  surface.setTitle("Press 'p' for sketch folder pdf");
}

void draw() {
  fill(0);
  circle(width/2, height/2, 300);
}

void keyPressed() {
  if (key == 'p') {
    beginRecord(PDF, "myPDF-####.pdf");
    saveFrame("myPNG.png");
    PImage img = loadImage("myPNG.png");
    image(img, 0, 0);
    endRecord();
    println("pdf file in sketch folder");
  }
}

```

---

<div class="post-metadata">

**Author:** ![glv](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/glv/32/18785_2.png) [@glv](https://discourse.processing.org/u/glv)\
**Post date:** [May 28, 2023, 11:41pm UTC](https://discourse.processing.org/t/pgraphics-not-exporting-to-pdf/42081/11 "2023-05-28T23:41:02Z")

</div>

Hello @travis.stdenis ,

> [@travis.stdenis](#):
>
> adding the beginDraw() and endDraw() along with the addition of P2D as a parameter to the createGraphics() call.

Both of the _createGraphics()_ calls. `:)`

> [@svan](#):
>
> it changed the background color to pure white instead of the off colored yellow of the original code.

@svan,

The background should be applied between record calls to apply to final PDF (also to SVG):

```auto
void draw() 
  {
  //background(bg);
  beginRecord(PDF,"test.pdf");
  
  background(bg); //Background should be here to apply to PDF
  for(Cell c : voronCells)
    {
    c.render();
    }
  endRecord();
  }

```

> [@travis.stdenis](#):
>
> I have a sketch that I am trying to export to PDF so it can be plotted. I can export to SVG, but it doesn’t preserve any of the underlying vectors graphics, only exports embedded images so it isn’t much use for this application.

Check this out:

> [@Processing Geometry Suite](https://discourse.processing.org/t/processing-geometry-suite/29924):
>
> Processing Geometry Suite Hi everyone. I’m pleased to share something I’ve been working on the past few months – a 2D computational geometry that I’ve called Processing Geometry Suite. The focus of the library is on visualisation rather than providing underlying data structures and so all methods in the library are static and most of them take in and return PShapes or PVectors. I’ve made a real effort to make it easy to pick up – it’s well [documented](https://micycle1.github.io/PGS/micycle/pgs/package-summary.html), the Github is replete with gifs illust…

There may be something in there that will allow you to generate your shapes and create a PDF or SVG with [vector graphics](https://en.wikipedia.org/wiki/Vector_graphics) instead of [raster graphics](https://en.wikipedia.org/wiki/Raster_graphics).

I was able to export PDFs (with vector graphics) for one of the examples:

 ![image](https://canada1.discourse-cdn.com/flex036/uploads/processingfoundation1/original/3X/e/b/eb78a401dceefcdd9cc02e88369a95a9a0e7b1dc.jpeg)

`:)`

---

<div class="post-metadata">

**Author:** ![svan](https://avatars.discourse-cdn.com/v4/letter/s/82dd89/32.png) [@svan](https://discourse.processing.org/u/svan)\
**Post date:** [May 29, 2023, 1:22am UTC](https://discourse.processing.org/t/pgraphics-not-exporting-to-pdf/42081/12 "2023-05-29T01:22:07Z")

</div>

There should be no reason why you can’t save the png, pdf, and svg files with one keystroke and remove a lot of your code (presuming this technique works on a Windows system if that’s what you have; works well on a Mac).

```auto
import processing.pdf.*;
import processing.svg.*;

void setup() {
  size(500, 500);
  surface.setTitle("Press 'p' for sketch folder png, pdf, and svg");
}

void draw() {
  fill(0);
  circle(width/2, height/2, 300);
}

void keyPressed() {
  if (key == 'p') {
    saveFrame("myPNG.png");
    PImage img = loadImage("myPNG.png");
    beginRecord(PDF, "myPDF-####.pdf");
    image(img, 0, 0);
    endRecord();
    beginRecord(SVG, "mySVG-####.svg");
    image(img, 0, 0);
    endRecord();
    println("png, pdf, and svg files saved in sketch folder");
  }
}

```

**Sketch folder:**  
 ![tres](https://canada1.discourse-cdn.com/flex036/uploads/processingfoundation1/original/3X/d/e/de15abea90a13555c590d4a1603703fe84a2f17a.png)

---

<div class="post-metadata">

**Author:** ![travis.stdenis](https://avatars.discourse-cdn.com/v4/letter/t/67e7ee/32.png) [@travis.stdenis](https://discourse.processing.org/u/travis.stdenis)\
**Post date:** [May 29, 2023, 5:52pm UTC](https://discourse.processing.org/t/pgraphics-not-exporting-to-pdf/42081/13 "2023-05-29T17:52:11Z")

</div>

Check this out:

> [@](#):
>
> Processing Geometry Suite Hi everyone. I’m pleased to share something I’ve been working on the past few months – a 2D computational geometry that I’ve called Processing Geometry Suite. The focus of the library is on visualisation rather than providing underlying data structures and so all methods in the library are static and most of them take in and return PShapes or PVectors. I’ve made a real effort to make it easy to pick up – it’s well [documented](https://micycle1.github.io/PGS/micycle/pgs/package-summary.html), the Github is replete with gifs illust…

> There may be something in there that will allow you to generate your shapes and create a PDF or SVG with [vector graphics](https://en.wikipedia.org/wiki/Vector_graphics) instead of [raster graphics](https://en.wikipedia.org/wiki/Raster_graphics).

This looks really cool. Thanks for the share. I would have preferred to execute using vector graphics instead of rasters but I needed to clip the curved lines to the voronoi cell shape and PGraphics seemed the only way to accomplish that. I can do this fairly simply with standard geometric shapes given line intersection math, but I didn’t know how I could do it using the non-normal polygon shape. if anyone has ideas, i’m very open to it. Maybe this library will solve that.

---

<div class="post-metadata">

**Author:** ![scudly](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/scudly/32/5597_2.png) [@scudly](https://discourse.processing.org/u/scudly)\
**Post date:** [May 29, 2023, 6:17pm UTC](https://discourse.processing.org/t/pgraphics-not-exporting-to-pdf/42081/14 "2023-05-29T18:17:38Z")

</div>

The problem with this method is that it’s not saving a vector drawing. It is instead saving a fixed resolution pixel image inside a vector image format. It loses the whole point of using a vector format in the first place which is to be resolution independent.

SVG and PDF store path and fill drawing commands independent of output resolution which means that they can later be blown up to whatever resolution you need such as for printing a large poster or issuing smooth drawing commands to a plotter at the native resolution of your output device.

---

<div class="post-metadata">

**Author:** ![svan](https://avatars.discourse-cdn.com/v4/letter/s/82dd89/32.png) [@svan](https://discourse.processing.org/u/svan)\
**Post date:** [May 29, 2023, 7:52pm UTC](https://discourse.processing.org/t/pgraphics-not-exporting-to-pdf/42081/15 "2023-05-29T19:52:46Z")

</div>

Good point, but as far as this thread goes I can’t see that it would make a difference since he is using rasters to begin with.

---

<div class="post-metadata">

**Author:** ![glv](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/glv/32/18785_2.png) [@glv](https://discourse.processing.org/u/glv)\
**Post date:** [May 30, 2023, 9:00am UTC](https://discourse.processing.org/t/pgraphics-not-exporting-to-pdf/42081/16 "2023-05-30T09:00:41Z")

</div>

Hello @travis.stdenis ,

> [@travis.stdenis](#):
>
> if anyone has ideas, i’m very open to it. Maybe this library will solve that.

I was able to do this with the PGS library:

![image](https://canada1.discourse-cdn.com/flex036/uploads/processingfoundation1/original/3X/1/2/12186170500a6c60a046971896ef32f01eeaa12f.png)

```auto
  s2 = PGS_ShapeBoolean.intersect(s1, star);
  PGS_Conversion.setAllStrokeColor(s2, color(0, 255, 0), 2);

```

s1 is a PShape with lines.  
star is a PShape with the star.  
s2 is the _intersect_ PShape and displayed on the right on top of the star PShape with a grey fill.

`:)`

---

<div class="post-metadata">

**Author:** ![travis.stdenis](https://avatars.discourse-cdn.com/v4/letter/t/67e7ee/32.png) [@travis.stdenis](https://discourse.processing.org/u/travis.stdenis)\
**Post date:** [May 30, 2023, 1:03pm UTC](https://discourse.processing.org/t/pgraphics-not-exporting-to-pdf/42081/17 "2023-05-30T13:03:18Z")

</div>

That’s perfect, exactly what i’m looking for. I’ll take a closer look at the library tonight.
