How do you convert an image (PNG) to a 2D Array (b

2019-02-20 09:20发布

问题:

I need a 2D binary representation of the following PNG image:

Can anyone provide a method or a source to convert PNG image above to a 2D array where 1 = land and 0 = water?

With some reading I figured out a way to loop through all the pixels in the image after converting the image to base64 using online Base64ImageEncoder.

With the following fiddle I am able to figure out if the pixel is water or land then change the pixel color, so the output is:

I feel that I am very close to getting exactly what I need. What do I need to do to change the main for-loop to instead save data inside of a Matrix?

JavaScript:

$(document).ready(function() {
    $("#btnSubmit").click(function(){
        GetBinary();
    }); 
});

function GetBinary() {
    var canvas = document.createElement("canvas");
    canvas.width = imgElement.offsetWidth;
    canvas.height = imgElement.offsetHeight;

    var ctx = canvas.getContext("2d");
    ctx.drawImage(imgElement,0,0);

    var map = ctx.getImageData(0,0,canvas.width,canvas.height);
    var imdata = map.data;

    var r,g,b;
    for(var p = 0, len = imdata.length; p < len; p+=4) {
        r = imdata[p]
        g = imdata[p+1];
        b = imdata[p+2];

        if ((r >= 164 && r <= 255) && (g >= 191 && g <= 229) && (b >= 220 && b <= 255)) {

            // black  = water
             imdata[p] = 0;
             imdata[p+1] = 0;
             imdata[p+2] = 0;

        } else {

            // white = land
             imdata[p] = 255;
             imdata[p+1] = 255;
             imdata[p+2] = 255;                     
        }                   
    }
    ctx.putImageData(map,0,0);
    imgElement.src = canvas.toDataURL();
}               

Please note that I used a base64 image so we are not allowed to paste here because it is too long. Please my fiddle instead.

HTML:

<img id='myImage' src='base64 image data' />
<br />
<input id = "btnSubmit" type="button" value="Get Binary Image"/>

回答1:

It looks like image data returns a single array of rgba components, you just have to break it up into rows. See http://jsfiddle.net/mendesjuan/wjn0dub7/1/

var currentInnerArray;
var zeroesAndOnes = [];
for(var p = 0, len = imdata.length; p < len; p+=4) {
    r = imdata[p]
    g = imdata[p+1];
    b = imdata[p+2];

    // Each line is the pixel width * 4, (rgba), start a newline
    if (p % imdata.width * 4 === 0) {
      currentInnerArray = [];
      zeroesAndOnes.push(currentInnerArray);
    }
    if ((r >= 164 && r <= 255) && (g >= 191 && g <= 229) && (b >= 220 && b <= 255)) {
      currentInnerArray.push(0);
      // black  = water
      imdata[p] = 0;
      imdata[p+1] = 0;
      imdata[p+2] = 0;

   } else {
     currentInnerArray.push(1);
     // white = land
     imdata[p] = 255;
     imdata[p+1] = 255;
     imdata[p+2] = 255;
     }                  
}
// zeroesAndOnes has your 2d array


回答2:

Here's the relevant part if you want to access individual pixels as a 2D array

var w = canvas.width * 4;
var r,g,b;

for (var i=0; i<canvas.width * 4; i+=4) {
  for (var j=0; j<canvas.height; j+=1) {
        //console.log(j*w+i, j*w+i+1, j*w+i+2, j*w+i+3);
    r = imdata[j*w+i]
            g = imdata[j*w+i+1];
            b = imdata[j*w+i+2];

    if ((r >= 164 && r <= 255) && 
        (g >= 191 && g <= 229) && 
        (b >= 220 && b <= 255)) {

      // blue  = water
      imdata[j*w+i] = 0;
      imdata[j*w+i+1] = 0;
      imdata[j*w+i+2] = 150;

    } else {

      // green = land
      imdata[j*w+i] = 0;
      imdata[j*w+i+1] = 120;
      imdata[j*w+i+2] = 0;                      
    }                   
  }
}