Wie PIL verwenden, um eine Drehung EXIF-Informationen in die Datei der Größe und anwenden?
-
05-07-2019 - |
Frage
Ich versuche, Python zu verwenden Bild zu ändern. Mit meiner Kamera werden alle Dateien geschrieben ist Landschaft Art und Weise.
Die EXIF-Informationen einen Tag verarbeiten die Bildbetrachter zu fragen, in der einen oder anderen zu drehen. Da die meisten der Browser diese Information nicht verstehen, möchte ich das Bild mit dieser EXIF-Informationen und durch jede andere EXIF-Informationen drehen.
Wissen Sie, wie ich tun kann, dass die Verwendung von Python?
die EXIF.py Quellcode lesen, fand ich etwas wie folgt aus:
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'})
Wie kann ich diese Informationen und PIL sie anzuwenden?
Lösung
Ich habe schließlich pyexiv2 , aber es ist ein bisschen schwierig, auf anderen Plattformen als GNU zu installieren.
#!/usr/bin/python
# -*- coding: utf-8 -*-
# Copyright (C) 2008-2009 Rémy HUBSCHER <natim@users.sf.net> - 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
Wenn Sie etwas sehen, das (mit Ausnahme der Tatsache, dass es nach wie vor für Python 2.5 ist) verbessert werden könnte, dann lass es mich wissen.
Andere Tipps
Obwohl PIL EXIF-Metadaten lesen kann, es verfügt nicht über die Fähigkeit, sie zu ändern und es zurück in eine Bilddatei zu schreiben.
Eine bessere Wahl ist die pyexiv2 Bibliothek. Mit dieser Bibliothek ist es ganz einfach Flip der Ausrichtung des Fotos. Hier ein Beispiel:
import sys
import pyexiv2
image = pyexiv2.Image(sys.argv[1])
image.readMetadata()
image['Exif.Image.Orientation'] = 6
image.writeMetadata()
Hier wird die Orientierung bis 6, entsprechend "gedreht um 90 CW".
Als erstes müssen Sie sicherstellen, dass Ihre Kamera tatsächlich einen Rotationssensor hat. Die meisten Kameramodelle ohne Sensor einfach die Orientierung Tag bis 1 (horizontal) gesetzt für alle Bilder.
Dann empfehle ich pyexiv2 und pyjpegtran in Ihrem Fall zu verwenden. PIL unterstützt keine lossless Rotation, die die Domäne des pyjpegtran ist. pyexiv2 ist eine Bibliothek, die Sie Metadaten von einem Bild zum anderen kopieren (ich glaube, der Methodenname ist copyMetadata).
Sind Sie sicher, dass Sie nicht möchten, um Ihre Fotos skalieren, bevor sie im Browser angezeigt wird? A 8 Megapixel JPEG viel zu groß für das Browser-Fenster und wird endlos Ladezeiten führen.