use*_*984 11 algorithm image permutation matrix
我的编程经验非常少.
我想编写一个程序,生成并保存为gif图像的每个可能的图像,只能使用640 x 360像素尺寸的黑白像素.
换句话说,每个像素可以是黑色或白色.640 x 360 = 230,400像素.所以我相信总共可以生成460,800张图像(黑色/白色为230,400 x 2).
我想要一个程序自动执行此操作.
请帮忙!
首先回答你的问题.是的,会有关于"一些"图片的文章.实际上,任何符合640x360像素的人类文字都会出现.还有其他所有文本(尚未写入的文本或永远不会被写入的文本).你也会看到每个人的照片,现在或将要活着.有关详细信息,请参阅无限猴子定理.
创建你想要的gif的代码相当容易.我为此使用了Java.请注意,您需要一个额外的类:AnimatedGifEncoder.代码不受内存限制,因为AanimatedGifEncoder它会在计算后立即将每个映像写入磁盘.但请确保您有足够的可用磁盘空间.
import java.awt.Color;
import java.awt.image.BufferedImage;
public class BigPicture {
private final int width;
private final int height;
private final int WHITE = Color.WHITE.getRGB();
private final int BLACK = Color.BLACK.getRGB();
public BigPicture(int width, int height) {
this.width = width;
this.height = height;
}
public void process(String outFile) {
AnimatedGifEncoder gif = new AnimatedGifEncoder();
gif.setSize(width, height);
gif.setTransparent(null); // no transparency
gif.setRepeat(-1); // play only once
gif.setDelay(0); // 0 ms delay between images,
// 'cause ain't nobody got time for that!
gif.start(outFile);
BufferedImage bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_BYTE_BINARY);
// set the image to all white
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
bufferedImage.setRGB(x, y, WHITE);
}
}
// add white image
gif.addFrame(bufferedImage);
// add all other combinations
while (increase(bufferedImage)) {
gif.addFrame(bufferedImage);
}
gif.finish();
}
/**
* @param bufferedImage
* the image to increase
* @return false if last pixel set to black => image is complete black
*/
private boolean increase(BufferedImage bufferedImage) {
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
if (bufferedImage.getRGB(x, y) == WHITE) {
bufferedImage.setRGB(x, y, BLACK);
return true;
}
bufferedImage.setRGB(x, y, WHITE);
}
}
return false;
}
public static void main(String[] args) {
new BigPicture(640, 360).process("C:\\temp\\bigpicture.gif");
System.out.println("finished.");
}
}
Run Code Online (Sandbox Code Playgroud)
请注意,这需要一些时间.所以不要打扰等待,享受你的生活!;)
编辑:由于我的解决方案有点不清楚,我会解释算法.
increase.此方法采用BufferedImage并更改图像的位模式,以便显示下一个位模式.该方法只是一点点补充.false如果图像遇到最后一位模式(所有像素都设置为黑色),则该方法将返回.increase()返回true),我们就会将图像保存为新帧并再次增加图像.increase()方法的工作原理:该方法首先在x方向上运行,然后在y方向上运行.我假设白色像素是0黑色像素1.所以,我们想要采用图像的位模式并添加1.我们检查第一个像素:如果它是白色(0)我们可以添加1没有溢出,所以我们将像素转为黑色(0 + 1 = 1=>黑色像素).之后我们从方法返回,因为我们只想增加一个位置.它返回true是因为可能增加.如果我们遇到黑色像素,我们会有溢出(1 + 1 = 2或二进制10).所以我们必须将当前像素设置为白色并添加1到下一个像素.这将持续到我们找到第一个白色像素.示例:首先我们创建一个print方法:此方法将图像打印为二进制数.注意数字反转,最重要的位是右侧的位.
public void print(BufferedImage bufferedImage) {
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
if (bufferedImage.getRGB(x, y) == WHITE) {
System.out.print(0); // white pixel
} else {
System.out.print(1); // black pixel
}
}
}
System.out.println();
}
Run Code Online (Sandbox Code Playgroud)
现在我们修改main-while循环:
print(bufferedImage); // this one prints the empty image
while (increase(bufferedImage)) {
print(bufferedImage);
}
Run Code Online (Sandbox Code Playgroud)
现在设置一些简短的例子来测试:
new BigPicture(1, 5).process("C:\\temp\\bigpicture.gif");
Run Code Online (Sandbox Code Playgroud)
最后输出:
00000 // 0 this is the first print before the loop -> "white image"
10000 // 1 the first white pixel is set to black
01000 // 2 the first overflow, so the second pixel is set to black "2"
11000 // 3
00100 // 4
10100 // 5
01100
11100
00010 // 8
10010
01010
11010
00110
10110
01110
11110
00001 // 16
10001
01001
11001
00101
10101
01101
11101
00011
10011
01011
11011
00111
10111
01111
11111 // 31 == 2^5 - 1
finished.
Run Code Online (Sandbox Code Playgroud)
换句话说,每个像素可以是黑色或白色。640 x 360 = 230,400 像素。所以我相信总共可以生成 460,800 张图像(黑色/白色为 230,400 x 2)。
你的信念有一点缺陷。您对像素数的看法是正确的:230,400。不幸的是,这意味着没有 2 * 230,400,而是 2 ^ 230,400 张可能的图片,这是一个超过 60,000 位数的数字(恐怕比允许的答案大小还要长)。为了进行比较,具有 45 位数字的特定数字表示以厘米为单位的可观测宇宙的直径(大约是小指的宽度)。
为了理解为什么你计算的图片数量是错误的,考虑这个例子:如果你的图片只包含三个像素,你可能有 8 张不同的图片 (2 ^ 3),而不是 6 (2 * 3)。以下是所有这些:BBB、BBW、BWB、BWW、WBB、WBW、WWB、WWW。添加另一个像素会使可能的图片尺寸加倍,因为您可以将所有 3 像素情况下的图像设为白色,或将所有 3 像素情况下设为黑色。将 1(您可以拥有 0 像素的图片数量)加倍 230,400 次得到 2 ^ 230,400。
这个问题有悬赏是很好的,但如果它只是一个愚人节玩笑,它就会让人分心并且适得其反。
我将继续从相关问题中提取一些代码,只是为了好玩。
from itertools import product
for matrix in product([0, 1], repeat=(math,pow(2,230400)):
# render and save your .gif
Run Code Online (Sandbox Code Playgroud)
正如所有评论已经指出的那样,祝你好运!
更严重的是,如果您不想绝对确定拥有所有排列,您可以生成一个随机 640x360 矩阵并将其存储为图像。
执行此操作(比如说 10 万次),您至少会看到一组有趣的图片,但获得所有可能的排列是不可行的。
然后,您可以删除所有相同的文件,以将文件集减少为仅包含唯一的图像。