Похоже, что другие изображения работают, поэтому я остановлюсь на 16-битном преобразовании cmyk tif в 8-битный rgb jpeg.Я полагаю, что этот подход будет применяться и для других конверсий с некоторыми изменениями.
Вот несколько способов конвертировать его.Первые два используют GDAL, поскольку вы предположили, что в последнем подходе используется libtiff, что, я думаю, немного более подходит для вашего варианта использования.
GDAL из командной строки
Из чистой командной строки я начал работать с двумя командами и промежуточным tif.
Сначала преобразовать 16-битный tif в 8-битный tif
gdal_translate -scale -ot byte -of GTIFF cmyk-16.tif cmyk-out.tif -co PHOTOMETRIC=CMYK
Файл cmyk-out.tif теперь находится в 8 битах.Теперь его можно преобразовать в jpeg с помощью следующей команды
gdal_translate -of JPEG cmyk-out.tif cmyk-out.jpg
Следовательно, вы можете просто создать пакетный скрипт, объединяющий две команды (и, возможно, удалив промежуточный tif)
GDAL (и numpy и PIL) из python
Если проблема заключается в том, что изображение не может быть открыто PIL, вы можете использовать GDAL для открытия, numpy дляпреобразование в 8 бит и PIL для преобразования в 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, чтобы открыть tif вместо gdal,Тогда приведенный выше скрипт будет выглядеть так:
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")