我的编程经验很少。
我想编写一个程序,生成并保存为gif图像的每个可能的图像,只能使用640 x 360像素尺寸的黑白像素。
换句话说,每个像素可以是黑色或白色。 640 x 360 = 230,400像素。所以我相信总共可以生成460,800张图像(黑色/白色为230,400 x 2)。
我想要一个程序自动执行此操作。
请帮忙!
答案 0 :(得分:8)
首先回答你的问题。是的,会有#34;一些"图片。实际上,任何符合640x360像素的人类文字都会出现。还有其他所有文本(尚未写入的文本或永远不会被写入的文本)。你也会看到每个人的照片,现在或将要活着。有关详细信息,请参阅Infinite Monkey Theorem。
创建你想要的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.");
}
}
请注意,这需要一些时间。因此,请不要打扰等待,享受生活! ;)
编辑:由于我的解决方案有点不清楚,我将解释算法。
increase
的方法。此方法采用BufferedImage并更改图像的位模式,以便显示下一个位模式。该方法只是一点点补充。如果图像遇到最后一位模式(所有像素都设置为黑色),该方法将返回false
。increase()
返回true),我们就会将图像保存为新帧并再次增加图像。increase()
方法的工作原理:该方法首先在x方向上运行,然后在y方向上运行。我假设白色像素为0
,黑色像素为1
。因此,我们想要采用图像的位模式并添加1
。我们检查第一个像素:如果是白色(0
),我们可以添加1
而不会溢出,因此我们将像素转为黑色(0 + 1 = 1
=&gt;黑色像素)。之后我们从方法返回,因为我们只想增加一个位置。它返回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();
}
现在我们修改main-while循环:
print(bufferedImage); // this one prints the empty image
while (increase(bufferedImage)) {
print(bufferedImage);
}
现在设置一些简短的例子进行测试:
new BigPicture(1, 5).process("C:\\temp\\bigpicture.gif");
最后输出:
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.
答案 1 :(得分:4)
换句话说,每个像素可以是黑色或白色。 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。
这个问题很有价值,但如果它只是四月的傻瓜玩笑那么它会让人分心和适得其反。
答案 2 :(得分:2)
我将继续前进并从相关问题中捏一些代码,只是为了好玩。
from itertools import product
for matrix in product([0, 1], repeat=(math,pow(2,230400)):
# render and save your .gif
正如所有评论已经说明的那样,祝你好运!
更严重的是,如果你不想绝对确定你有所有的排列,你可以生成一个随机的640x360矩阵并将其存储为图像。
执行此操作说100k次,你将至少看到一组有趣的图片,但是获得所有可能的排列是不可行的。
然后,您可以删除所有相同的文件,以将设置简化为唯一的图像。