I am trying to manipulate pixel data as seen in the following example. And my goal is to safe the manipulated data into a new image.
Manipulating already works, but when I try to save the image data with context.putImageData() it seems like the data is being manipulated internally.
Lets start with my initializing Code:
class MultiColorTexture{
private initialized: boolean = false;
private multiColorImage: HTMLImageElement;
private canvas!: HTMLCanvasElement;
private context!: CanvasRenderingContext2D|null;
constructor(textureUrl:string){
this.multiColorImage = new Image();
this.multiColorImage.src = textureUrl;
this.multiColorImage.crossOrigin = "anonymous";
}
async Initialize(){
await this.multiColorImage.decode();
this.canvas = document.createElement("canvas");
// this.canvas.style.imageRendering = "pixelated";
this.canvas.style.imageRendering = "-moz-crisp-edges";
this.canvas.width = this.multiColorImage.width;
this.canvas.height = this.multiColorImage.height;
this.context = this.canvas.getContext("2d");
this.context?.drawImage(this.multiColorImage,0,0);
this.initialized = true;
}
}
You can see, that I already tried to change the canvas behaviour by setting styling options for imageRendering. But it didnt work.
Here my current code for manipulating - see comments for more information:
Manipulate(){ // this function is part of the MultiColorTexture class
if(!this.initialized){
alert("Not initialized")
debugger;
}
var imageData = this.context?.getImageData(0, 0, this.canvas.width, this.canvas.height);
if(imageData === undefined){
return;
}
// manipulating loop and putImageData()
// I only want certain blue values in my final image and with my current example image the following values need to be manipulated.
// So it is not necessarily about the exact manipulation since this is already giving me the desired output.
// See first example image below
for (var i=0, length=imageData?.data.length; i<length; i+=4){
if((imageData.data[i] !== imageData.data[i+1]) && (imageData.data[i+1] !== imageData.data[i+2]) && imageData.data[i+3] !==0){
var blue = imageData.data[i+2];
if( blue === 125 || blue === 124 ){
imageData.data[i] = 0;
imageData.data[i+1] = 0;
imageData.data[i+2] = 123;
imageData.data[i+3] = 0;
}
if( blue === 171){
imageData.data[i] = 0;
imageData.data[i+1] = 0;
imageData.data[i+2] = 170;
imageData.data[i+3] = 0;
}
if( blue === 32 || blue === 251 || blue === 81 || blue === 84){
imageData.data[i] = 0;
imageData.data[i+1] = 0;
imageData.data[i+2] = 0;
imageData.data[i+3] = 0;
}
}
}
this.context?.putImageData(imageData, 0,0);
// first validating loop
var counter = 0;
var tmpMap = new Map<number, number>();
for (var i=0, length=imageData?.data.length; i<length; i+=4){
if((imageData.data[i] !== imageData.data[i+1]) && (imageData.data[i+1] !== imageData.data[i+2]) && imageData.data[i+3] !==0){
var blue = imageData.data[i+2];
if(!tmpMap.has(blue)){
tmpMap.set(blue, 1);
}
else{
var cnt = tmpMap.get(blue);
cnt! += 1;
tmpMap.set(blue, cnt!);
}
counter++;
}
}
console.log(tmpMap);
console.log(counter);
// second validating loop after putImageData()
var imageData2 = this.context?.getImageData(0, 0, this.canvas.width, this.canvas.height);
if(imageData2 === undefined){
return;
}
var counter2 = 0;
var tmpMap2 = new Map<number, number>();
for (var i=0, length=imageData2?.data.length; i<length; i+=4){
if((imageData2.data[i] !== imageData2.data[i+1]) && (imageData2.data[i+1] !== imageData2.data[i+2]) && imageData2.data[i+3] !==0){
var blue = imageData2.data[i+2];
if(!tmpMap2.has(blue)){
tmpMap2.set(blue, 1);
}
else{
var cnt = tmpMap2.get(blue);
cnt! += 1;
tmpMap2.set(blue, cnt!);
}
counter2++;
}
}
console.log(tmpMap2);
console.log(counter2);
}
Output after first validating loop which shows exactly what I want:
Output after second validation loop which show different values. This exactly what I currently dont understand:

From my understanding it should be the exact same output. Does anyone of you know what is going on here and how to fix my problem?
