1

I am trying to detect whether an image has transparency in it using HTML5 canvas. Here is my code, which is based on logic I have found on the internet for detecting transparent pixels using canvas (for example, this question):

//note: this happens during the onload of the element
var found = false;
if((element.src).indexOf('.png') || element.src.indexOf('.tif')) {
    var c = document.createElement('canvas');
    var ctx = c.getContext('2d');
    ctx.drawImage(element,0,0);
    var imageData = ctx.getImageData(0, 0, element.width, element.height),
        data = imageData.data;
    var i = data.length/4 - 1;
    do {
        if(data[(i*4) + 3] < 255) {
            found = true;
        }
    } while (i-- && !found);
}
return found;

The problem is, even when I put in a PNG that does not have any transparency, it returns true. I used a counter to investigate:

console.log('total: '+i);
do {
    if(data[(i*4) + 3] === 0) {
        //found = true;
        found++;
    }
} while (i-- /*&& !found*/);
console.log('found: '+found);

//result for http://www.fnordware.com/superpng/pnggrad8rgb.png:
//total: 89999
//found: 45000

My question is, how can I reliably detect transparency in PNG and TIF files?

Community
  • 1
  • 1
miyasudokoro
  • 1,705
  • 1
  • 15
  • 23

1 Answers1

4

A couple of possibilities:

Check the console to be sure you don't have a cross-domain security violation caused by trying to .getImageData on an image loaded from a different domain than the webpage code.

Make sure you resize your canvas to the same size as the image or else some pixels will be transparent where the image doesn't cover the canvas.

c.width=element.width;
c.height=element.height;

**Example code and Demo:**

var canvas1=document.getElementById("canvas1");
var ctx1=canvas1.getContext("2d");
var canvas2=document.getElementById("canvas2");
var ctx2=canvas2.getContext("2d");

$p1=$('#results1');
$p2=$('#results2');

var img1=new Image();
img1.crossOrigin='anonymous'
img1.onload=start1;
img1.src="https://dl.dropboxusercontent.com/u/139992952/stackoverflow/house204-1.jpg";
function start1(){

  canvas1.width=img1.width;
  canvas1.height=img1.height;

  ctx1.drawImage(img1,0,0);

  var imgData=ctx1.getImageData(0,0,canvas1.width,canvas1.height);
  var data=imgData.data;
  var found1='Left canvas does not have transparency';
  for(var i=0;i<data.length;i+=4){
    if(data[i+3]<255){found1='Left canvas does have transparency'; }
  }

  $p1.text(found1);

}


var img2=new Image();
img2.crossOrigin='anonymous'
img2.onload=start2;
img2.src="https://dl.dropboxusercontent.com/u/139992952/stackoverflow/house-icon.png";
function start2(){

  canvas2.width=img2.width;
  canvas2.height=img2.height;

  ctx2.drawImage(img2,0,0);

  var imgData=ctx2.getImageData(0,0,canvas2.width,canvas2.height);
  var data=imgData.data;
  var found2='Right canvas does not have transparency';
  for(var i=0;i<data.length;i+=4){
    if(data[i+3]<255){found2='Right canvas does have transparency'; }
  }

  $p2.text(found2);

}
body{ background-color: ivory; }
canvas{border:1px solid red;}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<p id=results1>Results:</p>
<p id=results2>Results:</p>
<canvas id="canvas1" width=300 height=300></canvas>
<canvas id="canvas2" width=300 height=300></canvas>
markE
  • 102,905
  • 11
  • 164
  • 176