1#!/usr/bin/python3
2
3import sys
4import time
5
6import pyvips
7from PIL import Image
8import numpy as np
9
10if len(sys.argv) != 3:
11    print('usage: {0} input-filename output-filename'.format(sys.argv[0]))
12    sys.exit(-1)
13
14# map vips formats to np dtypes
15format_to_dtype = {
16    'uchar': np.uint8,
17    'char': np.int8,
18    'ushort': np.uint16,
19    'short': np.int16,
20    'uint': np.uint32,
21    'int': np.int32,
22    'float': np.float32,
23    'double': np.float64,
24    'complex': np.complex64,
25    'dpcomplex': np.complex128,
26}
27
28# map np dtypes to vips
29dtype_to_format = {
30    'uint8': 'uchar',
31    'int8': 'char',
32    'uint16': 'ushort',
33    'int16': 'short',
34    'uint32': 'uint',
35    'int32': 'int',
36    'float32': 'float',
37    'float64': 'double',
38    'complex64': 'complex',
39    'complex128': 'dpcomplex',
40}
41
42
43# numpy array to vips image
44def numpy2vips(a):
45    height, width, bands = a.shape
46    linear = a.reshape(width * height * bands)
47    vi = pyvips.Image.new_from_memory(linear.data, width, height, bands,
48                                      dtype_to_format[str(a.dtype)])
49    return vi
50
51
52# vips image to numpy array
53def vips2numpy(vi):
54    return np.ndarray(buffer=vi.write_to_memory(),
55                      dtype=format_to_dtype[vi.format],
56                      shape=[vi.height, vi.width, vi.bands])
57
58
59# load with PIL
60start_pillow = time.time()
61pillow_img = np.asarray(Image.open(sys.argv[1]))
62print('Pillow Time:', time.time() - start_pillow)
63print('pil shape', pillow_img.shape)
64
65# load with vips to a memory array
66start_vips = time.time()
67img = pyvips.Image.new_from_file(sys.argv[1])
68np_3d = vips2numpy(img)
69
70print('Vips Time:', time.time() - start_vips)
71print('vips shape', np_3d.shape)
72
73# make a vips image from the numpy array
74vi = numpy2vips(pillow_img)
75
76# verify we have the same result
77# this can be non-zero for formats like jpg if the two libraries are using
78# different libjpg versions ... try with png instead
79print('Average pil/vips difference:', (vi - img).avg())
80
81# and write back to disc for checking
82vi.write_to_file(sys.argv[2])
83