Программно изменить изображение, чтобы заменить детали с текстом? - PullRequest
2 голосов
/ 06 января 2009

Как можно программно воспроизвести следующий эффект?

image
(source: artext.co.uk )

Я бы хотел автоматизировать процесс, если это возможно, но иметь некоторый контроль над выводом (например, инвертирование цветовой палитры для получения светлого фона для темных изображений и т. Д.). Было бы также неплохо получать результаты в векторном формате.

Обновление: Вместо того, чтобы просто воссоздавать с помощью ASCII-art, я бы также хотел указать строку, которая используется для воссоздания изображения.

Ответы [ 4 ]

4 голосов
/ 06 января 2009

Это довольно просто: разделить изображение на сетку, вычислить средний цвет (или яркость, оттенок и т. Д.) Пикселей, найденных в каждой ячейке сетки, создать изображение одинакового размера, нарисовать букву, соответствующую сетке ячейка с найденным цветом.

2 голосов
/ 06 января 2009

Я был немного раздражен, но наконец-то взломал небольшой Обработка набросок, чтобы продемонстрировать мой алгоритм.

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);
    }
  }
}

Должно работать лучше с жирным (жирным) моноширинным шрифтом.

0 голосов
/ 20 сентября 2011

Это даже проще, чем ответ PhiLho. Просто визуализируйте текст с изображением одинакового размера во всем белом на черном фоне (это может быть предварительно сгенерировано, если хотите) и умножьте это изображение «текстовой маски» на исходное изображение. Размытие исходного изображения с помощью гауссова размытия, радиус которого сравним с размером текста, может быть желательным, если вы не хотите, чтобы детали размером меньше символа оставались видимыми.

0 голосов
/ 06 января 2009

Есть два драйвера для mplayer, которые решают эту проблему, один BW называется libaa / ascii-art, другой libcaca:

Источники доступны обоим, я не помню, по какой лицензии.

Смотрите это для скриншотов обеих библиотек в действии: http://liquidweather.net/howto/index.php?id=74

...