def picture(
        relationshiplist, picname, picdescription, pixelwidth=None,
        pixelheight=None, nochangeaspect=True, nochangearrowheads=True,
        imagefiledict=None):
    """
    Take a relationshiplist, picture file name, and return a paragraph
    containing the image and an updated relationshiplist
    """
    if imagefiledict is None:
        warn(
            'Using picture() without imagefiledict parameter will be depreca'
            'ted in the future.', PendingDeprecationWarning
        )

    # http://openxmldeveloper.org/articles/462.aspx
    # Create an image. Size may be specified, otherwise it will based on the
    # pixel size of image. Return a paragraph containing the picture

    # Set relationship ID to that of the image or the first available one
    picid = '2'
    picpath = abspath(picname)

    if imagefiledict is not None:
        # Keep track of the image files in a separate dictionary so they don't
        # need to be copied into the template directory
        if picpath not in imagefiledict:
            picrelid = 'rId' + str(len(relationshiplist) + 1)
            imagefiledict[picpath] = picrelid

            relationshiplist.append([
                'http://schemas.openxmlformats.org/officeDocument/2006/relat'
                'ionships/image',
                'media/%s_%s' % (picrelid, basename(picpath))
            ])
        else:
            picrelid = imagefiledict[picpath]
    else:
        # Copy files into template directory for backwards compatibility
        # Images still accumulate in the template directory this way
        picrelid = 'rId' + str(len(relationshiplist) + 1)

        relationshiplist.append([
            'http://schemas.openxmlformats.org/officeDocument/2006/relations'
            'hips/image', 'media/' + picname
        ])

        media_dir = join(template_dir, 'word', 'media')
        if not os.path.isdir(media_dir):
            os.mkdir(media_dir)
        shutil.copyfile(picname, join(media_dir, picname))

    image = Image.open(picpath)

    # Extract EXIF data, if available
    try:
        exif = image._getexif()
        exif = {} if exif is None else exif
    except:
        exif = {}

    imageExif = {}
    for tag, value in exif.items():
        imageExif[TAGS.get(tag, tag)] = value

    imageOrientation = imageExif.get('Orientation', 1)
    imageAngle = {
        1: 0, 2: 0, 3: 180, 4: 0, 5: 90, 6: 90, 7: 270, 8: 270
    }[imageOrientation]
    imageFlipH = 'true' if imageOrientation in (2, 5, 7) else 'false'
    imageFlipV = 'true' if imageOrientation == 4 else 'false'

    # Check if the user has specified a size
    if not pixelwidth or not pixelheight:
        # If not, get info from the picture itself
        pixelwidth, pixelheight = image.size[0:2]

    # Swap width and height if necessary
    if imageOrientation in (5, 6, 7, 8):
        pixelwidth, pixelheight = pixelheight, pixelwidth

    # OpenXML measures on-screen objects in English Metric Units
    # 1cm = 36000 EMUs
    emuperpixel = 12700
    width = str(pixelwidth * emuperpixel)
    height = str(pixelheight * emuperpixel)

    # There are 3 main elements inside a picture
    # 1. The Blipfill - specifies how the image fills the picture area
    #    (stretch, tile, etc.)
    blipfill = makeelement('blipFill', nsprefix='pic')
    blipfill.append(makeelement('blip', nsprefix='a', attrnsprefix='r',
                    attributes={'embed': picrelid}))
    stretch = makeelement('stretch', nsprefix='a')
    stretch.append(makeelement('fillRect', nsprefix='a'))
    blipfill.append(makeelement('srcRect', nsprefix='a'))
    blipfill.append(stretch)

    # 2. The non visual picture properties
    nvpicpr = makeelement('nvPicPr', nsprefix='pic')
    cnvpr = makeelement(
        'cNvPr', nsprefix='pic',
        attributes={'id': '0', 'name': 'Picture 1', 'descr': picdescription}
    )
    nvpicpr.append(cnvpr)
    cnvpicpr = makeelement('cNvPicPr', nsprefix='pic')
    cnvpicpr.append(makeelement(
        'picLocks', nsprefix='a',
        attributes={'noChangeAspect': str(int(nochangeaspect)),
                    'noChangeArrowheads': str(int(nochangearrowheads))}))
    nvpicpr.append(cnvpicpr)

    # 3. The Shape properties
    sppr = makeelement('spPr', nsprefix='pic', attributes={'bwMode': 'auto'})
    xfrm = makeelement(
        'xfrm', nsprefix='a', attributes={
            'rot': str(imageAngle * 60000), 'flipH': imageFlipH,
            'flipV': imageFlipV
        }
    )
    xfrm.append(
        makeelement('off', nsprefix='a', attributes={'x': '0', 'y': '0'})
    )
    xfrm.append(
        makeelement(
            'ext', nsprefix='a', attributes={'cx': width, 'cy': height}
        )
    )
    prstgeom = makeelement(
        'prstGeom', nsprefix='a', attributes={'prst': 'rect'}
    )
    prstgeom.append(makeelement('avLst', nsprefix='a'))
    sppr.append(xfrm)
    sppr.append(prstgeom)

    # Add our 3 parts to the picture element
    pic = makeelement('pic', nsprefix='pic')
    pic.append(nvpicpr)
    pic.append(blipfill)
    pic.append(sppr)

    # Now make the supporting elements
    # The following sequence is just: make element, then add its children
    graphicdata = makeelement(
        'graphicData', nsprefix='a',
        attributes={'uri': ('http://schemas.openxmlformats.org/drawingml/200'
                            '6/picture')})
    graphicdata.append(pic)
    graphic = makeelement('graphic', nsprefix='a')
    graphic.append(graphicdata)

    framelocks = makeelement('graphicFrameLocks', nsprefix='a',
                             attributes={'noChangeAspect': '1'})
    framepr = makeelement('cNvGraphicFramePr', nsprefix='wp')
    framepr.append(framelocks)
    docpr = makeelement('docPr', nsprefix='wp',
                        attributes={'id': picid, 'name': 'Picture 1',
                                    'descr': picdescription})
    effectextent = makeelement('effectExtent', nsprefix='wp',
                               attributes={'l': '25400', 't': '0', 'r': '0',
                                           'b': '0'})
    extent = makeelement('extent', nsprefix='wp',
                         attributes={'cx': width, 'cy': height})
    inline = makeelement('inline', attributes={'distT': "0", 'distB': "0",
                                               'distL': "0", 'distR': "0"},
                         nsprefix='wp')
    inline.append(extent)
    inline.append(effectextent)
    inline.append(docpr)
    inline.append(framepr)
    inline.append(graphic)
    drawing = makeelement('drawing')
    drawing.append(inline)
    run = makeelement('r')
    run.append(drawing)
    paragraph = makeelement('p')
    paragraph.append(run)

    if imagefiledict is not None:
        return relationshiplist, paragraph, imagefiledict
    else:
        return relationshiplist, paragraph
def picture ( relationshiplist , picname , picdescription , pixelwidth = None , pixelheight = None , nochangeaspect = True , nochangearrowheads = True , imagefiledict = None ) : if imagefiledict is None : warn ( 'Using picture() without imagefiledict parameter will be depreca' 'ted in the future.' , PendingDeprecationWarning ) picid = '2' picpath = abspath ( picname ) if imagefiledict is not None : if picpath not in imagefiledict : picrelid = 'rId' + str ( len ( relationshiplist ) + 1 ) imagefiledict [ picpath ] = picrelid relationshiplist . append ( [ 'http://schemas.openxmlformats.org/officeDocument/2006/relat' 'ionships/image' , 'media/%s_%s' % ( picrelid , basename ( picpath ) ) ] ) else : picrelid = imagefiledict [ picpath ] else : picrelid = 'rId' + str ( len ( relationshiplist ) + 1 ) relationshiplist . append ( [ 'http://schemas.openxmlformats.org/officeDocument/2006/relations' 'hips/image' , 'media/' + picname ] ) media_dir = join ( template_dir , 'word' , 'media' ) if not os . path . isdir ( media_dir ) : os . mkdir ( media_dir ) shutil . copyfile ( picname , join ( media_dir , picname ) ) image = Image . open ( picpath ) try : exif = image . _getexif ( ) exif = { } if exif is None else exif except : exif = { } imageExif = { } for tag , value in exif . items ( ) : imageExif [ TAGS . get ( tag , tag ) ] = value imageOrientation = imageExif . get ( 'Orientation' , 1 ) imageAngle = { 1 : 0 , 2 : 0 , 3 : 180 , 4 : 0 , 5 : 90 , 6 : 90 , 7 : 270 , 8 : 270 } [ imageOrientation ] imageFlipH = 'true' if imageOrientation in ( 2 , 5 , 7 ) else 'false' imageFlipV = 'true' if imageOrientation == 4 else 'false' if not pixelwidth or not pixelheight : pixelwidth , pixelheight = image . size [ 0 : 2 ] if imageOrientation in ( 5 , 6 , 7 , 8 ) : pixelwidth , pixelheight = pixelheight , pixelwidth emuperpixel = 12700 width = str ( pixelwidth * emuperpixel ) height = str ( pixelheight * emuperpixel ) blipfill = makeelement ( 'blipFill' , nsprefix = 'pic' ) blipfill . append ( makeelement ( 'blip' , nsprefix = 'a' , attrnsprefix = 'r' , attributes = { 'embed' : picrelid } ) ) stretch = makeelement ( 'stretch' , nsprefix = 'a' ) stretch . append ( makeelement ( 'fillRect' , nsprefix = 'a' ) ) blipfill . append ( makeelement ( 'srcRect' , nsprefix = 'a' ) ) blipfill . append ( stretch ) nvpicpr = makeelement ( 'nvPicPr' , nsprefix = 'pic' ) cnvpr = makeelement ( 'cNvPr' , nsprefix = 'pic' , attributes = { 'id' : '0' , 'name' : 'Picture 1' , 'descr' : picdescription } ) nvpicpr . append ( cnvpr ) cnvpicpr = makeelement ( 'cNvPicPr' , nsprefix = 'pic' ) cnvpicpr . append ( makeelement ( 'picLocks' , nsprefix = 'a' , attributes = { 'noChangeAspect' : str ( int ( nochangeaspect ) ) , 'noChangeArrowheads' : str ( int ( nochangearrowheads ) ) } ) ) nvpicpr . append ( cnvpicpr ) sppr = makeelement ( 'spPr' , nsprefix = 'pic' , attributes = { 'bwMode' : 'auto' } ) xfrm = makeelement ( 'xfrm' , nsprefix = 'a' , attributes = { 'rot' : str ( imageAngle * 60000 ) , 'flipH' : imageFlipH , 'flipV' : imageFlipV } ) xfrm . append ( makeelement ( 'off' , nsprefix = 'a' , attributes = { 'x' : '0' , 'y' : '0' } ) ) xfrm . append ( makeelement ( 'ext' , nsprefix = 'a' , attributes = { 'cx' : width , 'cy' : height } ) ) prstgeom = makeelement ( 'prstGeom' , nsprefix = 'a' , attributes = { 'prst' : 'rect' } ) prstgeom . append ( makeelement ( 'avLst' , nsprefix = 'a' ) ) sppr . append ( xfrm ) sppr . append ( prstgeom ) pic = makeelement ( 'pic' , nsprefix = 'pic' ) pic . append ( nvpicpr ) pic . append ( blipfill ) pic . append ( sppr ) graphicdata = makeelement ( 'graphicData' , nsprefix = 'a' , attributes = { 'uri' : ( 'http://schemas.openxmlformats.org/drawingml/200' '6/picture' ) } ) graphicdata . append ( pic ) graphic = makeelement ( 'graphic' , nsprefix = 'a' ) graphic . append ( graphicdata ) framelocks = makeelement ( 'graphicFrameLocks' , nsprefix = 'a' , attributes = { 'noChangeAspect' : '1' } ) framepr = makeelement ( 'cNvGraphicFramePr' , nsprefix = 'wp' ) framepr . append ( framelocks ) docpr = makeelement ( 'docPr' , nsprefix = 'wp' , attributes = { 'id' : picid , 'name' : 'Picture 1' , 'descr' : picdescription } ) effectextent = makeelement ( 'effectExtent' , nsprefix = 'wp' , attributes = { 'l' : '25400' , 't' : '0' , 'r' : '0' , 'b' : '0' } ) extent = makeelement ( 'extent' , nsprefix = 'wp' , attributes = { 'cx' : width , 'cy' : height } ) inline = makeelement ( 'inline' , attributes = { 'distT' : "0" , 'distB' : "0" , 'distL' : "0" , 'distR' : "0" } , nsprefix = 'wp' ) inline . append ( extent ) inline . append ( effectextent ) inline . append ( docpr ) inline . append ( framepr ) inline . append ( graphic ) drawing = makeelement ( 'drawing' ) drawing . append ( inline ) run = makeelement ( 'r' ) run . append ( drawing ) paragraph = makeelement ( 'p' ) paragraph . append ( run ) if imagefiledict is not None : return relationshiplist , paragraph , imagefiledict else : return relationshiplist , paragraph
Take a relationshiplist, picture file name, and return a paragraph
    containing the image and an updated relationshiplist