2016-04-07 29 views
4

Küçük resimlere sahip bir klasörüm var (Facebook profil resimleri). Bu örnekte olduğu gibi (source) gibi tüm küçük resimlerin bir sayı şeklinde düzenlendiği mozaik benzeri bir resim yapmak istiyorum.Bir dizi biçiminde düzen resimleri

enter image description here

yapabilirsiniz bir yazılım programı var mıdır (ve bu Windows 7 üzerinde çalışır)? Aksi halde, aynısını yapmak için küçük bir betik yazmaya da açıkım. Görüntülere PIL/Yastık ile nasıl beyaz bir kenar ekleyebileceğimi biliyorum, ancak görüntülerin düzenini nasıl yapacağım için aramalarım sorunsuz hale geldi.

Beni doğru yöne yönlendiren var mı?

+0

Bu [wordcloud] (https://github.com/amueller/word_cloud/blob/master/wordcloud/wordcloud.py) repo dosyasında maskeleme ile ilgili bölümlere bakabilirsiniz. –

cevap

1

jsheperd shows ASCII art'a metin nasıl dönüştürülür. Yazı tipinin siyah olduğu bir glif maskesi - 1 ve arka planın olduğu yer olan 0 elde etmek için bu kodu hafifçe değiştirebilirsiniz. Daha sonra, PIL'i maskenin 1 olduğu her yerde bir yüze rastgele döndürebilir ve yapıştırabiliriz.

Aşağıda, matplotlib'u kullanarak, sadece matplotlib yüklü olduğunuzu varsaydığımız bir görüntü (Ada Lovelace) elde ettik. Matplotlib bağımlılığını kaldırabilir ve bir PIL görüntüsü dizisi olarak faces'u yeniden tanımlayabilirsiniz.

enter image description here

min_sep

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') 

yüz görüntüleri arasındaki minimum kare mesafedir. min_sep parametresini artırırsanız, yüzler daha uzak aralıklı olacaktır. min_sep'u azaltırsanız, yüzler daha yoğun olarak üst üste binebilir.