Building a digital painting studio from scratch with Processing




A few weeks ago I met the German artist Arno Beck, whose work I find absolutely great. Arno is a painter and deals with the transfer of digital phenomena into the physical world. Inspired by his painting I developed a digital painting software with Processing in this session.
Thanks to johnny_ctrl for the editing!
paintingstudio.pde
PImage[] images;
PGraphics source;
PGraphics target;
PGraphics result;
PGraphics comp;
PGraphics artboard;
PImage buffer;
PImage currImage;
int POSTER_W = 580;
int POSTER_H = 810;
float TILES_X = POSTER_W / 5;
float TILES_Y = POSTER_H / 5;
int sx, sy, sw, sh, dx, dy, dw, dh;
float scalar = 1;
float offsetX = 0;
float offsetY = 0;
float coutoutW = 30;
float threshold = 150;
void setup() {
size(1740, 810);
source = createGraphics(POSTER_W, POSTER_H);
target = createGraphics(POSTER_W, POSTER_H);
result = createGraphics(POSTER_W, POSTER_H);
artboard = createGraphics(900, 900);
comp = createGraphics(POSTER_W, POSTER_H);
images = new PImage[9];
images[0] = loadImage("1.jpg");
images[1] = loadImage("2.jpg");
images[2] = loadImage("3.jpg");
images[3] = loadImage("4.jpg");
images[4] = loadImage("5.jpg");
images[5] = loadImage("6.jpg");
images[6] = loadImage("7.jpg");
images[7] = loadImage("8.jpg");
images[8] = loadImage("9.jpg");
currImage = images[int(random(images.length))];
}
void draw() {
background(#00ff00);
drawSource();
drawTarget();
drawResult();
image(source, 0, 0);
image(target, POSTER_W, 0);
image(result, POSTER_W + POSTER_W, 0);
noFill();
stroke(#00ff00);
strokeWeight(3);
drawArtboard();
rect(mouseX, mouseY, sw, sh);
rect(mouseX + POSTER_W, mouseY, sw, sh);
render();
}
artboard.pde
void drawArtboard() {
artboard.beginDraw();
artboard.background(0);
artboard.imageMode(CENTER);
PImage buffer = target.get();
artboard.image(buffer,artboard.width/2,artboard.height/2);
artboard.endDraw();
}
randomComposition.pde
void randomComposition() {
int padding = 50;
comp.beginDraw();
comp.background(255);
float diameter = random(300);
comp.fill(0);
comp.noStroke();
comp.ellipse(random(padding,POSTER_W-padding), random(padding,POSTER_H-padding), diameter, diameter);
comp.stroke(0);
comp.strokeWeight(8);
comp.strokeCap(RECT);
comp.line(random(padding,POSTER_W-padding), random(padding,POSTER_H-padding), random(padding,POSTER_W-padding), random(padding,POSTER_H-padding));
comp.endDraw();
}
render.pde
void render() {
if (frameCount % 10 == 0) {
artboard.save("out/" + nf(frameCount, 6) + ".png");
}
}
result.pde
void drawResult() {
float tileW = result.width / TILES_X;
float tileH = result.height / TILES_Y;
PImage buffer = target.get();
result.beginDraw();
result.background(#f1f1f1);
result.noStroke();
for (int x = 0; x < TILES_X; x++) {
for (int y = 0; y < TILES_Y; y++) {
int px = int(x*tileW);
int py = int(y*tileH);
color c = buffer.get(px, py);
float b = brightness(c);
if (b < threshold) {
result.fill(0);
} else {
result.fill(#f1f1f1);
}
result.push();
result.translate(x*tileW, y*tileH);
result.rect(0, 0, tileW, tileH);
result.pop();
}
}
result.endDraw();
}
source.pde
void drawSource(){
source.beginDraw();
source.background(0);
source.imageMode(CENTER);
source.push();
source.translate(source.width/2 + offsetX, source.height/2 + offsetY);
source.scale(scalar);
source.image(currImage,0,0);
source.pop();
source.endDraw();
}
target.pde
void drawTarget() {
target.beginDraw();
buffer = source.get();
if (frameCount == 1) {
target.background(#ffffff);
}
sx = mouseX;
sy = mouseY;
sw = int(coutoutW);
sh = int(coutoutW);
dx = mouseX;
dy = mouseY;
dw = int(coutoutW);
dh = int(coutoutW);
if (mousePressed) {
target.copy(buffer, sx, sy, sw, sh, dx, dy, dw, dh);
}
target.endDraw();
}
ui.pde
void keyReleased() {
if (key == '1') {
currImage=images[0];
}
if (key == '2') {
currImage=images[1];
}
if (key == '3') {
currImage=images[2];
}
if (key == '4') {
currImage=images[3];
}
if (key == '5') {
currImage=images[4];
}
if (key == '6') {
currImage=images[5];
}
if (key == '7') {
currImage=images[6];
}
if (key == '8') {
currImage=images[7];
}
if (key == '9') {
currImage=images[8];
}
if (key == 'r') {
scalar = random(1, 5);
offsetX = random(-800, 800);
offsetY = random(-800, 800);
}
if (key == 't') {
randomComposition();
currImage = comp.get();
}
if (key == 'e') {
scalar = 1;
offsetX = 0;
offsetY = 0;
}
}
void mouseWheel(MouseEvent event) {
float e = event.getCount();
coutoutW += e*10;
}
Related
Links
Related
On Teaching
Learning creative coding is difficult. Just like learning to play the piano. Both can fill a lifetime. Both are deep […]
Teaching through the Lens of the Tool – with Prof. John Caserta
On a hot day in the summer of 2024, my friend Cem Eskinazi brought a stack of books to our […]
DJ_Dave – Raving with Code
Sarah, also known as DJ_Dave, writes code to produce rave music. You might say, “Oh, I know that stuff: Algorave! […]
The Story of 128KB
One day in January 2024, I was lethargically scrolling through my Instagram feed on my laptop. And, as so often […]
The Future of Processing – with Raphaël and Stef
I have some really good news: Processing is currently undergoing rapid development! Processing community lead Raphaël de Courville and primary […]
Deconstruction / Reconstruction – Creative Coding with Prof. Stig Møller Hansen
I am more than excited to share this session with Prof. Stig Møller Hansen with you today, whom I would […]
CodeCrafted
When I completed my bachelor’s degree in 2013, coding was considered a marginal topic. There was a dark spirit at […]
My new Podcast “Demystify Technology” is out!
One of the most beautiful books I have ever held in my hands is “Lo–TEK” by Julia Watson, an architect, […]
Click here to login or connect!To view this content, you must be a member of Tim's Patreon at €10 or […]
I am totally thrilled to introduce Nicolas Landrieux to you today. We met a few years ago at one of […]
Raquel Meyers – The Tool is the Message
Let’s begin here: A myriad of new technologies is accelerating our world at a breathtaking pace. I’m not interested in […]
Kit Kuksenok on p5.js 2.0
In 2025, both Processing and p5.js made major leaps forward in the development. I had the great opportunity to speak […]
Diogenes meets Demo Festival
Below is the written version of my talk at DEMO Festival in Amsterdam, January 2025. I’ve also recorded an audio […]
Omid Nemalhabib on Design within Limitations
I met Omid Nemaldhabib quite coincidentally in Rotterdam in 2022. He comes from Tehran and ran a design studio there […]
Hannah Gmeiner on Permacomputing in Graphic Design
In an age of increasing digital consumption, Hannah, a recent visual communication graduate, explored “Permacomputing”—a sustainable approach to technology inspired […]
DEMO 2025 – My Submissions
Limitations have always been playing a major role in my creative work; I was only able to develop my best […]
Tameem Sankari on Creative Coding for Large Media Corporations
In this interview, Copenhagen-based creative director Tameem Sankari shares his journey into Creative Coding, combining Processing, Blender, and Adobe CC. […]
Sam Griffith connects Creative Coding with Enviromentalism
In this post I’d like to introduce you to Sam Griffith, a talented graphic designer based in Detroit, to discuss […]
Throwback: My Talk at Demo Festival 2022
The next edition of the DEMO Festival is already approaching and I am currently developing a brand new talk for […]
Powers of Two – 128kb by Lena Weber
20 = 1 21 = 222 = 323 = 824 = 1625 = 3226 = 6427 = 128 … »In […]
A Call for Coding Designers
This is a call for coding designers. It aims to serve as a proposal and a provocation for creative work […]
p5.js Design Tools Directory
Hi! In this post I’ll collect case studies and direct links to tools that people have built with p5.js and […]
Your 128kb journey starts here! This is a template you can use to start developing your idea within the 128kb […]
In 2022, I spontaneously posted a story on Instagram: If anyone out there is also in Rotterdam, I’d love to […]
The 128kb Framework and its Aesthetic Characteristics
One day in early 2024 I started to experiment with a new idea. I wrote down a set of rules […]
A conversation with Talia Cotton
During OFFF Festival here in Barcelona, many interesting people come around! This interview with Talia Cotton came about almost by […]
Lena Weber about her collaboration with A. G. Cook
Lena: This 10-minute visualiser for A. G. Cooks album teaser featuring my python archive generator, is one of my favourite […]
A conversation with Anna Shams Ili
Hi Anna! It was super nice to meet you at the PCD CPH, I really liked your talk in which […]
Coding Systems: New Workshop Dates!
When I held Martin Lorenz’s new book in my hands and turned it onto its back, I was a little […]
My new writing project “downgrade” is live
Hey folks, I hope you are doing great! You may have already read one or two of my essays that […]
Join the 128kb challenge!
Instagram, Twitter, TikTok… All the main platforms that technically have the required features to connect emerging communies for Creative Coding […]
Ruder Processing Unit by Kevin Koch
In my teaching at universities and in workshops, I have met many very enthusiastic and highly talented people who have […]
A reflection on Processing Community Day Copenhagen 2023
I’ve been travelling a lot in the last few months. Still, it was only during a short stay in Copenhagen […]
Ksawery Kirklewski on his Symphony in Acid
For me, it’s by far the most inspiring project of the last few years: “Symphony in Acid”, a collaboration between […]
Meetup: What is Creative Coding?
Hey you! I hope you are doing good! Today, I‘m announcing a meetup where I’ll try to answer a question […]
A 128KB Export Pipeline
With some help by CoPilot I have coded a Bash script that you can use to convert your animations for […]