本文介绍了如何打开TIF(CMYK,16位)图像文件?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个脚本,可以处理许多图像文件(使用Pillow).最近,我注意到我的脚本使用TIF(CMYK/16)格式失败.因此,我创建了一个测试用例.

I have a script that processes dozens of image files (using Pillow). Recently, I've noticed that my script fails with TIF (CMYK/16) format. So I've created a test case.

images = [
    "cmyk-8.tif",
    "cmyk-16.tif",
    "rgb-8.tif",
    "rgb-16.tif",
]

for img_name in images:
    path = img_dir + "\\" + img_name
    try:
        img = Image.open(path)
    except OSError as e:
        print(e)
    else:
        print("success: " + img_name)

这将产生以下输出:

success: cmyk-8.tif
cannot identify image file '...\\cmyk-16.tif'
success: rgb-8.tif
success: rgb-16.tif

所以问题肯定出在TIF(CMYK/16)格式上.

So the problem is definitely with the TIF (CMYK/16) format.

如何首先打开此特定格式,或将其转换为可打开的(?)格式(即RGB/8,RGB/16,CMYK/8),然后再将其打开?

How can I open this specific format, or convert it to a openable(?) format (that is RGB/8, RGB/16, CMYK/8) first, and then open it?

在另一个质量保证中,建议使用GDAL解决该问题.我已经对其进行了尝试(安装GDAL,将其与Python关联,并使其与当前脚本一起使用),但最终放弃了(太麻烦了).因此,我决定只专注于 gdal_translate .

In another QA, GDAL was suggested to solve the problem. I've tried it (install GDAL, associate it with Python, and make it work with the current script), but eventually gave up (too problematic). So I've decided just to focus on gdal_translate.

我已经从 GISInternals ,并尝试进行转换:

I've installed "gdal-203-1911-x64-core.msi" from GISInternals, and tried to do the conversion:

"C:\Program Files\GDAL\gdal_translate.exe" -scale -ot byte -of JPEG "C:\Users\%username%\Documents\GitHub\dump\python\tif-cmyk-16\images\cmyk-16.tif" "cmyk-16.jpg"

但是没有用.我的转换不正确:

but it didn't work. I got incorrect conversion:

我对GDAL不熟悉,因此我必须做错了什么.如何获得正确的转换结果?

I'm not familiar with GDAL, so I must be doing something wrong. How do I get it to do the conversion correct?

这也是cmd输出:

ERROR 1: Can't load requested DLL: C:\Program Files\GDAL\gdalplugins\ogr_MSSQLSpatial.dll
126: The specified module could not be found.

ERROR 1: Can't load requested DLL: C:\Program Files\GDAL\gdalplugins\ogr_MSSQLSpatial.dll
126: The specified module could not be found.

Input file size is 200, 200
0...10...20...30...40...50...60...70...80...90...100 - done.
Press any key to continue . . .

似乎丢失了一些东西,我也不知道错误的转换是否与此有关.

It seems something is missing, and I don't know if the inccorect conversion is related to this.

相关脚本和输出文件可以找到此处.

Related scripts and output files can be found here.

推荐答案

好像其他图像一样,因此,我将重点介绍将16位cmyk tif转换为8位rgb jpeg的方法.我猜想这种方法也将通过一些调整而适用于其他转化.

Seems like the other images are working, so I will focus on the 16 bit cmyk tif conversion to 8 bit rgb jpeg. I guess this approach will apply for other conversions too with a few tweaks.

有几种方法可以将其转换.前两个使用GDAL,因为您曾建议过,最后一种使用libtiff,我认为它更适合您的用例.

Here are a few ways to convert it. The first two uses GDAL since you suggested that, the last approach uses libtiff, which i think is a slightly more appropriate for your use case.

命令行中的GDAL

从纯命令行中,我可以使用两个命令和一个中间tif.

From pure command line I got it working with two commands and an intermediate tif.

首先将16位tif转换为8位tif

First convert the 16 bit tif to an 8 bit tif

gdal_translate -scale -ot byte -of GTIFF cmyk-16.tif cmyk-out.tif -co PHOTOMETRIC=CMYK

文件 cmyk-out.tif 现在为8位.现在可以使用以下命令将其转换为jpeg

The file cmyk-out.tif is now in 8 bit. It can now be converted into jpeg with the following command

gdal_translate -of JPEG cmyk-out.tif cmyk-out.jpg

因此,您只需创建将两个命令链接在一起的批处理脚本(并可能删除中间的tif)

Hence you can just create a batch script chaining the two commands (and maybe deleting the intermediate tif)

来自python的GDAL(以及numpy和PIL)

如果问题似乎在于PIL无法打开图像,则可以使用GDAL进行打开,使用numpy进行转换为8位,使用PIL进行转换为RGB.

If the problem seems to be that the image can not be opened by PIL, you could use GDAL for the opening, numpy for the conversion to 8 bit and PIL for the conversion to RGB.

from osgeo import gdal
import numpy as np
from PIL import Image

def reduceDepth(image, display_min, display_max):
    image -= display_min
    image = np.floor_divide(image, (display_min - display_max + 1) / 256)
    image = image.astype(np.uint8)
    return image

raster = gdal.Open("cmyk-16.tif")
c = raster.GetRasterBand(1).ReadAsArray()
m = raster.GetRasterBand(2).ReadAsArray()
y = raster.GetRasterBand(3).ReadAsArray()
k = raster.GetRasterBand(4).ReadAsArray()

cmyk = np.dstack((c, m, y, k))
cmyk8 = reduceDepth(cmyk, 0, 65536)

im = Image.fromarray(cmyk8)
im = im.convert('RGB')
im.save("cmyk-out.jpeg")

使用libtiff代替GDAL

您也可以使用libtiff而不是gdal打开tif.然后上面的脚本看起来像这样

You can also use libtiff to open the tif instead of gdal. Then the above script will look like this

import numpy as np
from PIL import Image
from libtiff import TIFF

input = TIFF.open("cmyk-16.tif").read_image()

def reduceDepth(image, display_min, display_max):
    image -= display_min
    image = np.floor_divide(image, (display_min - display_max + 1) / 256)
    image = image.astype(np.uint8)
    return image

v8 = reduceDepth(input, 0, 65536)

im = Image.fromarray(v8)
im = im.convert('RGB')
im.save("cmyk-out.jpeg")

这篇关于如何打开TIF(CMYK,16位)图像文件?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-25 02:59