Making a book cover! Sketch ---> 300 dpi

Hi!

Trying to make a book with my friends. We’d love to get a really high quality cover. Made a couple sketches on Processing. While the animations are great, we will need to capture a frame into an SVG. Know there are ways to do this but I haven’t been successful in creating something at 300 dpi. Would be very grateful for any help!

Here are the sketches we are working with:

https://www.openprocessing.org/sketch/626873

https://www.openprocessing.org/sketch/616441

Thank you!!!

I’m really not sure if it is possible to do over 72 dpi with computer screen but here’s what I have found to have better quality export file:

//There are different ways to generate high resolution output.
//One can use the PDF export options. Or one could use one of the many
//different ‘hacks’ to create a high resolution copy of the regular draw() loop.
//Here is an example of one such technique.
void saveHiRes(int scaleFactor) {
  PGraphics hires = createGraphics(width*scaleFactor, height*scaleFactor, JAVA2D);
  beginRecord(hires);
  hires.scale(scaleFactor);
  draw();
  endRecord();
  hires.save(file_name+NomfichierImage+".png");
  hires.save(file_name+NomfichierImage+".tif");
}
1 Like

It sounds like you might be interested in the reference example TileImages:

Draws an image larger than the screen, and saves the image as six tiles. The scaleValue variable sets amount of scaling

https://processing.org/examples/tileimages.html

1 Like

Thank you! Maybe paper.js could be a way to get 300 dpi? Don’t have a lot of experience with it, do you?

Wasn’t thinking of tiling but actually didn’t know how to do this before you mentioned it. Thanks!

Gave this a shot:

private static final float IDEAL_FRAME_RATE = 53.3814333f;
// Berkeley coordinates, added and dived by 3 (37.8716° N + 122.2727° W / 3)
ArrayList<MovingShape> movingShapeList = new ArrayList<MovingShape>();
color backgroundColor, strokeColor;

void setup() {
  size(640, 640);
  smooth(38);
// NYC coordinates, added and dived by 3 (40.7128° N + 74.0060° W / 3)
//Round down to 38 since smooth(int) requires whole number
  rectMode(CENTER);
  ellipseMode(CENTER);

  backgroundColor = color(0);
  strokeColor = color(255);
  noFill();
  strokeWeight(.0005f);
  stroke(strokeColor);

  initialize();
}

void draw() {
  for (MovingShape currentObject : movingShapeList) { 
    currentObject.run();
  }
}

void mousePressed() {
  initialize();
}

void initialize() {
  background(backgroundColor);

  movingShapeList.clear();
  for (int i = 0; i < 3; i++) {
    movingShapeList.add(new MovingShape());
  }
}



class MovingShape {
  final PositionController currentPositionController;
  final AngleController currentDirectionAngleController;
  final AngleController currentRotationAngleController;
  final ValueController currentObjectSizeController;
  final ShapeDisplayController currentShapeDisplayer;

  MovingShape() {
    currentDirectionAngleController = new AngleController(true);
    currentRotationAngleController = new AngleController(false);
    currentPositionController = new PositionController(currentDirectionAngleController);
    currentObjectSizeController = new ValueController(max(width, height) * 0.1f, max(width, height));
    currentShapeDisplayer = new ShapeDisplayController(currentPositionController, currentRotationAngleController, currentObjectSizeController);
  }

  void run() {
    currentDirectionAngleController.run();
    currentRotationAngleController.run();
    currentObjectSizeController.run();
    currentPositionController.run();

    currentShapeDisplayer.run();
  }
}


abstract class Controller {
  int properFrameCount;
  
  void run() {
    properFrameCount++;
  }
}

final class PositionController extends Controller {
  final AngleController directionAngleController;
  public float xPosition, yPosition;
  final float speed;

  PositionController(AngleController c) {
    directionAngleController = c;
    xPosition = random(width * 0.025f, width * 0.075f);
    yPosition = random(height * 0.025f, height * 0.075f);

    speed = 23.1318667f;
    // NYC coordinates, added and dived by 3 (33.8938° N + 35.5018° E / 3)
  }

  void run() {
    super.run();

    xPosition += speed * cos(directionAngleController.angle);
    yPosition += speed * sin(directionAngleController.angle);

    if (xPosition > width || xPosition < 0f) directionAngleController.angle = PI - directionAngleController.angle;
    if (yPosition > height || yPosition < 0f) directionAngleController.angle = -directionAngleController.angle;
  }
}

class AngleController extends Controller {
  public float angle;
  float angleVelocity;
  float angleAcceleration;
  final float maxAngleVelocity = TWO_PI / IDEAL_FRAME_RATE;
  final float maxAngleAcceleration = TWO_PI / sq(IDEAL_FRAME_RATE);

  final boolean angleChanges;
  final boolean angleVelocityChanges;
  final boolean angleChangesInterMittently;

  AngleController(boolean enableIntermittent) {
    angleChanges = (random(1f) < 0.7f);
    angleVelocityChanges = (random(1f) < 0.7f);
    
    if (enableIntermittent) angleChangesInterMittently = (random(1f) < 0.5f);
    else angleChangesInterMittently = false;

    angle = random(TWO_PI);
    if (angleChanges) angleVelocity = random(-maxAngleVelocity, maxAngleVelocity);
    if (angleVelocityChanges) angleAcceleration = random(maxAngleAcceleration);
  }
  AngleController() {
    this(false);
  }
  
  void run() {
    properFrameCount++;
    if (angleChanges == false) return;
    if (angleChangesInterMittently) if (properFrameCount % int(IDEAL_FRAME_RATE) != 0) return;
    
    if (angleChangesInterMittently) angle += constrain((angleVelocity * IDEAL_FRAME_RATE) % TWO_PI, QUARTER_PI, TWO_PI - QUARTER_PI);
    else angle += angleVelocity;

    if (angleVelocityChanges == false) return;
    angleVelocity += angleAcceleration;
    if (angleVelocity > maxAngleVelocity || angleVelocity < -maxAngleVelocity) {
      angleAcceleration = -angleAcceleration;
    }
  }
}

class ValueController extends Controller {
  public float value;
  float valueChangeRate;
  final float minValue;
  final float maxValue;
  final float maxValueChangeRate;

  final boolean valueChanges;
  
  int properFrameCount;

  ValueController(float minVal, float maxVal) {
    valueChanges = (random(1f) < 0.7f);

    minValue = minVal;
    maxValue = maxVal;
    value = random(max(maxValue * 0.1f, minValue), max(maxValue * 0.5f, minValue));

    maxValueChangeRate = maxValue / IDEAL_FRAME_RATE;
    if (valueChanges) valueChangeRate = random(maxValueChangeRate);
  }

  void run() {
    super.run();
    if (valueChanges == false) return;
    
    value += valueChangeRate;
    if (value > maxValue || value < minValue) valueChangeRate = -valueChangeRate;
  }
}



class ShapeDisplayController extends Controller {
  final PositionController position;
  final AngleController rotation;
  final ValueController objectSize;
  final int shapeTypeNumber;
  final float shapeParameter;

  ShapeDisplayController(PositionController pos, AngleController rot, ValueController obj) {
    position = pos;
    rotation = rot;
    objectSize = obj;
    shapeTypeNumber = int(random(4f));

    switch(shapeTypeNumber) {
    case 1:  // ellipse
    case 2:  // recatngle
      shapeParameter = random(1f, 1.7f);
      break;
    default:
      shapeParameter = 0f;
      break;
    }
  }

  void run() {
    super.run();
    
    pushMatrix();
    translate(position.xPosition, position.yPosition);
    rotate(rotation.angle);

    switch(shapeTypeNumber) {
    case 0: 
      drawLine(objectSize.value);
      break;
    case 1: 
      drawEllipse(objectSize.value);
      break;
    case 2: 
      drawRectangle(objectSize.value);
      break;
    case 3: 
      drawTriangle(objectSize.value);
      break;
    }

    popMatrix();
  }

  void drawLine(float objectSize) {
    line(-objectSize * 0.5f, -objectSize * 0.5f, objectSize * 0.5f, objectSize * 0.5f);
  }
  void drawEllipse(float objectSize) {
    ellipse(0f, 0f, objectSize, objectSize * shapeParameter);
  }
  void drawRectangle(float objectSize) {
    rect(0f, 0f, objectSize, objectSize * shapeParameter);
  }
  void drawTriangle(float objectSize) {
    triangle(objectSize / sqrt(3f), 0f, -objectSize/(2f * sqrt(3f)), objectSize / 2f, -objectSize / (2f * sqrt(3)), -objectSize / 2f);
  }
void keyPressed() {
  if (key == 's') {
    save("normal.png");
    saveHiRes(5);
    exit();
  }
}
 
void saveHiRes(int scaleFactor) {
  PGraphics hires = createGraphics(width*scaleFactor, height*scaleFactor, JAVA2D); // CREATION OF 2D PGRAPHICS OBJECT
  beginRecord(hires);
  hires.scale(scaleFactor);
  draw();
  endRecord();
  hires.save("hires.png");
}
}

Still having trouble. Not sure if files are being saved. Can’t find them. Am I doing something wrong?

Please edit your post and format code w highlight plus </> button.

First, did you try the example sketch I shared, and did that work for you? Can you see those images saved in the sketch folder?

hey @jeremydouglass! thanks for your help. tried to follow along with the tile example. still can’t seem to get it. ideally, i’d like every frame to be saved as a high res image until the animation stops playing (or for seconds). with what i’ve done so far, this does not seem to be happening. any ideas?


// Berkeley coordinates, added and dived by 3 (37.8716° N + 122.2727° W / 3)
ArrayList<MovingShape> movingShapeList = new ArrayList<MovingShape>();
color backgroundColor, strokeColor;

void setup() {
  size(640, 640);
  smooth(38);
// NYC coordinates, added and dived by 3 (40.7128° N + 74.0060° W / 3)
//Round down to 38 since smooth(int) requires whole number
  rectMode(CENTER);
  ellipseMode(CENTER);

  backgroundColor = color(0);
  strokeColor = color(255);
  noFill();
  strokeWeight(.0005f);
  stroke(strokeColor);

  initialize();
}

void draw() {
  for (MovingShape currentObject : movingShapeList) { 
    currentObject.run();
  }
}

void mousePressed() {
  initialize();
}

void initialize() {
  background(backgroundColor);

  movingShapeList.clear();
  for (int i = 0; i < 3; i++) {
    movingShapeList.add(new MovingShape());
  }
}



class MovingShape {
  final PositionController currentPositionController;
  final AngleController currentDirectionAngleController;
  final AngleController currentRotationAngleController;
  final ValueController currentObjectSizeController;
  final ShapeDisplayController currentShapeDisplayer;

  MovingShape() {
    currentDirectionAngleController = new AngleController(true);
    currentRotationAngleController = new AngleController(false);
    currentPositionController = new PositionController(currentDirectionAngleController);
    currentObjectSizeController = new ValueController(max(width, height) * 0.1f, max(width, height));
    currentShapeDisplayer = new ShapeDisplayController(currentPositionController, currentRotationAngleController, currentObjectSizeController);
  }

  void run() {
    currentDirectionAngleController.run();
    currentRotationAngleController.run();
    currentObjectSizeController.run();
    currentPositionController.run();

    currentShapeDisplayer.run();
  }
}


abstract class Controller {
  int properFrameCount;
  
  void run() {
    properFrameCount++;
  }
}

final class PositionController extends Controller {
  final AngleController directionAngleController;
  public float xPosition, yPosition;
  final float speed;

  PositionController(AngleController c) {
    directionAngleController = c;
    xPosition = random(width * 0.025f, width * 0.075f);
    yPosition = random(height * 0.025f, height * 0.075f);

    speed = 23.1318667f;
    // NYC coordinates, added and dived by 3 (33.8938° N + 35.5018° E / 3)
  }

  void run() {
    super.run();

    xPosition += speed * cos(directionAngleController.angle);
    yPosition += speed * sin(directionAngleController.angle);

    if (xPosition > width || xPosition < 0f) directionAngleController.angle = PI - directionAngleController.angle;
    if (yPosition > height || yPosition < 0f) directionAngleController.angle = -directionAngleController.angle;
  }
}

class AngleController extends Controller {
  public float angle;
  float angleVelocity;
  float angleAcceleration;
  final float maxAngleVelocity = TWO_PI / IDEAL_FRAME_RATE;
  final float maxAngleAcceleration = TWO_PI / sq(IDEAL_FRAME_RATE);

  final boolean angleChanges;
  final boolean angleVelocityChanges;
  final boolean angleChangesInterMittently;

  AngleController(boolean enableIntermittent) {
    angleChanges = (random(1f) < 0.7f);
    angleVelocityChanges = (random(1f) < 0.7f);
    
    if (enableIntermittent) angleChangesInterMittently = (random(1f) < 0.5f);
    else angleChangesInterMittently = false;

    angle = random(TWO_PI);
    if (angleChanges) angleVelocity = random(-maxAngleVelocity, maxAngleVelocity);
    if (angleVelocityChanges) angleAcceleration = random(maxAngleAcceleration);
  }
  AngleController() {
    this(false);
  }
  
  void run() {
    properFrameCount++;
    if (angleChanges == false) return;
    if (angleChangesInterMittently) if (properFrameCount % int(IDEAL_FRAME_RATE) != 0) return;
    
    if (angleChangesInterMittently) angle += constrain((angleVelocity * IDEAL_FRAME_RATE) % TWO_PI, QUARTER_PI, TWO_PI - QUARTER_PI);
    else angle += angleVelocity;

    if (angleVelocityChanges == false) return;
    angleVelocity += angleAcceleration;
    if (angleVelocity > maxAngleVelocity || angleVelocity < -maxAngleVelocity) {
      angleAcceleration = -angleAcceleration;
    }
  }
}

class ValueController extends Controller {
  public float value;
  float valueChangeRate;
  final float minValue;
  final float maxValue;
  final float maxValueChangeRate;

  final boolean valueChanges;
  
  int properFrameCount;

  ValueController(float minVal, float maxVal) {
    valueChanges = (random(1f) < 0.7f);

    minValue = minVal;
    maxValue = maxVal;
    value = random(max(maxValue * 0.1f, minValue), max(maxValue * 0.5f, minValue));

    maxValueChangeRate = maxValue / IDEAL_FRAME_RATE;
    if (valueChanges) valueChangeRate = random(maxValueChangeRate);
  }

  void run() {
    super.run();
    if (valueChanges == false) return;
    
    value += valueChangeRate;
    if (value > maxValue || value < minValue) valueChangeRate = -valueChangeRate;
  }
}



class ShapeDisplayController extends Controller {
  final PositionController position;
  final AngleController rotation;
  final ValueController objectSize;
  final int shapeTypeNumber;
  final float shapeParameter;

  ShapeDisplayController(PositionController pos, AngleController rot, ValueController obj) {
    position = pos;
    rotation = rot;
    objectSize = obj;
    shapeTypeNumber = int(random(4f));

    switch(shapeTypeNumber) {
    case 1:  // ellipse
    case 2:  // recatngle
      shapeParameter = random(1f, 1.7f);
      break;
    default:
      shapeParameter = 0f;
      break;
    }
  }

  void run() {
    super.run();
    
    pushMatrix();
    translate(position.xPosition, position.yPosition);
    rotate(rotation.angle);

    switch(shapeTypeNumber) {
    case 0: 
      drawLine(objectSize.value);
      break;
    case 1: 
      drawEllipse(objectSize.value);
      break;
    case 2: 
      drawRectangle(objectSize.value);
      break;
    case 3: 
      drawTriangle(objectSize.value);
      break;
    }

    popMatrix();
  }

  void drawLine(float objectSize) {
    line(-objectSize * 0.5f, -objectSize * 0.5f, objectSize * 0.5f, objectSize * 0.5f);
  }
  void drawEllipse(float objectSize) {
    ellipse(0f, 0f, objectSize, objectSize * shapeParameter);
  }
  void drawRectangle(float objectSize) {
    rect(0f, 0f, objectSize, objectSize * shapeParameter);
  }
  void drawTriangle(float objectSize) {
    triangle(objectSize / sqrt(3f), 0f, -objectSize/(2f * sqrt(3f)), objectSize / 2f, -objectSize / (2f * sqrt(3)), -objectSize / 2f);
  }
  void saveHiRes(int scaleFactor) {
  PGraphics hires = createGraphics(width*scaleFactor, height*scaleFactor, JAVA2D);
  beginRecord(hires);
  hires.scale(scaleFactor);
  draw();
  endRecord();
  hires.save("SCREEN11.png");
  hires.save("SCREEN11.tif");
  saveFrame("file_####.png");
}
}