Estoy tratando de usar Python para cambiar el tamaño de la imagen.
Con mi cámara, los archivos están todos escritos es el camino paisaje.

La información exif de la manija de una etiqueta para pedir el visor de imágenes para que gire en un sentido o en otro.
Dado que la mayoría de que el navegador no entender esta información, quiero girar la imagen utilizando esta información EXIF y manteniendo todos los demás la información EXIF.

¿Sabes cómo puedo hacer que el uso de Python ?

La lectura de la EXIF.py el código fuente, he encontrado algo así como que :

0x0112: ('Orientation',
         {1: 'Horizontal (normal)',
          2: 'Mirrored horizontal',
          3: 'Rotated 180',
          4: 'Mirrored vertical',
          5: 'Mirrored horizontal then rotated 90 CCW',
          6: 'Rotated 90 CW',
          7: 'Mirrored horizontal then rotated 90 CW',
          8: 'Rotated 90 CCW'})

¿Cómo puedo utilizar esta información y el PIL para aplicarlo ?

  • Más información aquí : abc-view.com/articles/article5.html ¿crees que debería utilizar una función con un proceso específico con respecto a este valor ?
  • buena pregunta! Puede PIL gire el JPEG sin pérdida (como jpegtran)? Sin transformaciones sin pérdida, no me gustaría considerar la posibilidad de hacerlo.
InformationsquelleAutor Natim | 2009-10-22

3 Comentarios

  1. 15

    Usé finalmente pyexiv2, pero es un poco difícil de instalar en otras plataformas de GNU.

    #!/usr/bin/python
    # -*- coding: utf-8 -*-
    # Copyright (C) 2008-2009 Rémy HUBSCHER <[email protected]> - 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

    Si ves algo que se podría mejorar (excepto el hecho de que todavía es para Python 2.5), por favor hágamelo saber.

    • Creo que el listJPEG función podría ser un poco más corta si utiliza el módulo de globo para obtener las rutas de los archivos, también hay un sistema operativo.makedirs en la biblioteca estándar que hace que su _mkdir() obsoleto, el bloque de código para escribir el resized JPEGs y la copia de los metadatos deben ser rediseñados para una función de evitar la duplicación de código, tal vez usted quiere adicional parámetros de línea de comandos para ajustar el formato de archivo, etc.
    • Ok, suena bien. Gracias 🙂
    • Estoy un poco tarde a la fiesta aquí, pero StackOverflow respuestas están bajo licencia de cc-wiki, que está en conflicto con el contenido de esta respuesta está bajo la GPL.
    • Sí, pero yo soy el autor de el código, así que puedo hacer lo que quiero con ella ¿no?
    • im.transpose (como im.girar) gira las imágenes en sentido antihorario, por lo que algunos de su código está roto…
    • No es lo que dice la documentación y lo vi con él: effbot.org/imagingbook/introduction.htm#geometrical-transforms
    • bien. De hecho, me miró en el código de C detrás de él…
    • Incluso la copia de los documentos que enlaza: im.rotate(45) # degrees counter-clockwise y después de que There’s no difference in performance or result between transpose(ROTATE) and corresponding rotate operations.
    • Hum, lo siento, no leer su comentario de la derecha, sí lo es en sentido antihorario, pero no es lo que yo hice realmente? im.transpose (como im.gire) gira en imágenes contador a la derecha
    • En el 5º caso (‘Espejo horizontal, a continuación, girar 90 CCW‘): no debe ser im.transpose(Image.FLIP_TOP_BOTTOM).transpose(Image.ROTATE_90) no im.transpose(Image.FLIP_TOP_BOTTOM).transpose(Image.ROTATE_270)
    • Ok gracias me fijo.
    • Yo al principio (erróneamente) el pensamiento de que no era el único caso que no era la correcta y por lo tanto no era lo suficientemente concreta, lo siento por eso 🙂
    • permítanos continuar esta discusión en el chat

  2. 6

    Aunque PIL puede leer los metadatos EXIF, no tiene la capacidad de cambiar y escribir en un archivo de imagen.

    Una mejor opción es la pyexiv2 de la biblioteca. Con esta biblioteca es bastante simple tapa la foto de la orientación. He aquí un ejemplo:

    import sys
    import pyexiv2
    image = pyexiv2.Image(sys.argv[1])
    image.readMetadata()
    image['Exif.Image.Orientation'] = 6
    image.writeMetadata()

    Este define la orientación a 6, correspondiente a la «gira 90 CW».

    • En realidad, la cámara ya se ha fijado el Exif.Imagen.La orientación de la etiqueta, quiero escribir la imagen en la Orientación correcta para habilitar el explorador para mostrar que, incluso si ellos no pueden entender la información EXIF. De todos modos, pyexiv2 es la biblioteca que yo necesitaba. Como se puede ver en mi código detrás.
  3. 2

    Primer lugar, usted tiene que asegurarse de que su cámara tiene un sensor de rotación. La mayoría de los modelos de cámara sin sensor de simplemente establecer la Orientación de la Etiqueta a 1 (Horizontal) de TODAS las imágenes.

    A continuación, recomiendo el uso de pyexiv2 y pyjpegtran en su caso. PIL no admite la rotación sin pérdida, que es el dominio de pyjpegtran. pyexiv2 es una biblioteca que permite la copia de los metadatos de una imagen a otra (creo que el nombre del método es copyMetadata).

    ¿Estás seguro de que no quieres cambiar el tamaño de tus fotos antes de mostrarlos en el navegador? Una de 8 Megapíxeles JPEG es demasiado grande para la ventana del navegador y va a causar interminables tiempos de carga.

    • Como ya he dicho, quiero cambiar el tamaño de la imagen y girar y mantener algunas útil la información EXIF.

Dejar respuesta

Please enter your comment!
Please enter your name here