Skip to content

Commit 792109c

Browse files
authored
Merge pull request #5508 from yifanmai/yifanmai/gif-mask
Animated GIF masking
2 parents 084374b + fe1c59d commit 792109c

File tree

2 files changed

+96
-5
lines changed

2 files changed

+96
-5
lines changed

src/image/p5.Image.js

+23-5
Original file line numberDiff line numberDiff line change
@@ -629,10 +629,6 @@ p5.Image.prototype.copy = function(...args) {
629629
* http://blogs.adobe.com/webplatform/2013/01/28/blending-features-in-canvas/
630630
*/
631631
// TODO: - Accept an array of alpha values.
632-
// - Use other channels of an image. p5 uses the
633-
// blue channel (which feels kind of arbitrary). Note: at the
634-
// moment this method does not match native processing's original
635-
// functionality exactly.
636632
p5.Image.prototype.mask = function(p5Image) {
637633
if (p5Image === undefined) {
638634
p5Image = this;
@@ -657,7 +653,29 @@ p5.Image.prototype.mask = function(p5Image) {
657653
];
658654

659655
this.drawingContext.globalCompositeOperation = 'destination-in';
660-
p5.Image.prototype.copy.apply(this, copyArgs);
656+
if (this.gifProperties) {
657+
for (let i = 0; i < this.gifProperties.frames.length; i++) {
658+
this.drawingContext.putImageData(
659+
this.gifProperties.frames[i].image,
660+
0,
661+
0
662+
);
663+
p5.Image.prototype.copy.apply(this, copyArgs);
664+
this.gifProperties.frames[i].image = this.drawingContext.getImageData(
665+
0,
666+
0,
667+
this.width,
668+
this.height
669+
);
670+
}
671+
this.drawingContext.putImageData(
672+
this.gifProperties.frames[this.gifProperties.displayIndex].image,
673+
0,
674+
0
675+
);
676+
} else {
677+
p5.Image.prototype.copy.apply(this, copyArgs);
678+
}
661679
this.drawingContext.globalCompositeOperation = currBlend;
662680
this.setModified(true);
663681
};

test/unit/image/p5.Image.js

+73
Original file line numberDiff line numberDiff line change
@@ -49,4 +49,77 @@ suite('p5.Image', function() {
4949
assert.strictEqual(img.height, 30);
5050
});
5151
});
52+
53+
suite('p5.Image.prototype.mask', function() {
54+
test('it should mask the image', function() {
55+
let img = myp5.createImage(10, 10);
56+
img.loadPixels();
57+
for (let i = 0; i < img.height; i++) {
58+
for (let j = 0; j < img.width; j++) {
59+
let alpha = i < 5 ? 255 : 0;
60+
img.set(i, j, myp5.color(0, 0, 0, alpha));
61+
}
62+
}
63+
img.updatePixels();
64+
65+
let mask = myp5.createImage(10, 10);
66+
mask.loadPixels();
67+
for (let i = 0; i < mask.width; i++) {
68+
for (let j = 0; j < mask.height; j++) {
69+
let alpha = j < 5 ? 255 : 0;
70+
mask.set(i, j, myp5.color(0, 0, 0, alpha));
71+
}
72+
}
73+
mask.updatePixels();
74+
75+
img.mask(mask);
76+
img.loadPixels();
77+
for (let i = 0; i < img.width; i++) {
78+
for (let j = 0; j < img.height; j++) {
79+
let alpha = i < 5 && j < 5 ? 255 : 0;
80+
assert.strictEqual(img.get(i, j)[3], alpha);
81+
}
82+
}
83+
});
84+
85+
test('it should mask the animated gif image', function() {
86+
const imagePath = 'unit/assets/nyan_cat.gif';
87+
return new Promise(function(resolve, reject) {
88+
myp5.loadImage(imagePath, resolve, reject);
89+
}).then(function(img) {
90+
let mask = myp5.createImage(img.width, img.height);
91+
mask.loadPixels();
92+
for (let i = 0; i < mask.width; i++) {
93+
for (let j = 0; j < mask.height; j++) {
94+
const alpha = j < img.height / 2 ? 255 : 0;
95+
mask.set(i, j, myp5.color(0, 0, 0, alpha));
96+
}
97+
}
98+
mask.updatePixels();
99+
100+
img.mask(mask);
101+
img.loadPixels();
102+
for (let i = 0; i < img.width; i++) {
103+
for (let j = 0; j < img.height; j++) {
104+
const alpha = j < img.height / 2 ? 255 : 0;
105+
assert.strictEqual(img.get(i, j)[3], alpha);
106+
}
107+
}
108+
for (
109+
frameIndex = 0;
110+
frameIndex < img.gifProperties.numFrames;
111+
frameIndex++
112+
) {
113+
const frameData = img.gifProperties.frames[frameIndex].image.data;
114+
for (let i = 0; i < img.width; i++) {
115+
for (let j = 0; j < img.height; j++) {
116+
const index = 4 * (i + j * img.width) + 3;
117+
const alpha = j < img.height / 2 ? 255 : 0;
118+
assert.strictEqual(frameData[index], alpha);
119+
}
120+
}
121+
}
122+
});
123+
});
124+
});
52125
});

0 commit comments

Comments
 (0)