C 生成适度有趣的图像

C 生成适度有趣的图像,c,C,摘要:你能提出一个像素平面上的数学ish算法来生成一个中等有趣的图像,最好是一个整体上类似于某个东西的图像吗 到目前为止的故事: 曾几何时,我决定努力减少我(无可否认也是如此)众多计算机上的循环浪费,并开始以一种适度有趣的方式生成图像;使用PRNG和一些聪明的数学来创建大体上类似于某个东西的图像 至少,这是计划。事实证明,聪明的数学需要成为聪明的数学家;我不是 在某种程度上,我找到了一种更倾向于直线的方法(因为直线通常是构成我们世界的组成部分),也许是过于强烈了。结果有点有趣;可能类似于城市网格

摘要:你能提出一个像素平面上的数学ish算法来生成一个中等有趣的图像,最好是一个整体上类似于某个东西的图像吗

到目前为止的故事:

曾几何时,我决定努力减少我(无可否认也是如此)众多计算机上的循环浪费,并开始以一种适度有趣的方式生成图像;使用PRNG和一些聪明的数学来创建大体上类似于某个东西的图像

至少,这是计划。事实证明,聪明的数学需要成为聪明的数学家;我不是

在某种程度上,我找到了一种更倾向于直线的方法(因为直线通常是构成我们世界的组成部分),也许是过于强烈了。结果有点有趣;可能类似于城市网格:

现在问一个恰当的问题:给定这个小程序的源代码;你能改进它,并提出一种能给出更有趣结果的方法吗?(例如,不是城市网格,而是可能的面孔、动物、地理、你有什么)

这也意味着一种挑战;我想,因此我制定了一些完全武断且同样可选的规则:

  • 代码中的注释说明了这一切。建议和“解决办法”应: 编辑算法本身,而不是周围的框架,除非要修复 阻止样本编译的错误

  • 代码应该使用标准的C编译器干净地编译。(如果 提供的示例没有,哎呀!告诉我,我会解决的。:)

  • 尽管如此,该方法还是应该是可选的,不需要从 您友好的邻居数学库,并且总体上使用(P)RNG作为其 主数据输入通道

  • 解决方案应该可以通过简单地拔掉两者之间的任何东西来实现 剪贴线(分别表示不应编辑上方和下方的剪贴线), 特别是你需要在序言中添加的内容

  • 编辑:有时很容易忘记,互联网上的人无法阅读我的文章 介意但你来了。该计划应至少需要人工干预 生成图像时,除了对结果进行评估外,还选择了最佳的 一个

  • 代码需要C编译器和libpng来构建;我并不完全相信MinGW编译器提供了必要的功能,但如果它没有提供,我会感到惊讶。对于Debian,您需要libpng开发包,对于Mac OS X,您需要XCode工具

    源代码可以是

    警告:大量代码涌入

    // 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