2012-10-16 00:26:38 +04:00
|
|
|
# PyCMSTests.py
|
|
|
|
# Examples of how to use pyCMS, as well as tests to verify it works properly
|
|
|
|
# By Kevin Cazabon (kevin@cazabon.com)
|
|
|
|
|
|
|
|
# Imports
|
|
|
|
import os
|
|
|
|
from PIL import Image
|
|
|
|
from PIL import ImageCms
|
|
|
|
|
|
|
|
# import PyCMSError separately so we can catch it
|
|
|
|
PyCMSError = ImageCms.PyCMSError
|
|
|
|
|
|
|
|
#######################################################################
|
|
|
|
# Configuration:
|
|
|
|
#######################################################################
|
|
|
|
# set this to the image you want to test with
|
|
|
|
IMAGE = "c:\\temp\\test.tif"
|
|
|
|
|
|
|
|
# set this to where you want to save the output images
|
|
|
|
OUTPUTDIR = "c:\\temp\\"
|
|
|
|
|
|
|
|
# set these to two different ICC profiles, one for input, one for output
|
|
|
|
# set the corresponding mode to the proper PIL mode for that profile
|
|
|
|
INPUT_PROFILE = "c:\\temp\\profiles\\sRGB.icm"
|
|
|
|
INMODE = "RGB"
|
|
|
|
|
|
|
|
OUTPUT_PROFILE = "c:\\temp\\profiles\\genericRGB.icm"
|
|
|
|
OUTMODE = "RGB"
|
|
|
|
|
|
|
|
PROOF_PROFILE = "c:\\temp\\profiles\\monitor.icm"
|
|
|
|
|
|
|
|
# set to True to show() images, False to save them into OUTPUT_DIRECTORY
|
2013-07-01 02:42:19 +04:00
|
|
|
SHOW = False
|
2012-10-16 00:26:38 +04:00
|
|
|
|
|
|
|
# Tests you can enable/disable
|
|
|
|
TEST_error_catching = True
|
|
|
|
TEST_profileToProfile = True
|
|
|
|
TEST_profileToProfile_inPlace = True
|
|
|
|
TEST_buildTransform = True
|
|
|
|
TEST_buildTransformFromOpenProfiles = True
|
|
|
|
TEST_buildProofTransform = True
|
|
|
|
TEST_getProfileInfo = True
|
|
|
|
TEST_misc = False
|
|
|
|
|
|
|
|
#######################################################################
|
|
|
|
# helper functions
|
|
|
|
#######################################################################
|
|
|
|
def outputImage(im, funcName = None):
|
|
|
|
# save or display the image, depending on value of SHOW_IMAGES
|
|
|
|
if SHOW == True:
|
|
|
|
im.show()
|
|
|
|
else:
|
|
|
|
im.save(os.path.join(OUTPUTDIR, "%s.tif" %funcName))
|
|
|
|
|
|
|
|
|
|
|
|
#######################################################################
|
|
|
|
# The tests themselves
|
|
|
|
#######################################################################
|
|
|
|
|
|
|
|
if TEST_error_catching == True:
|
|
|
|
im = Image.open(IMAGE)
|
|
|
|
try:
|
|
|
|
#neither of these proifles exists (unless you make them), so we should
|
|
|
|
# get an error
|
|
|
|
imOut = ImageCms.profileToProfile(im, "missingProfile.icm", "cmyk.icm")
|
2013-07-01 02:42:19 +04:00
|
|
|
|
2012-10-16 00:26:38 +04:00
|
|
|
except PyCMSError as reason:
|
2013-07-01 02:42:19 +04:00
|
|
|
print("We caught a PyCMSError: %s\n\n" %reason)
|
2012-10-16 00:26:38 +04:00
|
|
|
|
|
|
|
print("error catching test completed successfully (if you see the message \
|
|
|
|
above that we caught the error).")
|
|
|
|
|
|
|
|
if TEST_profileToProfile == True:
|
|
|
|
# open the image file using the standard PIL function Image.open()
|
|
|
|
im = Image.open(IMAGE)
|
|
|
|
|
|
|
|
# send the image, input/output profiles, and rendering intent to
|
2013-07-01 02:42:19 +04:00
|
|
|
# ImageCms.profileToProfile()
|
2012-10-16 00:26:38 +04:00
|
|
|
imOut = ImageCms.profileToProfile(im, INPUT_PROFILE, OUTPUT_PROFILE, \
|
|
|
|
outputMode = OUTMODE)
|
|
|
|
|
|
|
|
# now that the image is converted, save or display it
|
|
|
|
outputImage(imOut, "profileToProfile")
|
2013-07-01 02:42:19 +04:00
|
|
|
|
2012-10-16 00:26:38 +04:00
|
|
|
print("profileToProfile test completed successfully.")
|
|
|
|
|
2013-07-01 02:42:19 +04:00
|
|
|
if TEST_profileToProfile_inPlace == True:
|
2012-10-16 00:26:38 +04:00
|
|
|
# we'll do the same test as profileToProfile, but modify im in place
|
|
|
|
# instead of getting a new image returned to us
|
|
|
|
im = Image.open(IMAGE)
|
|
|
|
|
2013-07-01 02:42:19 +04:00
|
|
|
# send the image to ImageCms.profileToProfile(), specifying inPlace = True
|
2012-10-16 00:26:38 +04:00
|
|
|
result = ImageCms.profileToProfile(im, INPUT_PROFILE, OUTPUT_PROFILE, \
|
|
|
|
outputMode = OUTMODE, inPlace = True)
|
|
|
|
|
|
|
|
# now that the image is converted, save or display it
|
|
|
|
if result == None:
|
|
|
|
# this is the normal result when modifying in-place
|
|
|
|
outputImage(im, "profileToProfile_inPlace")
|
|
|
|
else:
|
|
|
|
# something failed...
|
|
|
|
print("profileToProfile in-place failed: %s" %result)
|
|
|
|
|
|
|
|
print("profileToProfile in-place test completed successfully.")
|
|
|
|
|
|
|
|
if TEST_buildTransform == True:
|
|
|
|
# make a transform using the input and output profile path strings
|
|
|
|
transform = ImageCms.buildTransform(INPUT_PROFILE, OUTPUT_PROFILE, INMODE, \
|
|
|
|
OUTMODE)
|
|
|
|
|
|
|
|
# now, use the trnsform to convert a couple images
|
|
|
|
im = Image.open(IMAGE)
|
|
|
|
|
|
|
|
# transform im normally
|
|
|
|
im2 = ImageCms.applyTransform(im, transform)
|
|
|
|
outputImage(im2, "buildTransform")
|
|
|
|
|
|
|
|
# then transform it again using the same transform, this time in-place.
|
|
|
|
result = ImageCms.applyTransform(im, transform, inPlace = True)
|
2013-07-01 02:42:19 +04:00
|
|
|
outputImage(im, "buildTransform_inPlace")
|
2012-10-16 00:26:38 +04:00
|
|
|
|
|
|
|
print("buildTransform test completed successfully.")
|
|
|
|
|
|
|
|
# and, to clean up a bit, delete the transform
|
|
|
|
# this should call the C destructor for the transform structure.
|
|
|
|
# Python should also do this automatically when it goes out of scope.
|
|
|
|
del(transform)
|
|
|
|
|
|
|
|
if TEST_buildTransformFromOpenProfiles == True:
|
|
|
|
# we'll actually test a couple profile open/creation functions here too
|
|
|
|
|
|
|
|
# first, get a handle to an input profile, in this case we'll create
|
|
|
|
# an sRGB profile on the fly:
|
|
|
|
inputProfile = ImageCms.createProfile("sRGB")
|
|
|
|
|
|
|
|
# then, get a handle to the output profile
|
|
|
|
outputProfile = ImageCms.getOpenProfile(OUTPUT_PROFILE)
|
|
|
|
|
|
|
|
# make a transform from these
|
|
|
|
transform = ImageCms.buildTransformFromOpenProfiles(inputProfile, \
|
|
|
|
outputProfile, INMODE, OUTMODE)
|
|
|
|
|
|
|
|
# now, use the trnsform to convert a couple images
|
|
|
|
im = Image.open(IMAGE)
|
|
|
|
|
|
|
|
# transform im normally
|
|
|
|
im2 = ImageCms.applyTransform(im, transform)
|
|
|
|
outputImage(im2, "buildTransformFromOpenProfiles")
|
|
|
|
|
|
|
|
# then do it again using the same transform, this time in-place.
|
|
|
|
result = ImageCms.applyTransform(im, transform, inPlace = True)
|
2013-07-01 02:42:19 +04:00
|
|
|
outputImage(im, "buildTransformFromOpenProfiles_inPlace")
|
2012-10-16 00:26:38 +04:00
|
|
|
|
|
|
|
print("buildTransformFromOpenProfiles test completed successfully.")
|
2013-07-01 02:42:19 +04:00
|
|
|
|
2012-10-16 00:26:38 +04:00
|
|
|
# and, to clean up a bit, delete the transform
|
|
|
|
# this should call the C destructor for the each item.
|
|
|
|
# Python should also do this automatically when it goes out of scope.
|
|
|
|
del(inputProfile)
|
|
|
|
del(outputProfile)
|
|
|
|
del(transform)
|
|
|
|
|
|
|
|
if TEST_buildProofTransform == True:
|
|
|
|
# make a transform using the input and output and proof profile path
|
|
|
|
# strings
|
|
|
|
# images converted with this transform will simulate the appearance
|
|
|
|
# of the output device while actually being displayed/proofed on the
|
|
|
|
# proof device. This usually means a monitor, but can also mean
|
|
|
|
# other proof-printers like dye-sub, etc.
|
|
|
|
transform = ImageCms.buildProofTransform(INPUT_PROFILE, OUTPUT_PROFILE, \
|
|
|
|
PROOF_PROFILE, INMODE, OUTMODE)
|
|
|
|
|
|
|
|
# now, use the trnsform to convert a couple images
|
|
|
|
im = Image.open(IMAGE)
|
|
|
|
|
|
|
|
# transform im normally
|
|
|
|
im2 = ImageCms.applyTransform(im, transform)
|
|
|
|
outputImage(im2, "buildProofTransform")
|
|
|
|
|
|
|
|
# then transform it again using the same transform, this time in-place.
|
|
|
|
result = ImageCms.applyTransform(im, transform, inPlace = True)
|
2013-07-01 02:42:19 +04:00
|
|
|
outputImage(im, "buildProofTransform_inPlace")
|
2012-10-16 00:26:38 +04:00
|
|
|
|
|
|
|
print("buildProofTransform test completed successfully.")
|
|
|
|
|
|
|
|
# and, to clean up a bit, delete the transform
|
|
|
|
# this should call the C destructor for the transform structure.
|
|
|
|
# Python should also do this automatically when it goes out of scope.
|
|
|
|
del(transform)
|
2013-07-01 02:42:19 +04:00
|
|
|
|
2012-10-16 00:26:38 +04:00
|
|
|
if TEST_getProfileInfo == True:
|
|
|
|
# get a profile handle
|
|
|
|
profile = ImageCms.getOpenProfile(INPUT_PROFILE)
|
2013-07-01 02:42:19 +04:00
|
|
|
|
2012-10-16 00:26:38 +04:00
|
|
|
# lets print some info about our input profile:
|
|
|
|
print("Profile name (retrieved from profile string path name): %s" %ImageCms.getProfileName(INPUT_PROFILE))
|
|
|
|
|
|
|
|
# or, you could do the same thing using a profile handle as the arg
|
|
|
|
print("Profile name (retrieved from profile handle): %s" %ImageCms.getProfileName(profile))
|
|
|
|
|
|
|
|
# now lets get the embedded "info" tag contents
|
|
|
|
# once again, you can use a path to a profile, or a profile handle
|
|
|
|
print("Profile info (retrieved from profile handle): %s" %ImageCms.getProfileInfo(profile))
|
|
|
|
|
|
|
|
# and what's the default intent of this profile?
|
|
|
|
print("The default intent is (this will be an integer): %d" %(ImageCms.getDefaultIntent(profile)))
|
|
|
|
|
|
|
|
# Hmmmm... but does this profile support INTENT_ABSOLUTE_COLORIMETRIC?
|
|
|
|
print("Does it support INTENT_ABSOLUTE_COLORIMETRIC?: (1 is yes, -1 is no): %s" \
|
|
|
|
%ImageCms.isIntentSupported(profile, ImageCms.INTENT_ABSOLUTE_COLORIMETRIC, \
|
2013-07-01 02:42:19 +04:00
|
|
|
ImageCms.DIRECTION_INPUT))
|
2012-10-16 00:26:38 +04:00
|
|
|
|
|
|
|
print("getProfileInfo test completed successfully.")
|
|
|
|
|
|
|
|
if TEST_misc == True:
|
|
|
|
# test the versions, about, and copyright functions
|
|
|
|
print("Versions: %s" %str(ImageCms.versions()))
|
|
|
|
print("About:\n\n%s" %ImageCms.about())
|
|
|
|
print("Copyright:\n\n%s" %ImageCms.copyright())
|
|
|
|
|
|
|
|
print("misc test completed successfully.")
|
2013-07-01 02:42:19 +04:00
|
|
|
|