使用python获取图像的大小(NEF和jpeg)

2024-09-28 21:33:49 发布

您现在位置:Python中文网/ 问答频道 /正文

当我用我的尼康D5100拍摄照片时,我同时用原始(.NEF)和jpeg格式拍摄。大多数时候我不使用原始图像,但有时我会使用。在

为了便于标记和选择图像,我想自动将原始图像移动到不同的位置。作为python脚本中移动原始图像的检查,我希望将jpeg的图像分辨率与原始分辨率进行比较。到目前为止,我还没有找到一个方法可以为原始图像和jpeg图像返回相同的大小。在

以下是我尝试使用Python的方法的摘要:

from PIL import Image as PIL_Image
from wand.image import Image as wand_Image
import imageio
from PIL.ExifTags import TAGS
import exifread
from collections import namedtuple


def get_exif(fname):
    # http://www.blog.pythonlibrary.org/2010/03/28/getting-photo-metadata-exif-using-python/
    ret = {}
    i = PIL_Image.open(fname)
    info = i._getexif()
    for tag, value in info.items():
        decoded = TAGS.get(tag, tag)
        ret[decoded] = value
    return ret


def get_imagesize_PIL(fname):
    with PIL_Image.open(fname) as im:
        return im.size


def get_imagesize_PIL2(fname):
    exif = get_exif(fname)
    return exif['ExifImageHeight'], exif['ExifImageWidth']


def get_imagesize_PIL3(fname):
    with PIL_Image.open(fname) as im:
        return im.info


def get_imagesize_imageioraw(fname):
    return imageio.imread(fname, "raw").shape[:-1]


def get_imagesize_imageio(fname):
    return imageio.imread(fname).shape[:-1]


def get_imagesize_exifread(fname):  # http://stackoverflow.com/a/18027454/1562285
    exif = exifread.process_file(open(fname, 'rb'), strict=True)
    return exif['Image XResolution'], exif['Image YResolution']


def get_imagesize_exifread2(fname):
    exif = exifread.process_file(open(fname, 'rb'), strict=True)
    return exif['Image ImageLength'], exif['Image ImageWidth']


def get_imagesize_exifread3(fname):
    exif = exifread.process_file(open(fname, 'rb'), strict=True)
    return exif['MakerNote CropHiSpeed']


def get_imagesize_exifread4(fname):
    exif = exifread.process_file(open(fname, 'rb'), strict=True)
    return exif['EXIF ExifImageLength'], exif['EXIF ExifImageWidth']


def get_imagesize_wand(fname):
    with wand_Image(filename=fname) as img:
        return img.size


def get_imagesize_wand2(fname):
    with wand_Image(filename=fname) as img:
        return img.page


# def get_imagesize_wand3(fname):
#     with wand_Image(filename=fname) as img:
#         return img.info


def get_imagesize_libraw(fname):
    with rawkit_Raw(filename=fname) as raw:
        print(raw.Metadata.height, raw.Metadata.width)

def create_eval(fmethod, fname):
    try:
        eval_str = "get_imagesize_%s('%s')" % (fmethod, fname)
        # print(eval_str)
        return eval(eval_str)
    except BaseException as e:
        return str(e)


if __name__ == '__main__':

    file_nt = namedtuple("image_file", "filename tag")
    filetypes = list()
    filetypes.append(file_nt("20120917_131155 DSC_0159.JPG", "jpeg"))
    filetypes.append(file_nt("20120917_131155 DSC_0159.NEF", "nef"))
    # filetypes.append(file_nt("20120917_131155 DSC_0159.xmp", "xmp"))
    # @TODO: add method to check into xmp?

    methods = [
        "PIL",
        "PIL2",
        "PIL3",
        "imageioraw",
        "imageio",
        "exifread",
        "exifread2",
        "exifread3",
        "exifread4",
        "wand",
        "wand2",
        "libraw",
    ]

    for method in methods:
        for filetype in filetypes:
            print("%s %s: %s" % (filetype.tag, method, repr(create_eval(method, filetype.filename))))
# @TODO: add timers to check the fastest method

有了这个结果

^{pr2}$

返回160x120的可能是嵌入式预览图像

Windows资源管理器似乎找到了正确的维度 screenshot

我也试过rawkit,但它似乎找不到天秤座。我找不到关于如何“安装”libraw的明确说明,但我尝试将其命名为图书馆.dll或者原始.dll进入“C:\Anaconda3\Library\bin”,当我尝试

In[3]: ctypes.util.find_library("libraw")
Out[3]: 
'C:\\Anaconda3\\Library\\bin\\libraw.dll'
In[4]: ctypes.util.find_library("Raw")
Out[4]: 
'C:\\Anaconda3\\Library\\bin\\Raw.dll'

它似乎找到了。在

有人知道我能用什么方法吗?jpeg和NEF图像的方法不一定相同,但这是受欢迎的。在

目前,性能不是关键问题,但速度越快越好

代码和示例图像可以在my github repo中找到


Tags: 图像imageimportgetreturnpildefas
2条回答

ImageMagick标识如下:

identify sign.jpg 

输出

^{pr2}$

对于NEF:

identify ~/Desktop/*NEF

输出

/Users/... NEF 4948x3280 4948x3280+0+0 16-bit sRGB 75.99MB 0.010u 0:00.009

由于this postP,我找到了一个使用win32com的不同解决方案

from pprint import pprint
import win32com.client
import os
import re
from pathlib import Path


# https://bytes.com/topic/python/answers/802917-finding-file-details

def _get_dimensions_subdir(folder_name):
    sh = win32com.client.Dispatch('Shell.Application')
    ns = sh.NameSpace(folder_name)
    results = {}
    for c in range(0, 255):
        colname = ns.GetDetailsOf(None, c)
        if colname == 'Dimensions':
            for i in ns.Items():
                dimensions = ns.GetDetailsOf(i, c)
                if dimensions:
                    results[ns.GetDetailsOf(i, 0)] = _parse_dimensions(dimensions)
    return results


dim_pat = re.compile("(\d+) x (\d+)")


def _parse_dimensions(dim):
    x, y = dim_pat.findall(dim)[0]
    return int(x), int(y)


def get_combined_results(subdirs, src_path):
    for subdir in subdirs:
        dim = _get_dimensions_subdir(str(subdir))
        if dim:
            yield str(subdir.relative_to(src_path)), dim


if __name__ == '__main__':
    DATA_DIR = Path(".")
    subdirs = DATA_DIR.glob("**")

    results = get_combined_results(subdirs, DATA_DIR)
    pprint(dict(results))

相关问题 更多 >