Modifier une image par programme pour remplacer les détails par du texte?

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

  •  03-07-2019
  •  | 
  •  

Question

Comment reproduire par programme l'effet suivant?


(source: artext.co.uk )

Je souhaiterais automatiser le processus si possible, tout en maintenant un certain contrôle sur la sortie (par exemple, en inversant la palette de couleurs pour produire un fond clair pour les images sombres, etc.). Produire des résultats au format vectoriel serait également utile, si possible.

Mise à jour: Plutôt que de simplement recréer avec ASCII-art, je voudrais également spécifier la chaîne utilisée pour recréer l'image.

Était-ce utile?

La solution

C’est très simple: divisez l’image en grille, calculez la couleur moyenne (ou luminosité ou teinte, etc.) des pixels de chaque cellule de la grille, créez une image de même taille, tracez la lettre correspondant à la grille cellule avec la couleur trouvée.

Autres conseils

J'étais un peu excité, mais j'ai finalement piraté un petit traitement du croquis pour illustrer mon algorithme.

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

Devrait mieux fonctionner avec une grosse police (gras) monospaced.

Il existe deux pilotes pour mplayer qui traitent ce problème, l'un s'appelle BW, " libaa " / ascii-art, l’autre "libcaca":

Les sources sont disponibles pour les deux. Je ne me souviens plus sous quelle licence.

Voir ceci pour les captures d'écran des deux bibliothèques en action: http://liquidweather.net/howto/index.php?id=74

C'est encore plus simple que la réponse de PhiLho. Il suffit de rendre le texte en une image de la même taille en blanc sur fond noir (vous pouvez le générer au préalable) et multiplier ce "masque de texte". image avec votre image source. Rendre flou l’image source avec un flou gaussien dont le rayon est comparable à la taille du texte peut être souhaitable si vous ne souhaitez pas que les détails plus petits que les caractères restent visibles.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top