Filter

filter() #

Apply convolution mask filter either to the whole quadrille or at specific (row, col) cell.

Observation
Only pixelated quadrille images may be filtered, i.e., those created either with createQuadrille(width, image, true) or createQuadrille(width, image, false).

Examples #

filter(mask) #

(press f to toggle filtered image; m to toggle mask display; and, s to rescale image)

code
let scl = 4;
let mask, quadrille, source, target;
let image;
let numberDisplay;
let displayMask;

function update() {
  const displaySource = !quadrille || quadrille === source;
  source = createQuadrille(2 ** scl, image, false);
  target = source.clone();
  target.filter(mask);
  quadrille = displaySource ? source : target;
}

function preload() {
  image = loadImage('mandrill.png');
}

function setup() {
  createCanvas(512, 512);
  mask = createQuadrille([
    [1 / 256, 4 / 256, 6 / 256, 4 / 256, 1 / 256],
    [4 / 256, 16 / 256, 24 / 256, 16 / 256, 4 / 256],
    [6 / 256, 24 / 256, 36 / 256, 24 / 256, 6 / 256],
    [4 / 256, 16 / 256, 24 / 256, 16 / 256, 4 / 256],
    [1 / 256, 4 / 256, 6 / 256, 4 / 256, 1 / 256]]);
  numberDisplay = ({graphics, value, outline, outlineWeight, cellLength}) => {
    const numberColor = 'magenta';
    const min = 0.0625;
    const max = 0.25;
    colorMode(RGB, 255);
    fill(color(red(numberColor), green(numberColor), blue(numberColor),
               map(value, min, max, 0, 255)));
    rect(0, 0, cellLength, cellLength);
    Quadrille.tileDisplay({ graphics, outline, outlineWeight, cellLength });
  }
  update();
}

function draw() {
  background('#060621');
  if (displayMask) {
    drawQuadrille(mask, { cellLength: width / mask.width, outline: 'magenta',
                          numberDisplay: numberDisplay });
  } else {
    drawQuadrille(quadrille,
                  { cellLength: 512 / (2 ** scl),
                    outlineWeight: 16 / (2 ** scl),
                    outline: quadrille === source ? 'magenta' : 'cyan' });
  }
}

function keyPressed() {
  if (key === 'f') {
    quadrille = quadrille === source ? target : source;
  }
  if (key === 'm') {
    displayMask = !displayMask;
  }
  if (key === 's') {
    scl = scl < 7 ? scl + 1 : 4;
    update();
  }
}

filter(mask, row, col) #

(mouse move to apply filter locally; press r to reset filtered image & s to rescale it)

code
let scl = 4;
let mask, quadrille;
let image;
let numberDisplay;

function preload() {
  image = loadImage('mandrill.png');
}

function setup() {
  createCanvas(512, 512);
  mask = createQuadrille([
    [0.0625, 0.125, 0.0625],
    [0.125, 0.25, 0.125],
    [0.0625, 0.125, 0.0625]]);
  numberDisplay = ({graphics, value, outline, outlineWeight, cellLength}) => {
    const numberColor = 'magenta';
    const min = 0.0625;
    const max = 0.25;
    colorMode(RGB, 255);
    fill(color(red(numberColor), green(numberColor), blue(numberColor),
               map(value, min, max, 0, 255)));
    rect(0, 0, cellLength, cellLength);
    Quadrille.tileDisplay({ graphics, outline, outlineWeight, cellLength });
  }
  quadrille = createQuadrille(2 ** scl, image, false);
}

function draw() {
  background('#060621');
  drawQuadrille(quadrille, { cellLength: 512 / (2 ** scl),
                             outlineWeight: 16 / (2 ** scl) });
  const half_size = (mask.width - 1) / 2;
  drawQuadrille(mask, { col: quadrille.mouseCol - half_size,
                        row: quadrille.mouseRow - half_size,
                        cellLength: 512 / (2 ** scl),
                        outline: 'green',
                        numberDisplay: numberDisplay });
}

function mouseMoved() {
  quadrille.filter(mask, quadrille.mouseRow, quadrille.mouseCol);
  return false;
}

function keyPressed() {
  if (key === 'r') {
    quadrille = createQuadrille(2 ** scl, image);
  }
  if (key === 's') {
    scl = scl < 7 ? scl + 1 : 4;
    quadrille = createQuadrille(2 ** scl, image);
  }
}

Syntax #

filter(mask, [row], [col])

Parameters #

parameterdescription
maskQuadrille: quadrille of numbers representing the convolution mask
rowNumber: cell row coordinate, if undefined applies filter to the whole quadrille
colNumber: cell col coordinate, if undefined applies filter to the whole quadrille