2016-04-07 6 views
4

Ich habe einen Ordner mit kleinen Bildern (Facebook Profilbilder). Ich möchte ein neues mosaikartiges Bild machen, in dem alle kleinen Bilder in Form einer Zahl angeordnet sind, wie in diesem Beispiel (source).Layout Bilder in Form einer Nummer

enter image description here

Gibt es eine Software, die dies tun können (und das läuft auf Windows 7)? Ansonsten bin ich auch offen für ein kleines Skript, um das gleiche zu tun. Ich weiß, wie ich den Bildern mit PIL/Pillow einen weißen Rahmen hinzufügen kann, aber meine Suche nach dem Layout der Bilder hat sich als nutzlos erwiesen.

Kann mir jemand in die richtige Richtung zeigen?

+0

In diesem [wordcloud] (https://github.com/amueller/word_cloud/blob/master/wordcloud/wordcloud.py) Repo können Sie sich die Maskierungsteile ansehen. –

Antwort

1

jsheperd shows wie Sie Text in ASCII-Art konvertieren. Sie können diesen Code leicht modifizieren, um eine Glyphmaske zu erhalten: 1 mit schwarzer Schrift und 0 mit Hintergrund. Wir können dann PIL verwenden, um ein Gesicht zufällig zu rotieren und einzufügen, wo auch immer die Maske 1 ist.

Unten habe ich matplotlib verwendet, nur um ein Bild (von Ada Lovelace) zu erhalten, das wir alle angenommen haben, dass Sie matplotlib installiert haben. Sie können die Matplotlib-Abhängigkeit entfernen und einfach faces als eine Sequenz von PIL-Bildern definieren.

from PIL import Image 
from PIL import ImageDraw 
from PIL import ImageFont 
import itertools as IT 
import numpy as np 
import matplotlib.cbook as cbook 

def text_to_pixels(text, path='arialbd.ttf', fontsize=14): 
    """ 
    https://stackoverflow.com/a/27753869/190597 (jsheperd) 
    https://stackoverflow.com/a/36386628/190597 (unutbu) 
    """ 
    font = ImageFont.truetype(path, fontsize) 
    w, h = font.getsize(text) 
    h *= 2 
    image = Image.new('L', (w, h), 1) 
    draw = ImageDraw.Draw(image) 
    draw.text((0, 0), text, font=font) 
    arr = np.asarray(image) 
    arr = np.where(arr, 0, 1) 
    arr = arr[(arr != 0).any(axis=1)] 
    return arr 

def get_image(): 
    fn = cbook.get_sample_data("ada.png") 
    face_img = Image.open(fn).convert('RGBA') 
    face_img = face_img.resize((30, 40), Image.ANTIALIAS) 
    # give image a white background 
    img = Image.new('RGBA', size=(36, 46), color=(255, 255, 255)) 
    img.paste(face_img, (3, 3)) 
    return img 

def sqdist(a, b): 
    return ((a -b)**2).sum() 

def pics_in_text(text, faces, img_width=600, img_height=250, path='arialbd.ttf', 
       fontsize=20, minsep=1000): 
    arr = text_to_pixels(text, path=path, fontsize=fontsize) 
    yx = np.column_stack(np.where(arr)).astype(float) 
    yx /= arr.shape 
    yx *= (0.75, 0.90) 
    yx += 0.05 
    yx *= (img_height, img_width) 
    yx = yx.astype('int') 
    np.random.shuffle(yx) 
    keep = [] 
    for coord in yx: 
     if all(sqdist(item, coord) > minsep for item in keep): 
      keep.append(coord) 
    yx = IT.cycle(keep) 

    img = Image.new('RGBA', size=(img_width, img_height), color=(255, 255, 255, 255)) 
    seen = list() 
    for face, coord in zip(faces, yx): 
     deg = np.random.uniform(-45, 45) 
     face = face.rotate(deg, resample=Image.BICUBIC, expand=False) 
     img.paste(face, tuple(coord[::-1]), mask=face) 
    return img 

def get_image(): 
    import matplotlib.cbook as cbook 
    fn = cbook.get_sample_data("ada.png") 
    face_img = Image.open(fn).convert('RGBA') 
    face_img = face_img.resize((30, 40), Image.ANTIALIAS) 
    # give image a white background 
    img = Image.new('RGBA', size=(36, 46), color=(255, 255, 255)) 
    img.paste(face_img, (3, 3)) 
    return img 

num_faces = 650 
faces = IT.islice(IT.cycle([get_image()]), num_faces) 
img = pics_in_text('800', faces, img_width=1200, img_height=500, 
      path='/usr/share/fonts/truetype/msttcorefonts/Comic_Sans_MS.ttf', 
      fontsize=40, minsep=375) 
img.save('/tmp/out.png', 'PNG') 

enter image description here

min_sep ist der minimale quadrierte Abstand zwischen Gesichtsbildern. Wenn Sie den Parameter min_sep erhöhen, sind die Flächen weiter voneinander entfernt. Wenn Sie min_sep verringern, können sich die Flächen dichter überlappen.