How to use PIL to resize and apply rotation EXIF information to the file?

前端 未结 3 1049
轮回少年
轮回少年 2020-12-07 19:36

I am trying to use Python to resize picture. With my camera, files are all written is landscape way.

The exif information handle a tag to ask the image viewer to rot

3条回答
  •  天涯浪人
    2020-12-07 19:42

    I finally used pyexiv2, but it is a bit tricky to install on other platforms than GNU.

    #!/usr/bin/python
    # -*- coding: utf-8 -*-
    # Copyright (C) 2008-2009 Rémy HUBSCHER  - http://www.trunat.fr/portfolio/python.html
    
    # This program is free software; you can redistribute it and/or modify
    # it under the terms of the GNU General Public License as published by
    # the Free Software Foundation; either version 2 of the License, or
    # (at your option) any later version.
    
    # This program is distributed in the hope that it will be useful,
    # but WITHOUT ANY WARRANTY; without even the implied warranty of
    # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    # GNU General Public License for more details.
    
    # You should have received a copy of the GNU General Public License along
    # with this program; if not, write to the Free Software Foundation, Inc.,
    # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
    
    # Using :
    #   - Python Imaging Library PIL    http://www.pythonware.com/products/pil/index.htm
    #   - pyexiv2                       http://tilloy.net/dev/pyexiv2/
    
    ###
    # What is doing this script ?
    #
    #  1. Take a directory of picture from a Reflex Camera (Nikon D90 for example)
    #  2. Use the EXIF Orientation information to turn the image
    #  3. Remove the thumbnail from the EXIF Information
    #  4. Create 2 image one maxi map in 600x600, one mini map in 200x200
    #  5. Add a comment with the name of the Author and his Website
    #  6. Copy the EXIF information to the maxi and mini image
    #  7. Name the image files with a meanful name (Date of picture)
    
    import os, sys
    try:
        import Image
    except:
        print "To use this program, you need to install Python Imaging Library - http://www.pythonware.com/products/pil/"
        sys.exit(1)
    
    try:
        import pyexiv2
    except:
        print "To use this program, you need to install pyexiv2 - http://tilloy.net/dev/pyexiv2/"
        sys.exit(1)
    
    ############# Configuration ##############
    size_mini = 200, 200
    size_maxi = 1024, 1024
    
    # Information about the Photograph should be in ASCII
    COPYRIGHT="Remy Hubscher - http://www.trunat.fr/"
    ARTIST="Remy Hubscher"
    ##########################################
    
    def listJPEG(directory):
        "Retourn a list of the JPEG files in the directory"
        fileList = [os.path.normcase(f) for f in os.listdir(directory)]
        fileList = [f for f in fileList if os.path.splitext(f)[1]  in ('.jpg', '.JPG')]
        fileList.sort()
        return fileList
    
    def _mkdir(newdir):
        """
        works the way a good mkdir should :)
          - already exists, silently complete
          - regular file in the way, raise an exception
          - parent directory(ies) does not exist, make them as well
        """
        if os.path.isdir(newdir):
            pass
        elif os.path.isfile(newdir):
            raise OSError("a file with the same name as the desired " \
                          "dir, '%s', already exists." % newdir)
        else:
            head, tail = os.path.split(newdir)
            if head and not os.path.isdir(head):
                _mkdir(head)
            if tail:
                os.mkdir(newdir)
    
    if len(sys.argv) < 3:
        print "USAGE : python %s indir outdir [comment]" % sys.argv[0]
        exit
    
    indir  = sys.argv[1]
    outdir = sys.argv[2]
    
    if len(sys.argv) == 4:
        comment = sys.argv[1]
    else:
        comment = COPYRIGHT
    
    agrandie = os.path.join(outdir, 'agrandie')
    miniature = os.path.join(outdir, 'miniature')
    
    print agrandie, miniature
    
    _mkdir(agrandie)
    _mkdir(miniature)
    
    for infile in listJPEG(indir):
        mini  = os.path.join(miniature, infile)
        grand = os.path.join(agrandie, infile)
        file_path = os.path.join(indir, infile)
    
        image = pyexiv2.Image(file_path)
        image.readMetadata()
    
        # We clean the file and add some information
        image.deleteThumbnail()
    
        image['Exif.Image.Artist'] = ARTIST
        image['Exif.Image.Copyright'] = COPYRIGHT
    
        image.setComment(comment)
    
        # I prefer not to modify the input file
        # image.writeMetadata()
    
        # We look for a meanful name
        if 'Exif.Image.DateTime' in image.exifKeys():
            filename = image['Exif.Image.DateTime'].strftime('%Y-%m-%d_%H-%M-%S.jpg')
            mini  = os.path.join(miniature, filename)
            grand = os.path.join(agrandie, filename)
        else:
            # If no exif information, leave the old name
            mini  = os.path.join(miniature, infile)
            grand = os.path.join(agrandie, infile)
    
        # We create the thumbnail
        #try:
        im = Image.open(file_path)
        im.thumbnail(size_maxi, Image.ANTIALIAS)
    
        # We rotate regarding to the EXIF orientation information
        if 'Exif.Image.Orientation' in image.exifKeys():
            orientation = image['Exif.Image.Orientation']
            if orientation == 1:
                # Nothing
                mirror = im.copy()
            elif orientation == 2:
                # Vertical Mirror
                mirror = im.transpose(Image.FLIP_LEFT_RIGHT)
            elif orientation == 3:
                # Rotation 180°
                mirror = im.transpose(Image.ROTATE_180)
            elif orientation == 4:
                # Horizontal Mirror
                mirror = im.transpose(Image.FLIP_TOP_BOTTOM)
            elif orientation == 5:
                # Horizontal Mirror + Rotation 90° CCW
                mirror = im.transpose(Image.FLIP_TOP_BOTTOM).transpose(Image.ROTATE_90)
            elif orientation == 6:
                # Rotation 270°
                mirror = im.transpose(Image.ROTATE_270)
            elif orientation == 7:
                # Horizontal Mirror + Rotation 270°
                mirror = im.transpose(Image.FLIP_TOP_BOTTOM).transpose(Image.ROTATE_270)
            elif orientation == 8:
                # Rotation 90°
                mirror = im.transpose(Image.ROTATE_90)
    
            # No more Orientation information
            image['Exif.Image.Orientation'] = 1
        else:
            # No EXIF information, the user has to do it
            mirror = im.copy()
    
        mirror.save(grand, "JPEG", quality=85)
        img_grand = pyexiv2.Image(grand)
        img_grand.readMetadata()
        image.copyMetadataTo(img_grand)
        img_grand.writeMetadata()
        print grand
    
        mirror.thumbnail(size_mini, Image.ANTIALIAS)
        mirror.save(mini, "JPEG", quality=85)
        img_mini = pyexiv2.Image(mini)
        img_mini.readMetadata()
        image.copyMetadataTo(img_mini)
        img_mini.writeMetadata()
        print mini
    
        print
    

    If you see something that could be improved (except the fact that it is still for Python 2.5) then please let me know.

提交回复
热议问题