From 84d4d0cfe86ed70dd0ae37a4232e5b51b6fd4bed Mon Sep 17 00:00:00 2001 From: Papershine Date: Sat, 3 Feb 2024 18:32:47 -0800 Subject: [PATCH 1/8] account for pixel density in image mask --- src/image/p5.Image.js | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/src/image/p5.Image.js b/src/image/p5.Image.js index ed14116070..164feaa650 100644 --- a/src/image/p5.Image.js +++ b/src/image/p5.Image.js @@ -878,21 +878,22 @@ p5.Image = class { } const currBlend = this.drawingContext.globalCompositeOperation; - let scaleFactor = 1; + let imgScaleFactor = this._pixelDensity; + let maskScaleFactor = 1; if (p5Image instanceof p5.Renderer) { - scaleFactor = p5Image._pInst._pixelDensity; + maskScaleFactor = p5Image._pInst._pixelDensity; } const copyArgs = [ p5Image, 0, 0, - scaleFactor * p5Image.width, - scaleFactor * p5Image.height, + maskScaleFactor * p5Image.width, + maskScaleFactor * p5Image.height, 0, 0, - this.width, - this.height + imgScaleFactor * this.width, + imgScaleFactor * this.height ]; this.drawingContext.globalCompositeOperation = 'destination-in'; @@ -907,8 +908,8 @@ p5.Image = class { this.gifProperties.frames[i].image = this.drawingContext.getImageData( 0, 0, - this.width, - this.height + imgScaleFactor * this.width, + imgScaleFactor * this.height ); } this.drawingContext.putImageData( From 23ad4f4606f786f50b8bb31f2707aab356ce4129 Mon Sep 17 00:00:00 2001 From: Papershine Date: Sun, 4 Feb 2024 19:30:35 -0800 Subject: [PATCH 2/8] account for mask pixeldensity --- src/image/p5.Image.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/image/p5.Image.js b/src/image/p5.Image.js index 164feaa650..f7cb5219af 100644 --- a/src/image/p5.Image.js +++ b/src/image/p5.Image.js @@ -883,6 +883,11 @@ p5.Image = class { if (p5Image instanceof p5.Renderer) { maskScaleFactor = p5Image._pInst._pixelDensity; } + if (p5Image instanceof p5.Image) { + maskScaleFactor = p5Image._pixelDensity; + } + console.log('mask density ' + maskScaleFactor + ' image density ' + imgScaleFactor); + maskScaleFactor /= imgScaleFactor; const copyArgs = [ p5Image, From 2e2abf521777d53b8b9927119b60ccc567677ff0 Mon Sep 17 00:00:00 2001 From: Papershine Date: Sun, 4 Feb 2024 19:32:16 -0800 Subject: [PATCH 3/8] remove debug info --- src/image/p5.Image.js | 1 - 1 file changed, 1 deletion(-) diff --git a/src/image/p5.Image.js b/src/image/p5.Image.js index f7cb5219af..fbe183a1ae 100644 --- a/src/image/p5.Image.js +++ b/src/image/p5.Image.js @@ -886,7 +886,6 @@ p5.Image = class { if (p5Image instanceof p5.Image) { maskScaleFactor = p5Image._pixelDensity; } - console.log('mask density ' + maskScaleFactor + ' image density ' + imgScaleFactor); maskScaleFactor /= imgScaleFactor; const copyArgs = [ From f841abb90704b3d41bcf1b89c869047573931204 Mon Sep 17 00:00:00 2001 From: Papershine Date: Tue, 30 Apr 2024 15:56:52 -0700 Subject: [PATCH 4/8] test higher pixel densities in mask --- test/unit/image/p5.Image.js | 54 ++++++++++++++++++++----------------- 1 file changed, 29 insertions(+), 25 deletions(-) diff --git a/test/unit/image/p5.Image.js b/test/unit/image/p5.Image.js index 0e44d84a29..c456334534 100644 --- a/test/unit/image/p5.Image.js +++ b/test/unit/image/p5.Image.js @@ -51,36 +51,40 @@ suite('p5.Image', function() { }); suite('p5.Image.prototype.mask', function() { - test('it should mask the image', function() { - let img = myp5.createImage(10, 10); - img.loadPixels(); - for (let i = 0; i < img.height; i++) { - for (let j = 0; j < img.width; j++) { - let alpha = i < 5 ? 255 : 0; - img.set(i, j, myp5.color(0, 0, 0, alpha)); + for (const density of [1, 2]) { + test(`it should mask the image at pixel density ${density}`, function() { + let img = myp5.createImage(10, 10); + img.pixelDensity(density); + img.loadPixels(); + for (let i = 0; i < img.height; i++) { + for (let j = 0; j < img.width; j++) { + let alpha = i < 5 ? 255 : 0; + img.set(i, j, myp5.color(0, 0, 0, alpha)); + } } - } - img.updatePixels(); + img.updatePixels(); - let mask = myp5.createImage(10, 10); - mask.loadPixels(); - for (let i = 0; i < mask.width; i++) { - for (let j = 0; j < mask.height; j++) { - let alpha = j < 5 ? 255 : 0; - mask.set(i, j, myp5.color(0, 0, 0, alpha)); + let mask = myp5.createImage(10, 10); + mask.pixelDensity(density); + mask.loadPixels(); + for (let i = 0; i < mask.width; i++) { + for (let j = 0; j < mask.height; j++) { + let alpha = j < 5 ? 255 : 0; + mask.set(i, j, myp5.color(0, 0, 0, alpha)); + } } - } - mask.updatePixels(); + mask.updatePixels(); - img.mask(mask); - img.loadPixels(); - for (let i = 0; i < img.width; i++) { - for (let j = 0; j < img.height; j++) { - let alpha = i < 5 && j < 5 ? 255 : 0; - assert.strictEqual(img.get(i, j)[3], alpha); + img.mask(mask); + img.loadPixels(); + for (let i = 0; i < img.width; i++) { + for (let j = 0; j < img.height; j++) { + let alpha = i < 5 && j < 5 ? 255 : 0; + assert.strictEqual(img.get(i, j)[3], alpha); + } } - } - }); + }); + } test('it should mask the animated gif image', function() { const imagePath = 'unit/assets/nyan_cat.gif'; From 11519b6b095f13d22146f3bb2ab13d7a1bdc04dd Mon Sep 17 00:00:00 2001 From: Papershine Date: Tue, 30 Apr 2024 17:19:19 -0700 Subject: [PATCH 5/8] fix and test masking with different densities --- src/image/p5.Image.js | 7 ++----- test/unit/image/p5.Image.js | 35 ++++++++++++++++++++++++++++++++++- 2 files changed, 36 insertions(+), 6 deletions(-) diff --git a/src/image/p5.Image.js b/src/image/p5.Image.js index fbe183a1ae..f048b0822e 100644 --- a/src/image/p5.Image.js +++ b/src/image/p5.Image.js @@ -846,7 +846,8 @@ p5.Image = class { * Masks part of an image from displaying by loading another * image and using its alpha channel as an alpha channel for * this image. Masks are cumulative, once applied to an image - * object, they cannot be removed. + * object, they cannot be removed. If the mask has a different + * pixel density from this image, the mask will be scaled * * @method mask * @param {p5.Image} srcImage source image. @@ -883,10 +884,6 @@ p5.Image = class { if (p5Image instanceof p5.Renderer) { maskScaleFactor = p5Image._pInst._pixelDensity; } - if (p5Image instanceof p5.Image) { - maskScaleFactor = p5Image._pixelDensity; - } - maskScaleFactor /= imgScaleFactor; const copyArgs = [ p5Image, diff --git a/test/unit/image/p5.Image.js b/test/unit/image/p5.Image.js index c456334534..7ba41a55d7 100644 --- a/test/unit/image/p5.Image.js +++ b/test/unit/image/p5.Image.js @@ -50,7 +50,7 @@ suite('p5.Image', function() { }); }); - suite('p5.Image.prototype.mask', function() { + suite.only('p5.Image.prototype.mask', function() { for (const density of [1, 2]) { test(`it should mask the image at pixel density ${density}`, function() { let img = myp5.createImage(10, 10); @@ -86,6 +86,39 @@ suite('p5.Image', function() { }); } + test('it should mask images of different density', function() { + let img = myp5.createImage(10, 10); + img.pixelDensity(1); + img.loadPixels(); + for (let i = 0; i < img.height; i++) { + for (let j = 0; j < img.width; j++) { + let alpha = i < 5 ? 255 : 0; + img.set(i, j, myp5.color(0, 0, 0, alpha)); + } + } + img.updatePixels(); + + let mask = myp5.createImage(20, 20); + mask.loadPixels(); + for (let i = 0; i < mask.width; i++) { + for (let j = 0; j < mask.height; j++) { + let alpha = j < 10 ? 255 : 0; + mask.set(i, j, myp5.color(0, 0, 0, alpha)); + } + } + mask.updatePixels(); + mask.pixelDensity(2); + + img.mask(mask); + img.loadPixels(); + for (let i = 0; i < img.width; i++) { + for (let j = 0; j < img.height; j++) { + let alpha = i < 5 && j < 5 ? 255 : 0; + assert.strictEqual(img.get(i, j)[3], alpha); + } + } + }); + test('it should mask the animated gif image', function() { const imagePath = 'unit/assets/nyan_cat.gif'; return new Promise(function(resolve, reject) { From e832b3ddccfe4ac1836b8f08dd7f7dd31b80d846 Mon Sep 17 00:00:00 2001 From: Papershine Date: Tue, 30 Apr 2024 17:22:05 -0700 Subject: [PATCH 6/8] comment grammar --- src/image/p5.Image.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/image/p5.Image.js b/src/image/p5.Image.js index f048b0822e..dac63304c5 100644 --- a/src/image/p5.Image.js +++ b/src/image/p5.Image.js @@ -847,7 +847,7 @@ p5.Image = class { * image and using its alpha channel as an alpha channel for * this image. Masks are cumulative, once applied to an image * object, they cannot be removed. If the mask has a different - * pixel density from this image, the mask will be scaled + * pixel density from this image, the mask will be scaled. * * @method mask * @param {p5.Image} srcImage source image. From fbefb564fd3fe7c2c985522b92f0a2c298f4c93b Mon Sep 17 00:00:00 2001 From: Papershine Date: Tue, 30 Apr 2024 17:27:56 -0700 Subject: [PATCH 7/8] fix testing not testing everything --- test/unit/image/p5.Image.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/unit/image/p5.Image.js b/test/unit/image/p5.Image.js index 7ba41a55d7..90f48985a8 100644 --- a/test/unit/image/p5.Image.js +++ b/test/unit/image/p5.Image.js @@ -50,7 +50,7 @@ suite('p5.Image', function() { }); }); - suite.only('p5.Image.prototype.mask', function() { + suite('p5.Image.prototype.mask', function() { for (const density of [1, 2]) { test(`it should mask the image at pixel density ${density}`, function() { let img = myp5.createImage(10, 10); From a11e2bc9c5b827804634289fbe156c087c866cf9 Mon Sep 17 00:00:00 2001 From: Papershine Date: Thu, 2 May 2024 22:31:04 -0700 Subject: [PATCH 8/8] add createGraphics test for mask --- test/unit/image/p5.Image.js | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/test/unit/image/p5.Image.js b/test/unit/image/p5.Image.js index 90f48985a8..6db53702d2 100644 --- a/test/unit/image/p5.Image.js +++ b/test/unit/image/p5.Image.js @@ -119,6 +119,25 @@ suite('p5.Image', function() { } }); + test('it should mask images from createGraphics', function() { + myp5.createCanvas(10,10); + myp5.pixelDensity(2); + let img = myp5.createGraphics(10,10); + img.rect(0,0,10,10); + img.background(0); + let mask = createGraphics(10,10); + mask.rect(0,0,5,5); + let masked = img.get(); + masked.mask( mask.get() ); + + for (let i = 0; i < masked.width; i++) { + for (let j = 0; j < masked.height; j++) { + let alpha = i < 5 && j < 5 ? 255 : 0; + assert.strictEqual(masked.get(i, j)[3], alpha); + } + } + }); + test('it should mask the animated gif image', function() { const imagePath = 'unit/assets/nyan_cat.gif'; return new Promise(function(resolve, reject) {