# Image filter gets stronger every loop - p5.js

**URL:** <https://discourse.processing.org/t/image-filter-gets-stronger-every-loop-p5-js/35641>\
**Category:** Coding Questions\
**Tags:** homework\
**Created:** [March 9, 2022, 1:47pm UTC](https://discourse.processing.org/t/image-filter-gets-stronger-every-loop-p5-js/35641 "2022-03-09T13:47:51Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![emihardej](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/emihardej/32/15862_2.png) [@emihardej](https://discourse.processing.org/u/emihardej)\
**Post date:** [March 9, 2022, 1:47pm UTC](https://discourse.processing.org/t/image-filter-gets-stronger-every-loop-p5-js/35641/1 "2022-03-09T13:47:52Z")

</div>

I have made my own image filters sepia and blur. When the mouse is clicked on the original (left) image, it is meant to create a radial blur effect on the processed (right) image. However, after testing it I have found that it only works if I have my mouse over the picture as it’s loading. Then, if I click my mouse, the original picture is processed and it looks like the filter gets stronger on the already processed image to the right like it gets another filter applied on top. This continues the more I click. Would anyone have an idea of what I’ve done wrong? I’m not sure where the issue with my code is.

```
var imgIn;

function preload() {
    imgIn = loadImage("https://media.makeameme.org/created/doesnt-know-why-gxsyb3.jpg");
}
function setup() {
    createCanvas((imgIn.width * 2), imgIn.height);
}
function draw() {
    background(125);
    image(imgIn, 0, 0);
    image(earlyBirdFilter(imgIn), imgIn.width, 0);
    noLoop();
}
function mousePressed(){
  loop();
}
function earlyBirdFilter(img){
  var resultImg = createImage(img.width, img.height);

  resultImg = sepiaFilter(img);
  resultImg = darkCorners(resultImg);
  resultImg = radialBlurFilter(resultImg);
  resultImg = borderFilter(resultImg)

  resultImg.updatePixels();
  return resultImg;
}

function sepiaFilter(input){
  input.loadPixels();

  for (var x = 0 ; x < input.width; x++){
    for (var y = 0 ; y <input.height; y++){
      var index = (y*input.width + x) * 4;

      var oldRed = input.pixels[index+0];
      var oldGreen = input.pixels[index+1];
      var oldBlue = input.pixels[index+2];

      var newRed = (oldRed * .393) + (oldGreen *.769) + (oldBlue * .189)
      var newGreen = (oldRed * .349) + (oldGreen *.686) + (oldBlue * .168)
      var newBlue = (oldRed * .272) + (oldGreen *.534) + (oldBlue * .131)

      input.pixels[index +0] = newRed;
      input.pixels[index +1] = newGreen;
      input.pixels[index +2] = newBlue;
      input.pixels[index +3] = 255;
      
    }
  }
  input.updatePixels();
  return input;
  
}
function radialBlurFilter(input){
  var matrixSize = matrix.length;

  input.loadPixels();

for (var x = 0; x < input.width; x++) {
  for (var y = 0; y < input.height; y++) {

      var index = (x + y * input.width) * 4;
      var c = convolution(x, y, matrix, matrixSize, input);
      var d = dist(mouseX, mouseY, x, y);
      var m = map(d, 100, 300, 0, 1);
      var dynBlur = constrain(m ,0, 1);
      var r = input.pixels[index+0];
      var g = input.pixels[index+1];
      var b = input.pixels[index+2];

      input.pixels[index + 0] = c[0]*dynBlur + r*(1-dynBlur);
      input.pixels[index + 1] = c[1]*dynBlur + g*(1-dynBlur);
      input.pixels[index + 2] = c[2]*dynBlur + b*(1-dynBlur);
      input.pixels[index + 3] = 255;
  }
}
  input.updatePixels();
  return input;
}
```

---

<div class="post-metadata">

**Author:** ![GoToLoop](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/gotoloop/32/86_2.png) [@GoToLoop](https://discourse.processing.org/u/GoToLoop)\
**Post date:** [March 9, 2022, 2:15pm UTC](https://discourse.processing.org/t/image-filter-gets-stronger-every-loop-p5-js/35641/2 "2022-03-09T14:15:58Z")

</div>

> [@emihardej](#):
>
> … the filter gets stronger on the already processed image to the right…

I guess you should make a clone of the original image before processing it:

- [reference | p5.js](http://p5js.org/reference/#/p5.Image/get)

```auto
function draw() {
  const imgClone = imgIn.get();

  background(125);
  image(imgClone, 0, 0);
  image(earlyBirdFilter(imgClone), imgClone.width, 0);
}

```

---

<div class="post-metadata">

**Author:** ![GoToLoop](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/gotoloop/32/86_2.png) [@GoToLoop](https://discourse.processing.org/u/GoToLoop)\
**Post date:** [March 10, 2022, 9:55pm UTC](https://discourse.processing.org/t/image-filter-gets-stronger-every-loop-p5-js/35641/4 "2022-03-10T21:55:28Z")

</div>

I’m a little concerned about that many p5.Image cloning at each **draw()** iteration at 60 FPS. 😨

Each time we use **createImage()**, **loadImage()** or clone it via its method **get()**, we also create a heavy `<canvas>` element:

> **[: The Graphics Canvas element - HTML: HyperText Markup Language | MDN](https://developer.Mozilla.org/en-US/docs/Web/HTML/Element/canvas)**
>
> Use the HTML element with either the canvas scripting API or the WebGL API to draw graphics and animations.

We could instead have 2 p5.Image variables for the original & its clone, and then just transfer the original’s _pixels[]_ to the clone’s _pixels[]_ by calling method **set()**:

```auto
function transferImage(src, tgt) {
  tgt.pixels.set(src.pixels);
  tgt.updatePixels();
  return tgt;
}

```

> **[TypedArray.prototype.set() - JavaScript | MDN](https://developer.Mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/set)**
>
> The set() method stores multiple values in the typed
> array, reading input values from a specified array.

This way we avoid creating p5.Image/`<canvas>` unneeded objects all the time. 💡

```javascript
// https://Discourse.Processing.org/t/
// image-filter-gets-stronger-every-loop-p5-js/35641/4

// (2022-Mar-10)

'use strict';

const
  HTTP = 'https://',
  SITE = 'media.MakeAMeme.org/',
  FOLDER = 'created/',
  FILE = 'doesnt-know-why-gxsyb3',
  EXT = '.jpg',
  FILENAME = HTTP + SITE + FOLDER + FILE + EXT;

var imgIn, imgClone;

function preload() {
  imgIn = loadImage(FILENAME, img => {
    imgClone = img.get();
    img.loadPixels();
    imgClone.loadPixels();
  });
}

function setup() {
  createCanvas(imgIn.width << 1, imgIn.height).mousePressed(redraw);
  noLoop();
}

function draw() {
  background(125);
  image(transferImage(imgIn, imgClone), 0, 0);
  image(earlyBirdFilter(imgClone), imgIn.width, 0);
}

function transferImage(src, tgt) {
  tgt.pixels.set(src.pixels);
  tgt.updatePixels();
  return tgt;
}

function earlyBirdFilter(img) {
  borderFilter(radialBlurFilter(darkCorners(sepiaFilter(img)))).updatePixels();
  return img;
}

function sepiaFilter(img) {
  // blah, blah, blah...
  return img;
}

function darkCorners(img) {
  // blah, blah, blah...
  return img;
}

function radialBlurFilter(img) {
  // blah, blah, blah...
  return img;
}

function borderFilter(img) {
  // blah, blah, blah...
  return img;
}

```
