1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 import os
19 import cairo
20 import pango
21 import pangocairo
22
23 from flumotion.configure import configure
24
25 __version__ = "$Rev$"
26 FONT = 'sans'
27 FONT_PROPS = 'normal 22'
28 TEXT_XOFFSET = 6
29 TEXT_YOFFSET = 6
30 BORDER = 4
31 FONT_SIZE = 22528
32
33
34 -def generateOverlay(text,
35 font,
36 showFlumotion,
37 showCC,
38 showXiph,
39 width, height):
40 """Generate an transparent image with text + logotypes rendered on top
41 of it suitable for mixing into a video stream
42 @param text: text to put in the top left corner
43 @type text: str
44 @param font: font description used to render the text
45 @type: str
46 @param showFlumotion: if we should show the flumotion logo
47 @type showFlumotion: bool
48 @param showCC: if we should show the Creative Common logo
49 @type showCC: bool
50 @param showXiph: if we should show the xiph logo
51 @type showXiph: bool
52 @param width: width of the image to generate
53 @type width: int
54 @param height: height of the image to generate
55 @type height: int
56 @returns: raw image and if images or if text overflowed
57 @rtype: 3 sized tuple of string and 2 booleans
58 """
59 from cairo import ImageSurface
60 from cairo import Context
61
62 image = ImageSurface(cairo.FORMAT_ARGB32, width, height)
63 context = Context(image)
64
65 subImages = []
66 if showXiph:
67 subImages.append(os.path.join(configure.imagedir, '36x36', 'xiph.png'))
68 if showCC:
69 subImages.append(os.path.join(configure.imagedir, '36x36', 'cc.png'))
70 if showFlumotion:
71 subImages.append(os.path.join(configure.imagedir, '36x36',
72 'fluendo.png'))
73
74 imagesOverflowed = False
75
76 offsetX = BORDER
77 for subPath in subImages:
78 sub = ImageSurface.create_from_png(subPath)
79 subX = sub.get_width()
80 subY = sub.get_height()
81 offsetY = height - subY - BORDER
82 context.set_source_surface(sub, offsetX, offsetY)
83 context.paint()
84 if (offsetX + subX) > width:
85 imagesOverflowed = True
86 offsetX += subX + BORDER
87
88 textOverflowed = False
89 if text:
90 pcContext = pangocairo.CairoContext(context)
91 pangoLayout = pcContext.create_layout()
92 if font is not None:
93 font = pango.FontDescription(font)
94 if not font.get_family() or \
95 not font.get_family().lower() in [family.get_name().lower()
96 for family in pangoLayout.get_context().list_families()]:
97 font.set_family(FONT)
98 if font.get_size() == 0:
99 font.set_size(FONT_SIZE)
100 else:
101 font = pango.FontDescription('%s %s' % (FONT, FONT_PROPS))
102 pangoLayout.set_font_description(font)
103
104 context.move_to(TEXT_XOFFSET+2, TEXT_YOFFSET+2)
105 pangoLayout.set_markup('<span foreground="black" >%s</span>' % text)
106 pcContext.show_layout(pangoLayout)
107 context.move_to(TEXT_XOFFSET, TEXT_YOFFSET)
108 pangoLayout.set_markup('<span foreground="white" >%s</span>' % text)
109 pcContext.show_layout(pangoLayout)
110
111 textWidth, textHeight = pangoLayout.get_pixel_size()
112 if textWidth > width:
113 textOverflowed = True
114
115 if cairo.version < '1.2.6':
116 buf = image.get_data_as_rgba()
117 else:
118 buf = image.get_data()
119
120 return buf, imagesOverflowed, textOverflowed
121
122 if __name__ == '__main__':
123 print generateOverlay('Testing', 'sans normal 22',
124 True, True, True, 128, 196)[0]
125