Skip to content

Commit 53f4648

Browse files
committed
doc: add color management section
Document the desired end state of color management support. Signed-off-by: Benjamin Gilbert <[email protected]>
1 parent 1f58432 commit 53f4648

File tree

1 file changed

+50
-0
lines changed

1 file changed

+50
-0
lines changed

doc/index.rst

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,56 @@ OpenSlide objects
188188
Close the OpenSlide object.
189189

190190

191+
Color management
192+
----------------
193+
194+
Every slide region, associated image, thumbnail, and Deep Zoom tile produced
195+
by OpenSlide Python includes a reference to an ICC color profile whenever a
196+
profile is available for the underlying pixel data. Profiles are stored as
197+
a :class:`bytes` object in
198+
:attr:`Image.info <PIL.Image.Image.info>`:attr:`['icc_profile']`. If no
199+
profile is available, the :attr:`icc_profile` dictionary key is absent.
200+
201+
To include the profile in an image file when saving the image to disk::
202+
203+
image.save(filename, icc_profile=image.info.get('icc_profile'))
204+
205+
To perform color conversions using the profile, import it into
206+
:mod:`ImageCms <PIL.ImageCms>`. For example, to convert an image in-place
207+
to a synthesized sRGB profile, using absolute colorimetric rendering::
208+
209+
from io import BytesIO
210+
from PIL import ImageCms
211+
212+
fromProfile = ImageCms.getOpenProfile(BytesIO(image.info['icc_profile']))
213+
toProfile = ImageCms.createProfile('sRGB')
214+
ImageCms.profileToProfile(
215+
image, fromProfile, toProfile,
216+
ImageCms.Intent.ABSOLUTE_COLORIMETRIC, 'RGBA', True, 0
217+
)
218+
219+
Absolute colorimetric rendering `maximizes the comparability`_ of images
220+
produced by different scanners. When converting Deep Zoom tiles, use
221+
``'RGB'`` instead of ``'RGBA'``.
222+
223+
All pyramid regions in a slide have the same profile, but each associated
224+
image can have its own profile. As a convenience, the former is also
225+
available as :attr:`OpenSlide.color_profile`, already parsed into an
226+
:class:`~PIL.ImageCms.ImageCmsProfile` object. You can save processing time
227+
by building an :class:`~PIL.ImageCms.ImageCmsTransform` for the slide and
228+
reusing it for multiple slide regions::
229+
230+
toProfile = ImageCms.createProfile('sRGB')
231+
transform = ImageCms.buildTransform(
232+
slide.color_profile, toProfile, 'RGBA', 'RGBA',
233+
ImageCms.Intent.ABSOLUTE_COLORIMETRIC, 0
234+
)
235+
# for each region image:
236+
ImageCms.applyTransform(image, transform, True)
237+
238+
.. _maximizes the comparability: https://www.ncbi.nlm.nih.gov/pmc/articles/PMC4478790/
239+
240+
191241
Caching
192242
-------
193243

0 commit comments

Comments
 (0)