photoalbum.py 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  1. #!/usr/bin/env python
  2. # -*- coding: utf-8 -*-
  3. # Copyright (C) 2007-2009 Søren Roug, European Environment Agency
  4. #
  5. # This is free software. You may redistribute it under the terms
  6. # of the Apache license and the GNU General Public License Version
  7. # 2 or at your option any later version.
  8. #
  9. # This program is distributed in the hope that it will be useful,
  10. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. # GNU General Public License for more details.
  13. #
  14. # You should have received a copy of the GNU General Public
  15. # License along with this program; if not, write to the Free Software
  16. # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  17. #
  18. # Contributor(s):
  19. #
  20. import os,sys,getopt,struct
  21. from cStringIO import StringIO
  22. from odf.opendocument import OpenDocumentPresentation
  23. from odf.style import Style, MasterPage, PageLayout, PageLayoutProperties, \
  24. TextProperties, GraphicProperties, ParagraphProperties, DrawingPageProperties
  25. from odf.text import P
  26. from odf.draw import Page, Frame, TextBox, Image
  27. def getImageInfo(data):
  28. size = len(data)
  29. height = -1
  30. width = -1
  31. w = -1
  32. h = -1
  33. content_type = ''
  34. # handle GIFs
  35. if (size >= 10) and data[:6] in ('GIF87a', 'GIF89a'):
  36. # Check to see if content_type is correct
  37. content_type = 'image/gif'
  38. w, h = struct.unpack("<HH", data[6:10])
  39. width = int(w)
  40. height = int(h)
  41. # See PNG v1.2 spec (http://www.cdrom.com/pub/png/spec/)
  42. # Bytes 0-7 are below, 4-byte chunk length, then 'IHDR'
  43. # and finally the 4-byte width, height
  44. elif ((size >= 24) and (data[:8] == '\211PNG\r\n\032\n')
  45. and (data[12:16] == 'IHDR')):
  46. content_type = 'image/png'
  47. w, h = struct.unpack(">LL", data[16:24])
  48. width = int(w)
  49. height = int(h)
  50. # Maybe this is for an older PNG version.
  51. elif (size >= 16) and (data[:8] == '\211PNG\r\n\032\n'):
  52. # Check to see if we have the right content type
  53. content_type = 'image/png'
  54. w, h = struct.unpack(">LL", data[8:16])
  55. width = int(w)
  56. height = int(h)
  57. # handle JPEGs
  58. elif (size >= 2) and (data[:2] == '\377\330'):
  59. content_type = 'image/jpeg'
  60. jpeg = StringIO(data)
  61. jpeg.read(2)
  62. b = jpeg.read(1)
  63. try:
  64. while (b and ord(b) != 0xDA):
  65. while (ord(b) != 0xFF): b = jpeg.read(1)
  66. while (ord(b) == 0xFF): b = jpeg.read(1)
  67. if (ord(b) >= 0xC0 and ord(b) <= 0xC3):
  68. jpeg.read(3)
  69. h, w = struct.unpack(">HH", jpeg.read(4))
  70. break
  71. else:
  72. jpeg.read(int(struct.unpack(">H", jpeg.read(2))[0])-2)
  73. b = jpeg.read(1)
  74. width = int(w)
  75. height = int(h)
  76. except: pass
  77. return content_type, width, height
  78. def usage():
  79. sys.stderr.write("Usage: %s [-o outputfile] [input-directory]\n" % sys.argv[0])
  80. if __name__ == "__main__":
  81. try:
  82. opts, args = getopt.getopt(sys.argv[1:], "o:", ["output="])
  83. except getopt.GetoptError:
  84. usage()
  85. sys.exit(2)
  86. outputfile = "photoalbum.odp"
  87. for o, a in opts:
  88. if o in ("-o", "--output"):
  89. outputfile = a
  90. if outputfile[-4:] != ".odp": outputfile += ".odp"
  91. doc = OpenDocumentPresentation()
  92. # We must describe the dimensions of the page
  93. pagelayout = PageLayout(name="MyLayout")
  94. doc.automaticstyles.addElement(pagelayout)
  95. pagelayout.addElement(PageLayoutProperties(margin="0pt", pagewidth="800pt",
  96. pageheight="600pt", printorientation="landscape"))
  97. # Style for the title frame of the page
  98. # We set a centered 34pt font with yellowish background
  99. titlestyle = Style(name="MyMaster-title", family="presentation")
  100. titlestyle.addElement(ParagraphProperties(textalign="center"))
  101. titlestyle.addElement(TextProperties(fontsize="34pt"))
  102. titlestyle.addElement(GraphicProperties(fillcolor="#ffff99"))
  103. doc.styles.addElement(titlestyle)
  104. # Style for the photo frame
  105. photostyle = Style(name="MyMaster-photo", family="presentation")
  106. doc.styles.addElement(photostyle)
  107. # Create automatic transition
  108. dpstyle = Style(name="dp1", family="drawing-page")
  109. dpstyle.addElement(DrawingPageProperties(transitiontype="automatic",
  110. transitionstyle="move-from-top", duration="PT5S"))
  111. doc.automaticstyles.addElement(dpstyle)
  112. # Every drawing page must have a master page assigned to it.
  113. masterpage = MasterPage(name="MyMaster", pagelayoutname=pagelayout)
  114. doc.masterstyles.addElement(masterpage)
  115. if len(args) == 0:
  116. pict_dir = "."
  117. else:
  118. pict_dir = args[0]
  119. # Slides
  120. for picture in os.listdir(pict_dir):
  121. try:
  122. pictdata = open(pict_dir + "/" + picture).read()
  123. except:
  124. continue
  125. ct,w,h = getImageInfo(pictdata) # Get dimensions in pixels
  126. if ct != 'image/jpeg':
  127. continue
  128. if w > 720:
  129. h = float(h) * 720.0 / float(w)
  130. w = 720.0
  131. if h > 540.0:
  132. w = float(w) * 540.0 / float(h)
  133. h = 540.0
  134. page = Page(stylename=dpstyle, masterpagename=masterpage)
  135. doc.presentation.addElement(page)
  136. titleframe = Frame(stylename=titlestyle, width="720pt", height="56pt", x="40pt", y="10pt")
  137. page.addElement(titleframe)
  138. textbox = TextBox()
  139. titleframe.addElement(textbox)
  140. textbox.addElement(P(text=picture))
  141. offsetx = 400.0 - w/2.0
  142. photoframe = Frame(stylename=photostyle, width="%fpt" % w, height="%fpt" % h, x="%fpt" % offsetx, y="56pt")
  143. page.addElement(photoframe)
  144. href = doc.addPicture(pict_dir + "/" + picture)
  145. photoframe.addElement(Image(href=href))
  146. doc.save(outputfile)