简体   繁体   中英

Find all possible combinations of binary m by n matrix

I want to create images whose dimensions are m by n. I need to create all possible images whose pixels are either black or white (no other colors for now). One way to go about this is to create binary matrices whose fields are either 0 or 1, representing black and white. Each row in the matrix is an image, each field a pixel in the image.

I currently have the code to create an m by n image with color assignment for each pixel:

var fs = require("fs");
var Buffer = require("buffer").Buffer;
var Png = require("png").Png;

var IMAGE_WIDTH = 16;
var IMAGE_HEIGHT = 16;

var rgb_data = new Buffer(IMAGE_WIDTH * IMAGE_HEIGHT * 3);

for(var h = 0; h < IMAGE_HEIGHT; h++)
{
  for(var w = 0; w < IMAGE_WIDTH; w++)
  {
    var p = h * IMAGE_WIDTH * 3 + w * 3;

    rgb_data[p + 0] = 255; // r (0-255)
    rgb_data[p + 1] = 255; // g (0-255)
    rgb_data[p + 2] = 255; // b (0-255)
  }
}

var png = new Png(rgb_data, IMAGE_WIDTH, IMAGE_HEIGHT, "rgb")

fs.writeFile("output.png", png.encodeSync().toString("binary"), "binary", function(err) {
  if(err) { throw err; }
  console.log('image generated!');
});

This, for example, would make an image that's all white. I need to find a way to run this code in a loop for all possible black and white combinations.

A 1x1 image is easy, it's either all white or all black.

A 2x1 image would have the following combinations, each row being an image:

1 1 --> all white image
0 0 --> all black image
1 0 --> image with left pixel white, right pixel black
0 1 --> image with left pixel black, right pixel white

A 2x2 image would have the following combinations, again each row being an image:

0 0 0 0
0 0 0 1
0 0 1 0
0 1 0 0
1 0 0 0
0 0 1 1
0 1 0 1
1 0 0 1
1 0 1 0
1 1 0 0
0 1 1 1
1 0 1 1
1 1 0 1
1 1 1 0
1 1 1 1

And so on. This seems to have been solved for Matlab, but I need a solution in JavaScript (or any pseudo code, really) that doesn't utilize a library.

I found a solution. It struck me that I could just count up in binary code. For example, a 2x2 image will have four pixels. An all white image would be:

1 1 1 1

and an all black image would be:

0 0 0 0

So I know the lowest number in binary code, and the highest number in binary code. Then I just count up:

var pixelCount = imageWidth * imageHeight;

var lowestBinary = '';
var highestBinary = '';

for (var i = 0; i < pixelCount; i++) {
  lowestBinary += '0';
  highestBinary += '1';
}

var images = [];

var lowestDecimal = 0;
var highestDecimal = parseInt(highestBinary, 2); // convert from binary to decimal
var currentDecimal = lowestDecimal;

while (currentDecimal <= highestDecimal) {
  var image = currentDecimal.toString(2); // convert from decimal to binary

  while (image.length < pixelCount) {
    image = '0' + image;
  }

  images.push(image);

  currentDecimal++;
};

The whole code looks like this:

var fs = require("fs");
var Buffer = require("buffer").Buffer;
var Png = require("png").Png;

var imageWidth = 4;
var imageHeight = 3;

var rgb_data;

var pixelCount = imageWidth * imageHeight;

var lowestBinary = '';
var highestBinary = '';

for (var i = 0; i < pixelCount; i++) {
  lowestBinary += '0';
  highestBinary += '1';
}

var images = [];

var lowestDecimal = 0;
var highestDecimal = parseInt(highestBinary, 2);
var currentDecimal = lowestDecimal;

while (currentDecimal <= highestDecimal) {
  var image = currentDecimal.toString(2);

  while (image.length < pixelCount) {
    image = '0' + image;
  }

  images.push(image);

  currentDecimal++;
};

var h;
var w;
var p;

images.forEach(function (image, index) {
  rgb_data = new Buffer(imageWidth * imageHeight * 3);

  for (var i = 0; i < image.length; i++) {
    h = Math.floor(i / imageWidth);
    w = i % imageWidth;

    p = h * imageWidth * 3 + w * 3;

    var binary = image[i];
    var color = (binary * 255).toString();

    rgb_data[p + 0] = color; // r (0-255)
    rgb_data[p + 1] = color; // g (0-255)
    rgb_data[p + 2] = color; // b (0-255)
  }

  var png = new Png(rgb_data, imageWidth, imageHeight, "rgb")

  fs.writeFile(index + ".png", png.encodeSync().toString("binary"), "binary", function(err) {
    if (err) {
      console.log('Err:', err);
    } else {
      console.log('image generated!');
    }
  });
});

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM