%PDF- %PDF-
Direktori : /usr/share/doc/python3-freetype/examples/ |
Current File : //usr/share/doc/python3-freetype/examples/wordle.py |
#!/usr/bin/env python # -*- coding: utf-8 -*- # ----------------------------------------------------------------------------- # # FreeType high-level python API - Copyright 2011-2015 Nicolas P. Rougier # Distributed under the terms of the new BSD license. # # ----------------------------------------------------------------------------- import math import numpy as np from freetype import * import matplotlib.pyplot as plt def make_label(text, filename, size=12, angle=0): ''' Parameters: ----------- text : string Text to be displayed filename : string Path to a font size : int Font size in 1/64th points angle : float Text angle in degrees ''' face = Face(filename) face.set_char_size( size*64 ) angle = (angle/180.0)*math.pi matrix = FT_Matrix( (int)( math.cos( angle ) * 0x10000 ), (int)(-math.sin( angle ) * 0x10000 ), (int)( math.sin( angle ) * 0x10000 ), (int)( math.cos( angle ) * 0x10000 )) flags = FT_LOAD_RENDER pen = FT_Vector(0,0) FT_Set_Transform( face._FT_Face, byref(matrix), byref(pen) ) previous = 0 xmin, xmax = 0, 0 ymin, ymax = 0, 0 for c in text: face.load_char(c, flags) kerning = face.get_kerning(previous, c) previous = c bitmap = face.glyph.bitmap pitch = face.glyph.bitmap.pitch width = face.glyph.bitmap.width rows = face.glyph.bitmap.rows top = face.glyph.bitmap_top left = face.glyph.bitmap_left pen.x += kerning.x x0 = (pen.x >> 6) + left x1 = x0 + width y0 = (pen.y >> 6) - (rows - top) y1 = y0 + rows xmin, xmax = min(xmin, x0), max(xmax, x1) ymin, ymax = min(ymin, y0), max(ymax, y1) pen.x += face.glyph.advance.x pen.y += face.glyph.advance.y L = np.zeros((ymax-ymin, xmax-xmin),dtype=np.ubyte) previous = 0 pen.x, pen.y = 0, 0 for c in text: face.load_char(c, flags) kerning = face.get_kerning(previous, c) previous = c bitmap = face.glyph.bitmap pitch = face.glyph.bitmap.pitch width = face.glyph.bitmap.width rows = face.glyph.bitmap.rows top = face.glyph.bitmap_top left = face.glyph.bitmap_left pen.x += kerning.x x = (pen.x >> 6) - xmin + left y = (pen.y >> 6) - ymin - (rows - top) data = [] for j in range(rows): data.extend(bitmap.buffer[j*pitch:j*pitch+width]) if len(data): Z = np.array(data,dtype=np.ubyte).reshape(rows, width) L[y:y+rows,x:x+width] |= Z[::-1,::1] pen.x += face.glyph.advance.x pen.y += face.glyph.advance.y return L if __name__ == '__main__': from PIL import Image n_words = 100 H, W, dpi = 600, 800, 72.0 I = np.zeros((H, W, 3), dtype=np.ubyte) S = np.random.normal(0,1,n_words) S = (S-S.min())/(S.max()-S.min()) S = np.sort(1-np.sqrt(S))[::-1] sizes = (12 + S*48).astype(int).tolist() def spiral(): eccentricity = 1.5 radius = 8 step = 0.1 t = 0 while True: t += step yield eccentricity*radius*t*math.cos(t), radius*t*math.sin(t) fails = 0 for size in sizes: angle = np.random.randint(-25,25) L = make_label('Hello', './Vera.ttf', size, angle=angle) h,w = L.shape if h < H and w < W: x0 = W//2 + (np.random.uniform()-.1)*50 y0 = H//2 + (np.random.uniform()-.1)*50 for dx,dy in spiral(): c = .25+.75*np.random.random() x = int(x0+dx) y = int(y0+dy) if x <= w//2 or y <= h//2 or x >= (W-w//2) or y >= (H-h//2): fails += 1 break if (I[y-h//2:y-h//2+h, x-w//2:x-w//2+w,0] * L).sum() == 0: I[y-h//2:y-h//2+h, x-w//2:x-w//2+w,0] |= (c * L).astype('ubyte') I[y-h//2:y-h//2+h, x-w//2:x-w//2+w,1] |= (c * L).astype('ubyte') I[y-h//2:y-h//2+h, x-w//2:x-w//2+w,2] |= (c * L).astype('ubyte') break print ("Number of fails: {}".format(fails)) fig = plt.figure(figsize=(W/dpi,H/dpi), dpi=dpi) ax = fig.add_axes([0,0,1,1], frameon=False) ax.imshow(I, interpolation='nearest', cmap=plt.cm.gray, origin='upper') #plt.axis('off') plt.show() I = Image.fromarray(I[::-1,::1,::1], mode='RGB') I.save('wordle.png')