-
Notifications
You must be signed in to change notification settings - Fork 204
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Partial opacity color sampling #20
Comments
I'm not sure I quite understand. Can you give me 2 examples (one with the transparency other without) + the original image? |
Sorry for taking so long to give some feedback, this issue is not forgotten I haven't had the time to pick on this project. but I will check and give some feedback as soon as possible |
Since opacity is usually a float number between 0 to 1. config.opacityThreshold = .5 //or any value the user can customize.
if (pixel.opacity >= config.opacityThreshold) pixel.opacity = 1
else pixel.opacity = 0 |
I guess I kinda solved it... the pixel opacity comes from 0 to 255 as any other color
Opacity/Alpha is stored on image data as the 4th color input (R,G,B,A), so I created a function that reworks the alpha property before using putImageData: {
key: "crushAlpha",
value: function(threshold = 127.5, opacity = 255) {
const w = this.drawto.width;
const h = this.drawto.height;
var imgPixels = this.ctx.getImageData(0, 0, w, h);
for (var y = 0; y < imgPixels.height; y++) {
for (var x = 0; x < imgPixels.width; x++) {
var i = y * 4 * imgPixels.width + x * 4;
0 < imgPixels.data[i + 3] && imgPixels.data[i + 3] <= opacity ? //0 < pixelAlpha < 255
imgPixels.data[i + 3] = (imgPixels.data[i + 3] < threshold ?
0 : (Math.round(opacity) >= threshold ? (opacity - imgPixels.data[i + 3] / 2) + imgPixels.data[i + 3] : (opacity * imgPixels.data[i + 3]) / 127)) :
""
}
}
this.ctx.putImageData(imgPixels, 0, 0, 0, 0, imgPixels.width, imgPixels.height);
return this;
}
} to use it, call it like: var threshold = 50 // Any number between 0 and 255. Default is 127.5
var opacity = 255 // Any number between 0 and 255. Default is 255
px.draw().pixelate().crushAlpha( threshold, opacity ) Edits were made on on /**
* color similarity between colors, lower is better
* @param {number} threshold number between 0 and 255
* @param {number} opacity number between 0 and 255
*/
crushAlpha(threshold = 127.5, opacity = 255) {
const w = this.drawto.width;
const h = this.drawto.height;
var imgPixels = this.ctx.getImageData(0, 0, w, h);
for (var y = 0; y < imgPixels.height; y++) {
for (var x = 0; x < imgPixels.width; x++) {
var i = y * 4 * imgPixels.width + x * 4;
0 < imgPixels.data[i + 3] && imgPixels.data[i + 3] <= opacity ? //0 < pixelAlpha < 255
imgPixels.data[i + 3] = (imgPixels.data[i + 3] < threshold ?
0 : (Math.round(opacity) >= threshold ? (opacity - imgPixels.data[i + 3] / 2) + imgPixels.data[i + 3] : (opacity * imgPixels.data[i + 3]) / 127)) :
""
}
}
this.ctx.putImageData(imgPixels, 0, 0, 0, 0, imgPixels.width, imgPixels.height);
return this;
} I'm not sure, needs testing |
It could be a feature or could be a bug but when you load a png with transparency, the resulting pixelated image retains semi transparent colors from the border between opaque pixels and the background. It might be helpful to have a method to strip the underlying partially transparent pixels of their opacity so that the resulting image keeps the selected color palette. Well, I guess it wouldn't be striping it but rather rounding up or down. Like If a pixel is mostly transparent, just round it down to nothing but if its mostly opaque, round it up. It would feel more like pixel art since that rarely has partial transparency.
Example image where the transparency is retained from the original img:
The text was updated successfully, but these errors were encountered: