Programaticamente modificar uma imagem para substituir detalhe com o texto?

StackOverflow https://stackoverflow.com/questions/416376

  •  03-07-2019
  •  | 
  •  

Pergunta

Como seria um programaticamente reproduzir o seguinte efeito?

(fonte: artext.co.uk )

Eu gostaria de automatizar o processo, se possível, mas ter algum controle sobre a saída (IE, invertendo a paleta de cores para produzir uma luz de fundo para imagens escuras, etc). Produzindo resultados em formato vetorial seria ótimo, se possível, também.

Update: Ao invés de apenas recriando com ASCII-art, eu gostaria de também especificar a cadeia que é usado para recriar a imagem.

Foi útil?

Solução

É muito simples: dividir a imagem com uma grade, cor média de computação (ou luminosidade ou tonalidade, etc.) dos pixels encontrados em cada célula da grelha, criar uma imagem do mesmo tamanho, desenhar a letra correspondente à rede célula com a cor encontrada.

Outras dicas

Eu estava um pouco buzzy, mas eu finalmente cortado um pouco Processamento esboço para demonstrar meu algoritmo.

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

deve funcionar melhor com uma gordura (negrito) fonte monoespaçada.

Há dois drivers para mplayer que o endereço deste, um é BW chamado "libaa" / ascii-art, o outro "libcaca":

Fontes estão disponíveis para ambos, eu não me lembro em que licença.

Veja este para screenshots de ambos libs em ação: http://liquidweather.net/howto/index.php?id=74

É ainda mais simples do que a resposta de PhiLho. Apenas tornar o texto a uma imagem do mesmo tamanho em todo o branco no fundo preto (que pode ser pré-gerado, se quiser) e multiplicar esta imagem "máscara de texto" com a sua imagem de origem. Borrar a imagem de origem com um Gaussian Blur cujo raio é comparável ao tamanho do texto pode ser desejável se você não quer menor do que o caráter detalhe para permanecer visível.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top