Найти все возможные комбинации двоичной матрицы m на n
Я хочу создать изображения, размеры которых м. Мне нужно создать все возможные изображения, чьи пиксели либо черного, либо белого (других цветов пока нет). Один из способов сделать это - создать двоичные матрицы, поля которых равны 0 или 1, представляющие черный и белый цвета. Каждая строка в матрице является изображением, каждое поле - пикселем в изображении.
В настоящее время у меня есть код для создания изображения размером m на n с назначением цвета для каждого пикселя:
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!');
});
Это, например, сделает изображение полностью белым. Мне нужно найти способ запустить этот код в цикле для всех возможных комбинаций черного и белого.
Изображение 1x1 легко, оно либо белое, либо черное.
Изображение 2x1 будет иметь следующие комбинации, каждая строка будет изображением:
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
Изображение 2x2 будет иметь следующие комбинации, снова каждая строка будет изображением:
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
И так далее. Кажется, это было решено для Matlab, но мне нужно решение на JavaScript (или на самом деле любой псевдокод), которое не использует библиотеку.
1 ответ
Я нашел решение. Меня поразило, что я могу просто посчитать в двоичном коде. Например, изображение 2х2 будет иметь четыре пикселя. Все белое изображение будет:
1 1 1 1
и все черное изображение будет:
0 0 0 0
Итак, я знаю наименьшее число в двоичном коде и наибольшее число в двоичном коде. Тогда я просто считаю:
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++;
};
Весь код выглядит так:
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!');
}
});
});