P
P
Paulo Madronero2014-08-19 01:17:47
JavaScript
Paulo Madronero, 2014-08-19 01:17:47

How to draw on Canvas without using putImageData()?

Good day. There is such an old bug on android devices https://code.google.com/p/android/issues/detail?id... In general, if you change the color of an image using the getImageData() and putImageData() methods, then the result is not is equal to the expected result.

var imgCanvas = document.createElement("canvas");
var ctx = imgCanvas.getContext("2d");
var imageObj.src = 'img/someImage.png';
imageObj.onload = function(){
  ctx.draw(imageObj,0,0);
  var imageData = ctx.getImageData(0,0,30,30);
  var data = imageData.data;          
  for(var i = 0, n = data.length; i < n; i += 4) {                                 
    data[i]+=20;//red	
    data[i+1]-=20;//green
    data[i+2]-=20;//blue
    //data[i+3]=0; //alpha, но я не трогаю этого параметра             
  }
  ctx.putImageData(imageData,0,0);
}

If the initial parameters of a random pixel were, say, rgba = [100,50,200,200], then after applying these changes, the result is expected to be rgba = [120,30,180,200], but in the android browser the result is completely different. I am developing an application in html5 and I use Phonegap to build, the result is the same as in the android browser. In chrome for android everything works fine.
Since I have to finish the development very soon and the app needs to run on android 4.x+ devices, I would like to know how to do the same without using putImageData()? Or what advice do you have for this? Thank you.

Answer the question

In order to leave comments, you need to log in

2 answer(s)
P
Paulo Madroniero, 2014-08-19
@madroneropaulo

Solved the problem like this:

var imgCanvas = document.createElement("canvas");
var ctx = imgCanvas.getContext("2d");
var imageObj.src = 'img/someImage.png';
imageObj.onload = function(){   
  ctx.draw(imageObj,0,0);
  var imageData = ctx.getImageData(0,0,30,30);
  var data = imageData.data;
        var countX=0;
        var countY=0;         
  for(var i = 0, n = data.length; i < n; i += 4) {                                 
    var red = data[i] + 50;
                var green = data[i+1] - 50;
                var blue = data[i+2] - 50;
                var alpha = (data[i+3]/255).toFixed(2);
            
                ctx.fillStyle = 'rgba('+red+','+green+','+blue+','+alpha+')'; 
                ctx.fillRect(countX,countY,1,1);

                countX++;
                if(countX>=imageHeight){
        	         countX=0;
        	         countY++;
        	         if(countY>=imageWidth){
        		         countY=0;
        	         }                
                }                   
  }	
}

Draw a square at every pixel using fillRect(). And I took the rgba parameters from the original image using the getImageData() method. In this example, I am adding some red and removing some blue and green. I do not change the alpha, but fillStyle() takes an alpha value from 0 to 1, so it is divided by 255. Then the image in the canvas is available for use, for example, using toDataUrl()
var imageUrl=imgCanvas.toDataURL(); 
    var pushImg = new Image();
    pushImg.src = imageUrl;
    pushImg.onload = function(){
      //Действия с новым изображением pushImg. 
    }

E
Evgeny Nizamiev, 2014-08-19
@RadiationX

And seriously, the color is different. Didn't notice before.
As an option, just put a "mask" on the picture? with a certain color.
This "mask" / layer can be generated, it seems that there are no distortions during generation.
It looks like an error in getting the pixel array itself, because even if you add 0, the color is different.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question