2

如何以编程方式重现以下效果?(来源:arttext.co.uk


如果可能的话,我想自动化这个过程,但对输出有一些控制(IE,反转调色板以产生深色图像的浅色背景等)。如果可能的话,以矢量格式生成结果也会很棒。

更新: 不仅仅是用 ASCII-art 重新创建,我还想指定用于重新创建图像的字符串。

4

4 回答 4

4

很简单:用网格划分图像,计算每个网格单元上像素的平均颜色(或亮度或色调等),创建一个相同大小的图像,绘制与网格单元对应的字母发现颜色。

于 2009-01-06T12:48:54.677 回答
2

我有点忙,但我终于破解了一个小处理草图来演示我的算法。

final int GRID_SIZE_H = 9;
final int GRID_SIZE_V = 9;
final int GRID_SIZE = GRID_SIZE_H * GRID_SIZE_V;
final String TEXT_TO_DISPLAY = "Picture yourself in a boat on a river With tangerine trees and marmalade skies";

void setup()
{
  size(600, 600);
  smooth();
  noStroke();
  background(0);

  PImage niceImage = loadImage("SomeImage.png");
  int niW  = niceImage.width;
  int niH = niceImage.height;
  int imgW = niW + 10;
  image(niceImage, 0, 0);

  PFont f = loadFont("Arial-Black-12.vlw");
  textFont(f);
  textAlign(CENTER);
  String textToDisplay = TEXT_TO_DISPLAY.toUpperCase().replaceAll("\\s", "");

  int pos = 0;
  niceImage.loadPixels();
  for (int j = 0; j < niH - GRID_SIZE_V; j += GRID_SIZE_V)
  {
    for (int i = 0; i < niW - GRID_SIZE_H; i += GRID_SIZE_H)
    {
      long avgR = 0, avgG = 0, avgB = 0;
      for (int x = 0; x < GRID_SIZE_H; x++)
      {
        for (int y = 0; y < GRID_SIZE_V; y++)
        {
          int c = niceImage.pixels[i + x + (j + y) * niW];
          avgR += (c >> 16) & 0xFF;
          avgG += (c >>  8) & 0xFF;
          avgB +=  c        & 0xFF;
        }
      }
      color clr = color(avgR / GRID_SIZE, avgG / GRID_SIZE, avgB / GRID_SIZE);
      fill(clr);
      char chr = textToDisplay.charAt(pos++);
      pos = pos % textToDisplay.length();
      text(chr, i + imgW, j + 12);
    }
  }
}

应该更好地使用粗体(粗体)等宽字体。

于 2009-01-06T15:50:25.013 回答
0

mplayer 有两个驱动程序可以解决这个问题,一个是名为“libaa”/ascii-art 的 BW,另一个是“libcaca”:

两者都可以使用资源,我不记得在哪个许可证下。

查看这两个库的屏幕截图:http: //liquidweather.net/howto/index.php ?id=74

于 2009-01-06T12:56:31.137 回答
0

它甚至比 PhiLho 的答案更简单。只需将文本渲染为黑色背景上全白的相同大小的图像(如果您愿意,可以预先生成)并将此“文本掩码”图像与源图像相乘。如果您不希望小于字符的细节保持可见,则可能需要使用半径与文本大小相当的高斯模糊来模糊源图像。

于 2011-09-20T19:19:51.817 回答