Подушка: контроль качества и подвыборки JPEG-сжатых TIFF - PullRequest
0 голосов
/ 09 мая 2019

Я использую подушку для создания многостраничных TIFF.Я хочу сжать слои в формате JPEG, что, как я вижу, можно сделать с помощью параметра compression: https://pillow.readthedocs.io/en/stable/handbook/image-file-formats.html#saving-tiff-images

Я также хотел бы указать качество сжатия и, в идеале, цветностьМодель подвыборки, обе из которых доступны для плагина JPEG: https://pillow.readthedocs.io/en/stable/handbook/image-file-formats.html#jpeg

Возможно ли это сделать с плагином TIFF Writer?

Спасибо.

Ответы [ 2 ]

1 голос
/ 13 мая 2019

Я экспериментировал с этим:

from PIL import Image
import numpy as np
import PIL.TiffImagePlugin as tiff

# Turn on debugging for some insights
TiffImagePlugin.DEBUG = True

# Create Numpy random image and make PIL Image from it
randImage= np.random.randint(0,256,(480,640,3), dtype=np.uint8)
i = Image.fromarray(randImage)

# Save with JPEG compression and file is smaller and "tiffdump" agrees it is JPEG encoded
# NOTE: It is "jpeg", not "tiff_jpeg" like the docs say
i.save("result.tif",compression="jpeg")

# Try and modify settings
import PIL.TiffImagePlugin as tiff

# Set some tags and see if they are saved
ifd=tiff.ImageFileDirectory_v2()
ifd[315]="Funky 315"
ifd[316]="Funky 316"

# I tried setting the YCbCrChromaSubSampling here but it makes no difference - maybe I did it wrong!
# It gets reported differently from how I expect when examined with "tiffdump"
# ifd[530]=0x10001

i.save("result.tif",compression="jpeg",tiffinfo=ifd)  

Проверьте с помощью tiffdump:

tiffdump result.tif

Magic: 0x4949 <little-endian> Version: 0x2a <ClassicTIFF>
Directory 0: offset 511960 (0x7cfd8) next 0 (0)
ImageWidth (256) SHORT (3) 1<640>
ImageLength (257) SHORT (3) 1<480>
BitsPerSample (258) SHORT (3) 3<8 8 8>
Compression (259) SHORT (3) 1<7>        <--- New style JPEG
Photometric (262) SHORT (3) 1<2>
StripOffsets (273) LONG (4) 1<8>
SamplesPerPixel (277) SHORT (3) 1<3>
RowsPerStrip (278) SHORT (3) 1<480>
StripByteCounts (279) LONG (4) 1<511951>
PlanarConfig (284) SHORT (3) 1<1>
Artist (315) ASCII (2) 10<Funky 315\0>           <--- gets saved
HostComputer (316) ASCII (2) 10<Funky 316\0>     <--- gets saved
JPEGTables (347) UNDEFINED (7) 289<0xff 0xd8 0xff 0xdb 00 0x43 00 0x8 0x6 0x6 0x7 0x6 0x5 0x8 0x7 0x7 0x7 0x9 0x9 0x8 0xa 0xc 0x14 0xd ...>
0 голосов
/ 14 мая 2019

Я также провел несколько экспериментов с libvips и смог написать сжатые JPEG-файлы TIFF с контролируемым качеством следующим образом:

import numpy as np
import pyvips

# Set width, height and number of bands of image
h, w, bands = 480, 640, 3

# Initialise Numpy image and convert to VipsImage
n = np.random.randint(0,256,(h,w,bands), dtype=np.uint8)
linear = n.reshape(h*w*bands)
vi = pyvips.Image.new_from_memory(linear.data, w, h, bands,'uchar')

# Now save without compression, then with JPEG compression quality=60, 80, 90
vi.tiffsave('result-none.tif')
vi.tiffsave('result-60.tif', compression='jpeg', Q=60)
vi.tiffsave('result-80.tif', compression='jpeg', Q=80)
vi.tiffsave('result-90.tif', compression='jpeg', Q=90)

Проверить размеры соответствуют:

-rw-r--r--   1 mark  staff    921854 14 May 16:32 result-none.tif
-rw-r--r--   1 mark  staff    146266 14 May 16:32 result-60.tif
-rw-r--r--   1 mark  staff    205996 14 May 16:32 result-80.tif
-rw-r--r--   1 mark  staff    724649 14 May 16:32 result-90.tif

Команда tiffinfo также определяет сжатие JPEG:

tiffinfo result-60.tif

TIFF Directory at offset 0x237de (145374)
  Image Width: 640 Image Length: 480
  Resolution: 10, 10 pixels/cm
  Bits/Sample: 8
  Sample Format: unsigned integer
  Compression Scheme: JPEG
  Photometric Interpretation: YCbCr
  Orientation: row 0 top, col 0 lhs
  Samples/Pixel: 3
  Rows/Strip: 128
  Planar Configuration: single image plane
  Reference Black/White:
     0:     0   255
     1:   128   255
     2:   128   255
  JPEG Tables: (574 bytes)

Вы можете узнать, как конвертировать из pyvips в numpy и обратно здесь .

Аналогично вы можете конвертировать из PIL Image в numpy с помощью:

PILImage = Image.open('image.png')
numpyImage = np.array(PILImage)

и из numpy изображения в PIL Image с помощью:

PILImage = Image.fromarray(numpyImage)

Это означает, что вы должны иметь возможность смешивать открытие, закрытие и обработку изображений между PIL / Pillow, Numpy, scikit-image, OpenCV и vips.

...