Skip to content

Commit df462ca

Browse files
authored
Fixed new_from_array, fixed test for older pytorch (#321)
* Fixed new_from_array, fixed test for older pytorch * conversio of objects with no .data, better tests Co-authored-by: erdmann <[email protected]>
1 parent 43da307 commit df462ca

File tree

2 files changed

+31
-7
lines changed

2 files changed

+31
-7
lines changed

Diff for: pyvips/vimage.py

+12-6
Original file line numberDiff line numberDiff line change
@@ -509,7 +509,9 @@ def new_from_array(cls, obj, scale=1.0, offset=0.0, interpretation=None):
509509
shape = a['shape']
510510
typestr = a['typestr']
511511
ndim = len(shape)
512-
strides = a['strides']
512+
513+
# strides is optional
514+
strides = a.get('strides', None)
513515

514516
if ndim > 3:
515517
raise ValueError('array has more than 3 dimensions')
@@ -533,12 +535,16 @@ def new_from_array(cls, obj, scale=1.0, offset=0.0, interpretation=None):
533535

534536
format = TYPESTR_TO_FORMAT[typestr]
535537

536-
if strides is None:
538+
if strides is None and hasattr(obj, 'data'):
537539
data = obj.data
538540
else:
539541
# To obtain something with a contiguous memory layout
540-
data = obj.tobytes() if hasattr(obj, 'tobytes') else \
541-
obj.tostring()
542+
if hasattr(obj, 'tobytes'):
543+
data = obj.tobytes()
544+
elif hasattr(obj, 'tostring'):
545+
data = obj.tostring()
546+
else:
547+
raise TypeError('object has no .tobytes or .tostring')
542548

543549
im = cls.new_from_memory(
544550
data,
@@ -564,8 +570,8 @@ def new_from_array(cls, obj, scale=1.0, offset=0.0, interpretation=None):
564570
# make it into something that *does* define __array_interface__
565571
return cls.new_from_array(obj.__array__())
566572
else:
567-
raise ValueError('does not define __array_interface__ ' +
568-
'or __array__')
573+
raise TypeError('does not define __array_interface__ '
574+
'or __array__')
569575

570576
@staticmethod
571577
def new_from_memory(data, width, height, bands, format):

Diff for: tests/test_image.py

+19-1
Original file line numberDiff line numberDiff line change
@@ -303,7 +303,7 @@ def test_torch(self):
303303

304304
# Image to torch:
305305
im = pyvips.Image.zone(5, 5)
306-
t = torch.asarray(np.asarray(im))
306+
t = torch.from_numpy(np.asarray(im))
307307
assert t[2, 2] == 1.
308308

309309
def test_from_numpy(self):
@@ -342,6 +342,24 @@ def test_from_numpy(self):
342342
# no way in for strings
343343
im = pyvips.Image.new_from_array(a)
344344

345+
# test handling of strided data
346+
a = np.ones((1000, 1000, 3), dtype='uint8')[::10, ::10]
347+
im = pyvips.Image.new_from_array(a)
348+
assert im.width == 100
349+
assert im.height == 100
350+
assert im.bands == 3
351+
352+
class FakeArray(object):
353+
@property
354+
def __array_interface__(self):
355+
return {'shape': (1, 1, 1),
356+
'typestr': '|u1',
357+
'version': 3}
358+
359+
with pytest.raises(TypeError):
360+
# Handle evil objects that don't behave like ndarrays
361+
im = pyvips.Image.new_from_array(FakeArray())
362+
345363
def test_tolist(self):
346364
im = pyvips.Image.complexform(*pyvips.Image.xyz(3, 4))
347365

0 commit comments

Comments
 (0)