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