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