I’m working on a feature to dynamically determine the object color (white or black) based on the brightness of the canvas background where the object is placed. I use the getImageData method to calculate the average color and brightness of the background in the area where the text resides. However, I’m experiencing inconsistent results when the background is black.
Below is my code
getTextColor(ctx, text,) {
var zoom = this.canvas.getZoom();
let x1, y1, width, height;
x1 = text.left * zoom;
y1 = text.top * zoom;
width = text.width * zoom;
height = (text.type == 'line') ? text.strokeWidth * zoom : text.height * zoom;
var imageData = ctx.getImageData(x1, y1, width, height).data;
var totalPixels = width * height;
var r = 0, g = 0, b = 0, a = 0, count = 0;
for (var i = 0; i < imageData.length; i += 4) {
var red = imageData[i];
var green = imageData[i + 1];
var blue = imageData[i + 2];
var alpha = imageData[i + 3] / 255;
r += red * alpha;
g += green * alpha;
b += blue * alpha;
a += alpha;
count++;
}
if (count > 0 && a > 0) {
r = Math.floor(r / a);
g = Math.floor(g / a);
b = Math.floor(b / a);
} else {
r = g = b = 255;
}
var avgColor = { r: r, g: g, b: b, a: a / totalPixels };
var blendedR = (1 - avgColor.a) * 255 + avgColor.a * avgColor.r;
var blendedG = (1 - avgColor.a) * 255 + avgColor.a * avgColor.g;
var blendedB = (1 - avgColor.a) * 255 + avgColor.a * avgColor.b;
var brightness = (blendedR * 299 + blendedG * 587 + blendedB * 114) / 1000;
return brightness < ((text.type == 'line') ? 83 : 60) ? '#ffffff' : '#000000';
}
In this method, when my background color is black, the first time I return white and the second time I return. same method, perfect work on the White background color