Python 如何使用PIL调整文件大小并将旋转EXIF信息应用于文件?
我正在尝试使用Python来调整图片的大小。 使用我的相机,所有文件都是以横向方式写入的 exif信息处理一个标记,要求图像查看器以某种方式旋转。 由于大多数浏览器不理解此信息,我想使用此EXIF信息旋转图像,并保留其他所有EXIF信息 你知道我如何使用Python实现这一点吗 在阅读EXIF.py源代码时,我发现如下内容:Python 如何使用PIL调整文件大小并将旋转EXIF信息应用于文件?,python,jpeg,python-imaging-library,rotation,exif,Python,Jpeg,Python Imaging Library,Rotation,Exif,我正在尝试使用Python来调整图片的大小。 使用我的相机,所有文件都是以横向方式写入的 exif信息处理一个标记,要求图像查看器以某种方式旋转。 由于大多数浏览器不理解此信息,我想使用此EXIF信息旋转图像,并保留其他所有EXIF信息 你知道我如何使用Python实现这一点吗 在阅读EXIF.py源代码时,我发现如下内容: 0x0112: ('Orientation', {1: 'Horizontal (normal)', 2: 'Mirrored hor
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'})
如何使用这些信息和PIL来应用它?首先,您必须确保您的相机实际上有一个旋转传感器。大多数没有传感器的相机型号只是将所有图片的方向标签设置为1(水平) 然后我建议在您的案例中使用pyexiv2和pyjpetran。PIL不支持无损旋转,这是pyjpegtran的领域。pyexiv2是一个库,允许您将元数据从一个映像复制到另一个映像(我认为方法名为copyMetadata)
在浏览器中显示照片之前,是否确实不想调整照片的大小?800万像素的JPEG对于浏览器窗口来说太大,会导致无休止的加载时间。尽管PIL可以读取EXIF元数据,但它无法更改并将其写回图像文件 更好的选择是图书馆。使用此库,翻转照片的方向非常简单。下面是一个例子:
import sys
import pyexiv2
image = pyexiv2.Image(sys.argv[1])
image.readMetadata()
image['Exif.Image.Orientation'] = 6
image.writeMetadata()
这将方向设置为6,对应于“旋转90 CW”。我最后使用了,但在GNU以外的其他平台上安装有点棘手
#!/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
#/usr/bin/python
#-*-编码:utf-8-*-
#版权所有(C)2008-2009雷米·哈伯舍尔-http://www.trunat.fr/portfolio/python.html
#这个程序是自由软件;您可以重新分发和/或修改它
#它是根据GNU通用公共许可证的条款发布的
自由软件基金会;许可证的第2版,或
#(由您选择)任何更高版本。
#这个节目的发布是希望它会有用,
#但无任何保证;甚至没有任何关于
#适销性或适合某一特定目的。见
#有关更多详细信息,请参阅GNU通用公共许可证。
#您应该已经收到了GNU通用公共许可证的副本
#有了这个节目,;如果没有,请写信给自由软件基金会,
#美国马萨诸塞州波士顿富兰克林街51号五楼02110-1301。
#使用:
#-Python图像库PILhttp://www.pythonware.com/products/pil/index.htm
#-pyexiv2http://tilloy.net/dev/pyexiv2/
###
#这个脚本在做什么?
#
# 1. 从反光照相机(例如尼康D90)拍摄照片目录
# 2. 使用EXIF方向信息旋转图像
# 3. 从EXIF信息中删除缩略图
# 4. 创建两个图像一个600x600的最大贴图,一个200x200的最小贴图
# 5. 添加一条带有作者姓名及其网站的评论
# 6. 将EXIF信息复制到最大和最小映像
# 7. 使用有意义的名称(图片日期)命名图像文件
导入操作系统,系统
尝试:
导入图像
除:
打印“要使用此程序,您需要安装Python映像库-http://www.pythonware.com/products/pil/"
系统出口(1)
尝试:
导入pyexiv2
除:
打印“要使用此程序,您需要安装pyexiv2-http://tilloy.net/dev/pyexiv2/"
系统出口(1)
#############配置##############
尺寸_mini=200200
大小_最大值=1024,1024
#有关照片的信息应使用ASCII码
版权所有=“Remy Hubscher-http://www.trunat.fr/"
艺术家=“Remy Hubscher”
##########################################
def listJPEG(目录):
“返回目录中JPEG文件的列表”
fileList=[os.path.normcase(f)表示os.listdir(目录)中的f]
fileList=[f表示文件列表中的f,如果('.jpg','.jpg')中的os.path.splitext(f)[1]
fileList.sort()
返回文件列表
def_mkdir(newdir):
"""
一个好的mkdir应该是这样工作的:)
-已经存在,默默地完成
-常规文件的方式,引发异常
-父目录不存在,请同时创建它们
"""
如果os.path.isdir(newdir):
通过
elif os.path.isfile(newdir):
引发OSError(“与所需文件同名的文件”\
“目录“%s”已存在。“%newdir)
其他:
head,tail=os.path.split(newdir)
如果是head而不是os.path.isdir(head):
_mkdir(主管)
如果是尾部:
os.mkdir(newdir)
如果len(sys.argv)<3:
打印“用法:python%s indir outdir[comment]%sys.argv[0]
出口
indir=sys.argv[1]
outdir=sys.argv[2]
如果len(sys.argv)==4:
comment=sys.argv[1]
其他:
注释=版权
agrandie=os.path.join(outdir,'agrandie')
minimal=os.path.join(outdir,“minimal”)
打印agrandie,微型
_mkdir(阿格兰迪)
_mkdir(微型)
对于listJPEG(indir)中的填充:
mini=os.path.join(mini,infle)
grand=os.path.join(agrandie,infle)
file_path=os.path.join(indir,infle)
image=pyexiv2.image(文件路径)
image.readMetadata()
#我们清理文件并添加一些信息
image.deleteThumbnail()
图像['Exif.image.Artist']=艺术家
图像['Exif.image.Copyright']=版权所有
image.setComment(comment)
#我不想修改输入文件
#image.writeMetadata()文件
#我们寻找一个有意义的名字
如果Image.exifKeys()中的“Exif.Image.DateTime”:
filename=image['Exif.image.DateTime'].strftime(“%Y-%m-%d\u%H-%m-%S.jpg”)
mini=os.path.join(mini,文件名)
grand=os.path.join(agrandie,文件名)
其他:
#如果没有exif信息,请保留旧名称
mini=os.path.join(mini,infle)
grand=os.path.join(agrandie,infle)
#我们创建缩略图
#尝试:
im=Image.open(文件路径)
im.缩略图(最大尺寸,图像