Skip to content

Instantly share code, notes, and snippets.

@volfegan
Created June 25, 2020 23:04
Show Gist options
  • Save volfegan/23c416801a392d17a7aaee60b01bf330 to your computer and use it in GitHub Desktop.
Save volfegan/23c416801a392d17a7aaee60b01bf330 to your computer and use it in GitHub Desktop.
Custom low-pass filter (Blur) filter for Processing
//author Volfegan: https://twitter.com/VolfeganGeist
//resources:
//low-pass filter (Blur) https://processing.org/examples/blur.html
import java.util.UUID;
PImage img;
PImage sortedPixels; //image processed
boolean save = false;
int width = 0;
int height = 0;
String filename;
//there is no file validation, so any non-img selected will crash the program
void fileSelected(File selection) {
if (selection == null) {
println("No image file selected.");
exit();
} else {
String filepath = selection.getAbsolutePath();
filename = selection.getName();
int pos = filename.lastIndexOf(".");
if (pos != -1) filename = filename.substring(0, pos);
println("File selected " + filepath);
// load file here
img = loadImage(filepath);
}
}
void interrupt() {
while (img==null) delay(200);
}
void settings() {
selectInput("Select an image file to process:", "fileSelected");
interrupt(); //interrupt process until img is selected
width = img.width;
height = img.height;
if (width > 1920) {
int resizer = width / 1200;
width = 1200;
height = height / resizer;
img.resize(width, height);
}
if (height > 1080) {
int resizer = height / 900;
height = 900;
width = width / resizer;
img.resize(width, height);
}
//the canvas window size will be according to the img size
size(width, height);
}
void setup() {
// Create an opaque image of the same size as the original
sortedPixels = createImage(img.width, img.height, RGB);
sortedPixels = img.get();
//Blur
sortedPixels = lowPassFilter(sortedPixels);
background(0);
image(sortedPixels, 0, 0);
if (save) {
//save the image with a random id
save("image_"+UUID.randomUUID().toString().replace("-", "")+".png");
}
}
//return a blur PImage
public PImage lowPassFilter(PImage image) {
//low-pass matrix
float v = 1.0 / 9.0;
float[][] kernel = {
{v, v, v},
{v, v, v},
{v, v, v}};
image.loadPixels();
// Create an opaque image of the same size as the original
PImage processedImg = createImage(image.width, image.height, RGB);
for (int y = 0; y < image.height-1; y++) {
for (int x = 0; x < image.width-1; x++) {
//Skip left and right, top and bottom edges to avoid aberations
if (x==0 || y==0 || x==image.width-1 || y==image.height-1) continue;
float sum = 0; // Kernel sum for this pixel
for (int ky = -1; ky <= 1; ky++) {
for (int kx = -1; kx <= 1; kx++) {
// Calculate the adjacent pixel for this kernel point
int pos = (y + ky)*image.width + (x + kx);
// Image is grayscale, red/green/blue are identical
float val = red(image.pixels[pos]);
// Multiply adjacent pixels based on the kernel values
sum += kernel[ky+1][kx+1] * val;
}
}
// For this pixel in the new image, set the gray value
// based on the sum from the kernel
processedImg.pixels[y*image.width + x] = color(sum);
}
}
// State that there are changes to processedImg.pixels[]
processedImg.updatePixels();
return processedImg;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment