Skip to content

Commit

Permalink
Update imageio.imsave -> imageio.v3.imwrite (#237)
Browse files Browse the repository at this point in the history
  • Loading branch information
mplough-kobold authored Sep 12, 2024
1 parent b3c9171 commit a0b9089
Show file tree
Hide file tree
Showing 5 changed files with 26 additions and 33 deletions.
10 changes: 5 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,20 +15,20 @@ Load a RAW file and save the postprocessed image using default [parameters](http

```python
import rawpy
import imageio
import imageio.v3 as iio

path = 'image.nef'
with rawpy.imread(path) as raw:
rgb = raw.postprocess()
imageio.imsave('default.tiff', rgb)
iio.imwrite('default.tiff', rgb)
```

Save as 16-bit linear image:

```python
with rawpy.imread(path) as raw:
rgb = raw.postprocess(gamma=(1,1), no_auto_bright=True, output_bps=16)
imageio.imsave('linear.tiff', rgb)
iio.imwrite('linear.tiff', rgb)
```

Extract embedded thumbnail/preview image and save as JPEG:
Expand All @@ -44,7 +44,7 @@ if thumb.format == rawpy.ThumbFormat.JPEG:
f.write(thumb.data)
elif thumb.format == rawpy.ThumbFormat.BITMAP:
# thumb.data is an RGB numpy array, convert with imageio
imageio.imsave('thumb.jpeg', thumb.data)
iio.imwrite('thumb.jpeg', thumb.data)
```

Find bad pixels using multiple RAW files and repair them:
Expand All @@ -59,7 +59,7 @@ for path in paths:
with rawpy.imread(path) as raw:
rawpy.enhance.repair_bad_pixels(raw, bad_pixels, method='median')
rgb = raw.postprocess()
imageio.imsave(path + '.tiff', rgb)
iio.imwrite(path + '.tiff', rgb)
```

## Installation
Expand Down
4 changes: 2 additions & 2 deletions dev-requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@ scikit-image

# test dependencies
pytest
imageio
imageio>=2.21 # for imageio.v3 / iio support
setuptools

# documentation dependencies
sphinx_rtd_theme
sphinx
sphinx
5 changes: 4 additions & 1 deletion rawpy/_rawpy.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -866,6 +866,9 @@ cdef class RawPy:
If no image exists or the format is unsupported, an exception is raised.
.. code-block:: python
import imageio.v3 as iio
...
with rawpy.imread('image.nef') as raw:
try:
Expand All @@ -879,7 +882,7 @@ cdef class RawPy:
with open('thumb.jpg', 'wb') as f:
f.write(thumb.data)
elif thumb.format == rawpy.ThumbFormat.BITMAP:
imageio.imsave('thumb.tiff', thumb.data)
iio.imwrite('thumb.tiff', thumb.data)
:rtype: :class:`rawpy.Thumbnail`
"""
Expand Down
8 changes: 4 additions & 4 deletions rawpy/enhance.py
Original file line number Diff line number Diff line change
Expand Up @@ -350,11 +350,11 @@ def save_dcraw_bad_pixels(path, bad_pixels):
paths = [os.path.join(prefix, f) for f in testfiles]
coords = find_bad_pixels(paths)

import imageio
import imageio.v3 as iio
raw = rawpy.imread(paths[0])
if not os.path.exists('test_original.png'):
rgb = raw.postprocess()
imageio.imsave('test_original.png', rgb)
iio.imwrite('test_original.png', rgb)

# A. use dcraw repair
# Note that this method fails when two bad pixels are direct neighbors.
Expand All @@ -365,7 +365,7 @@ def save_dcraw_bad_pixels(path, bad_pixels):
save_dcraw_bad_pixels(bad_pixels_path, coords)
rgb = raw.postprocess(bad_pixels_path=bad_pixels_path)
print('badpixel dcraw repair+postprocessing:', time.time()-t0, 's')
imageio.imsave('test_hotpixels_repaired_dcraw.png', rgb)
iio.imwrite('test_hotpixels_repaired_dcraw.png', rgb)

# B. use own repair function
# With method='median' we still consider each bad pixel separately
Expand All @@ -374,7 +374,7 @@ def save_dcraw_bad_pixels(path, bad_pixels):
repair_bad_pixels(raw, coords, method='median')
rgb = raw.postprocess()
print('badpixel repair+postprocessing:', time.time()-t0, 's')
imageio.imsave('test_hotpixels_repaired.png', rgb)
iio.imwrite('test_hotpixels_repaired.png', rgb)

# TODO method 'mean' not implemented yet

Expand Down
32 changes: 11 additions & 21 deletions test/test_basic.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@

import rawpy
import rawpy.enhance
import imageio
import imageio.v3 as iio
from rawpy.enhance import _repair_bad_pixels_bayer2x2,\
_repair_bad_pixels_generic, find_bad_pixels

Expand Down Expand Up @@ -52,48 +52,48 @@ def testFileOpenAndPostProcess():
rgb = raw.postprocess(no_auto_bright=True, user_wb=raw.daylight_whitebalance)
assert_array_equal(rgb.shape, [2844, 4284, 3])
print_stats(rgb)
save('test_8daylight.tiff', rgb)
iio.imwrite('test_8daylight.tiff', rgb)

print('daylight white balance multipliers:', raw.daylight_whitebalance)

rgb = raw.postprocess(no_auto_bright=True, user_wb=raw.daylight_whitebalance)
print_stats(rgb)
save('test_8daylight2.tiff', rgb)
iio.imwrite('test_8daylight2.tiff', rgb)

rgb = raw.postprocess(no_auto_bright=True, user_wb=raw.daylight_whitebalance,
output_bps=16)
print_stats(rgb)
save('test_16daylight.tiff', rgb)
iio.imwrite('test_16daylight.tiff', rgb)

# linear images are more useful for science (=no gamma correction)
# see http://www.mit.edu/~kimo/blog/linear.html
rgb = raw.postprocess(no_auto_bright=True, user_wb=raw.daylight_whitebalance,
gamma=(1,1), output_bps=16)
print_stats(rgb)
save('test_16daylight_linear.tiff', rgb)
iio.imwrite('test_16daylight_linear.tiff', rgb)

def testFoveonFileOpenAndPostProcess():
raw = rawpy.imread(raw4TestPath)

assert_array_equal(raw.raw_image.shape, [1531, 2304, 3])
save('test_foveon_raw.tiff', raw.raw_image)
iio.imwrite('test_foveon_raw.tiff', raw.raw_image)

rgb = raw.postprocess()
assert_array_equal(rgb.shape, [1510, 2266, 3])
print_stats(rgb)
save('test_foveon.tiff', rgb)
iio.imwrite('test_foveon.tiff', rgb)

def testSRawFileOpenAndPostProcess():
raw = rawpy.imread(raw5TestPath)

assert_array_equal(raw.raw_image.shape, [1296, 1944, 4])
assert_equal(raw.raw_image[:,:,3].max(), 0)
save('test_sraw_raw.tiff', raw.raw_image[:,:,:3])
iio.imwrite('test_sraw_raw.tiff', raw.raw_image[:,:,:3])

rgb = raw.postprocess()
assert_array_equal(rgb.shape, [1296, 1944, 3])
print_stats(rgb)
save('test_sraw.tiff', rgb)
iio.imwrite('test_sraw.tiff', rgb)

def testFileOpenWithNonAsciiCharacters():
raw = rawpy.imread(raw6TestPath)
Expand All @@ -104,7 +104,7 @@ def testBufferOpen():
assert_array_equal(raw.raw_image.shape, [2844, 4288])
rgb = raw.postprocess()
print_stats(rgb)
save('test_buffer.tiff', rgb)
iio.imwrite('test_buffer.tiff', rgb)

def testContextManager():
with rawpy.imread(rawTestPath) as raw:
Expand Down Expand Up @@ -140,7 +140,7 @@ def testThumbExtractJPEG():
with rawpy.imread(rawTestPath) as raw:
thumb = raw.extract_thumb()
assert thumb.format == rawpy.ThumbFormat.JPEG
img = imageio.v3.imread(thumb.data)
img = iio.imread(thumb.data)
assert_array_equal(img.shape, [2832, 4256, 3])

def testThumbExtractBitmap():
Expand Down Expand Up @@ -278,16 +278,6 @@ def testCorruptFile():
with pytest.raises(rawpy.LibRawDataError):
im.extract_thumb()

def save(path, im):
# both imageio and skimage currently save uint16 images with 180deg rotation
# as they both use freeimage and this has some weird internal formats
# see https://github.com/scikit-image/scikit-image/issues/1101
# and https://github.com/imageio/imageio/issues/3
from packaging.version import Version
if im.dtype == np.uint16 and Version(imageio.__version__) <= Version('0.5.1'):
im = im[::-1,::-1]
imageio.v3.imwrite(path, im)

def print_stats(rgb):
print(rgb.dtype,
np.min(rgb, axis=(0,1)), np.max(rgb, axis=(0,1)), # range for each channel
Expand Down

0 comments on commit a0b9089

Please sign in to comment.