枕头:控制质量和JPEG压缩TIFF的二次采样

时间:2019-05-09 19:02:03

标签: python python-imaging-library tiff

我正在使用Pillow创建多页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 个答案:

答案 0 :(得分:1)

我做了一些实验:

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 ...>

答案 1 :(得分:0)

我还用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并再次返回here

同样,您可以使用以下方法将PIL Image转换为numpy

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

然后从numpy图片到PIL Image,并带有:

PILImage = Image.fromarray(numpyImage)

这意味着您应该能够在PIL /枕头,Numpy,scikit-image,OpenCV和vips之间混合图像打开,关闭,处理。