C 生成适度有趣的图像
摘要:你能提出一个像素平面上的数学ish算法来生成一个中等有趣的图像,最好是一个整体上类似于某个东西的图像吗 到目前为止的故事: 曾几何时,我决定努力减少我(无可否认也是如此)众多计算机上的循环浪费,并开始以一种适度有趣的方式生成图像;使用PRNG和一些聪明的数学来创建大体上类似于某个东西的图像 至少,这是计划。事实证明,聪明的数学需要成为聪明的数学家;我不是 在某种程度上,我找到了一种更倾向于直线的方法(因为直线通常是构成我们世界的组成部分),也许是过于强烈了。结果有点有趣;可能类似于城市网格: 现在问一个恰当的问题:给定这个小程序的源代码;你能改进它,并提出一种能给出更有趣结果的方法吗?(例如,不是城市网格,而是可能的面孔、动物、地理、你有什么) 这也意味着一种挑战;我想,因此我制定了一些完全武断且同样可选的规则:C 生成适度有趣的图像,c,C,摘要:你能提出一个像素平面上的数学ish算法来生成一个中等有趣的图像,最好是一个整体上类似于某个东西的图像吗 到目前为止的故事: 曾几何时,我决定努力减少我(无可否认也是如此)众多计算机上的循环浪费,并开始以一种适度有趣的方式生成图像;使用PRNG和一些聪明的数学来创建大体上类似于某个东西的图像 至少,这是计划。事实证明,聪明的数学需要成为聪明的数学家;我不是 在某种程度上,我找到了一种更倾向于直线的方法(因为直线通常是构成我们世界的组成部分),也许是过于强烈了。结果有点有趣;可能类似于城市网格
// compile with gcc -o imggen -lpng imggen.c
// optionally with -DITERATIONS=x, where x is an appropriate integer
// If you're on a Mac or using MinGW, you may have to fiddle with the linker flags to find the library and includes.
#include <stdio.h>
#include <stdlib.h>
#include <png.h>
#ifdef ITERATIONS
#define REPEAT
#endif // ITERATIONS
// YOU MAY CHANGE THE FOLLOWING DEFINES
#define WIDTH 320
#define HEIGHT 240
// YOU MAY REPLACE THE FOLLOWING DEFINES AS APPROPRIATE
#define INK 16384
void writePNG (png_bytepp imageBuffer, png_uint_32 width, png_uint_32 height, int iteration) {
char *fname;
asprintf(&fname, "out.%d.png", iteration);
FILE *fp = fopen(fname, "wb");
if (!fp) return;
png_structp png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
png_infop info_ptr = png_create_info_struct(png_ptr);
png_init_io(png_ptr, fp);
png_set_filter(png_ptr, PNG_FILTER_TYPE_DEFAULT, PNG_FILTER_NONE);
png_set_compression_level(png_ptr, Z_BEST_COMPRESSION);
png_set_IHDR(png_ptr, info_ptr, width, height, 8,
PNG_COLOR_TYPE_GRAY, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
png_set_rows(png_ptr, info_ptr, imageBuffer);
png_set_invert_mono(png_ptr); /// YOU MAY COMMENT OUT THIS LINE
png_write_png(png_ptr, info_ptr, PNG_TRANSFORM_IDENTITY, NULL);
png_destroy_write_struct(&png_ptr, &info_ptr);
fclose(fp);
free(fname);
}
int main (int argc, const char * argv[]) {
png_uint_32 height = HEIGHT, width = WIDTH;
int iteration = 1;
#ifdef REPEAT
for (iteration = 1; iteration <= ITERATIONS; iteration++) {
#endif // REPEAT
png_bytepp imageBuffer = malloc(sizeof(png_bytep) * height);
for (png_uint_32 i = 0; i < height; i++) {
imageBuffer[i] = malloc(sizeof(png_byte) * width);
for (png_uint_32 j = 0; j < width; j++) {
imageBuffer[i][j] = 0;
}
}
/// CUT ACROSS THE DASHED LINES
/// -------------------------------------------
/// NO EDITING ABOVE THIS LINE; EXCEPT AS NOTED
int ink = INK;
int x = rand() % width, y = rand() % height;
int xdir = (rand() % 2)?1:-1;
int ydir = (rand() % 2)?1:-1;
while (ink) {
imageBuffer[y][x] = 255;
--ink;
xdir += (rand() % 2)?(1):(-1);
ydir += (rand() % 2)?(1):(-1);
if (ydir > 0) {
++y;
} else if (ydir < 0) {
--y;
}
if (xdir > 0) {
++x;
} else if (xdir < 0) {
--x;
}
if (x == -1 || y == -1 || x == width || y == height || x == y && x == 0) {
x = rand() % width; y = rand() % height;
xdir = (rand() % 2)?1:-1;
ydir = (rand() % 2)?1:-1;
}
}
/// NO EDITING BELOW THIS LINE
/// -------------------------------------------
writePNG(imageBuffer, width, height, iteration);
for (png_uint_32 i = 0; i < height; i++) {
free(imageBuffer[i]);
}
free(imageBuffer);
#ifdef REPEAT
}
#endif // REPEAT
return 0;
}
//使用gcc-o imggen-lpng imggen.c编译
//可选地使用-DITERATIONS=x,其中x是适当的整数
//如果您在Mac上或使用MinGW,则可能需要修改链接器标志才能找到库和包含。
#包括
#包括
#包括
#ifdef迭代
#定义重复
#endif//迭代
//您可以更改以下定义
#定义宽度320
#定义高度240
//您可以根据需要替换以下定义
#定义墨水16384
void writePNG(png_bytepp imageBuffer、png_uint_32宽度、png_uint_32高度、int迭代){
char*fname;
asprintf(&fname,“out.%d.png”,迭代);
文件*fp=fopen(fname,“wb”);
如果(!fp)返回;
png_structp png_ptr=png_create_write_struct(png_LIBPNG_VER_STRING,NULL,NULL,NULL);
png_infop info_ptr=png_create_info_struct(png_ptr);
png_init_io(png_ptr,fp);
png_设置过滤器(png_ptr,png_过滤器类型默认,png_过滤器无);
png设置压缩级别(png ptr、Z最佳压缩);
png_集_IHDR(png_ptr,info_ptr,宽度,高度,8,
PNG_颜色_类型_灰色,PNG_交错_无,PNG_压缩_类型_默认,PNG_过滤器_类型_默认);
png_设置_行(png_ptr、info_ptr、imageBuffer);
png_set_invert_mono(png_ptr);///您可以注释掉这一行
png_write_png(png_ptr,info_ptr,png_TRANSFORM_IDENTITY,NULL);
png_destroy_write_struct(&png_ptr和&info_ptr);
fclose(fp);
免费(fname);
}
int main(int argc,const char*argv[]{
png_uint_32高度=高度,宽度=宽度;
int迭代=1;
#ifdef重复
对于(迭代=1;迭代0){
++y;
}else if(ydir<0){
--y;
}
如果(xdir>0){
++x;
}else if(xdir<0){
--x;
}
如果(x==-1 | | y==-1 | | x==宽度| | y==高度| | x==y&&x==0){
x=rand()%宽度;y=rand()%高度;
xdir=(rand()%2)?1:-1;
ydir=(rand()%2)?1:-1;
}
}
///此行下方禁止编辑
/// -------------------------------------------
writePNG(图像缓冲区、宽度、高度、迭代);
对于(png_uint_32 i=0;i
注意:虽然严格来说,这个问题似乎不是“可以回答的”;我仍然相信,它可以给出某种“正确”的答案。也许吧
狩猎快乐
编辑(再次):我的答案(向下阅读)中使用的简化贝塞尔路径的源代码可以找到。Hmmm。我记得很久以前在logo中制作了一个国家发电机。基本策略是为每种颜色分配一个油漆工,并制定规则,“油漆工,随机移动,但不得在任何已绘制的区域上移动,除非该区域已绘制为自己的颜色。”结果是几个连续绘制的区域。画家在4个方向随机移动,网格大小约为50x50 完成后,我拍摄了我的50x50图像,将它(与最近的邻居)扩展到更大的位置,并使用了一些标准的图形过滤器(模糊等)使它看起来像样。如果你
#include "bezier.h"
/// NO EDITING ABOVE THIS LINE; EXCEPT AS NOTED
Bezier *path = newBezier(newPoint(rand() % width,rand() % height), newPoint(rand() % width,rand() % height), newPoint(rand() % width,rand() % height), newPoint(rand() % width,rand() % height));
float t;
Point *point = NULL;
for (t = 0.0; t <= 1.0; t += 0.00000006) {
point = bezierPoint(path, t, point);
int32_t x = point->x, y = point->y;
if (x >= 0 && x < width && y >= 0 && y < height)
imageBuffer[y][x] = 255;
}
destroyPoint(point);
/// NO EDITING BELOW THIS LINE