def init_color_profiles(): global COLOR_PROFILES COLOR_PROFILES['srgb'] = ImageCms.createProfile('sRGB') #COLOR_PROFILES['argb'] = ImageCms.getOpenProfile(r'AdobeRGB.icc') COLOR_PROFILES['argb'] = ImageCms.getOpenProfile(os.path.join(ICC_DATA_DIR, 'AdobeRGB.icc'))
def imageRGB(self, prof_out=False): image = self.image() alpha_band = False if image.mode in ('LA', 'PA', 'RGBA'): bands = image.split() alpha_band = bands[-1] image = Image.merge(image.mode[:-1], bands[:-1]) sRGB = ImageCms.createProfile("sRGB") if 'icc_profile' in image.info: inputProfile = ImageCms.ImageCmsProfile(StringIO(image.info['icc_profile'])) else: if image.mode == "CMYK": inputProfile = (dirpath(__file__) or ".") + "/Fogra27L.icm" elif image.mode == "LAB": inputProfile = ImageCms.createProfile("LAB") else: image = image.convert('RGB') inputProfile = sRGB if prof_out: outputProfile = prof_out else: outputProfile = sRGB new_image = ImageCms.profileToProfile(image, inputProfile, outputProfile, outputMode="RGB") if not alpha_band: alpha_band = Image.new('L', image.size, 255) new_image.putalpha(alpha_band) return new_image
def imageRGB(self, width, height, prof_out=False): if len(self.colorstops) == 0: return False colors = set() for stop in self.colorstops: colors.add(stop.color) sRGB_colors = {} for color in colors: if color: sRGB_colors[color] = self.swatchbook.materials[color].toRGB(prof_out) or (128, 128, 128) # Color image = Image.new('RGB', (width, height)) draw = ImageDraw.Draw(image) for i in range(width): pos = i / width left = 0 right = len(self.colorstops) - 1 for j, stop in enumerate(self.colorstops): if pos >= stop.position: left = j else: right = j break sRGB_left = sRGB_colors[self.colorstops[left].color] if self.colorstops[left].color else (128, 128, 128) sRGB_right = sRGB_colors[self.colorstops[right].color] if self.colorstops[right].color else (128, 128, 128) if left == right or self.colorstops[left].color == self.colorstops[right].color: r, g, b = sRGB_left else: seg_pos = (pos - self.colorstops[left].position) / (self.colorstops[right].position - self.colorstops[left].position) if "midpoint" in self.colorstops[left].args: midpoint = self.colorstops[left].args["midpoint"] else: midpoint = 0.5 factor = Gradient.get_factor(self.colorstops[left].interpolation, seg_pos, midpoint) r, g, b = Gradient.interpolate(sRGB_left, sRGB_right, factor, self.colorstops[left].model, self.colorstops[left].args) draw.line((i, 0, i, height), fill=(int(round(r * 0xFF)), int(round(g * 0xFF)), int(round(b * 0xFF)))) del draw sRGB = ImageCms.createProfile("sRGB") if prof_out: new_image = ImageCms.profileToProfile(image, sRGB, prof_out) else: new_image = image # Opacity alpha = Image.new('L', (width, height), 255) if len(self.opacitystops) > 0: draw = ImageDraw.Draw(alpha) for i in range(width): try: a = self.alphaAt(float(i) / width) except TypeError: a = 1 draw.line((i, 0, i, image.size[1]), fill=int(round(a * 0xFF))) del draw new_image.putalpha(alpha) return new_image
def test_sanity(): # basic smoke test. # this mostly follows the cms_test outline. v = ImageCms.versions() # should return four strings assert_equal(v[0], '1.0.0 pil') assert_equal(list(map(type, v)), [str, str, str, str]) # internal version number assert_match(ImageCms.core.littlecms_version, "\d+\.\d+$") i = ImageCms.profileToProfile(lena(), SRGB, SRGB) assert_image(i, "RGB", (128, 128)) t = ImageCms.buildTransform(SRGB, SRGB, "RGB", "RGB") i = ImageCms.applyTransform(lena(), t) assert_image(i, "RGB", (128, 128)) p = ImageCms.createProfile("sRGB") o = ImageCms.getOpenProfile(SRGB) t = ImageCms.buildTransformFromOpenProfiles(p, o, "RGB", "RGB") i = ImageCms.applyTransform(lena(), t) assert_image(i, "RGB", (128, 128)) t = ImageCms.buildProofTransform(SRGB, SRGB, SRGB, "RGB", "RGB") assert_equal(t.inputMode, "RGB") assert_equal(t.outputMode, "RGB") i = ImageCms.applyTransform(lena(), t) assert_image(i, "RGB", (128, 128)) # test PointTransform convenience API im = lena().point(t)
def _merge_bands(bands, color_mode, size, icc_profile): if Image is None: raise Exception("This module requires PIL (or Pillow) installed.") if color_mode == ColorMode.RGB: merged_image = Image.merge('RGB', [bands[key] for key in 'RGB']) elif color_mode == ColorMode.CMYK: merged_image = Image.merge('CMYK', [bands[key] for key in 'CMYK']) merged_bytes = tobytes(merged_image) # colors are inverted in Photoshop CMYK images; invert them back merged_image = frombytes('CMYK', size, merged_bytes, 'raw', 'CMYK;I') elif color_mode == ColorMode.GRAYSCALE: merged_image = bands['L'] else: raise NotImplementedError() if icc_profile is not None: assert ImageCms is not None try: if color_mode in [ColorMode.RGB, ColorMode.CMYK]: merged_image = ImageCms.profileToProfile(merged_image, icc_profile, icc_profiles.sRGB, outputMode='RGB') elif color_mode == ColorMode.GRAYSCALE: ImageCms.profileToProfile(merged_image, icc_profile, icc_profiles.gray, inPlace=True, outputMode='L') except ImageCms.PyCMSError as e: # PIL/Pillow/(old littlecms?) can't convert some ICC profiles warnings.warn(repr(e)) if color_mode == ColorMode.CMYK: merged_image = merged_image.convert('RGB') alpha = bands.get('A') if alpha: merged_image.putalpha(alpha) return merged_image
def imageRGB(self, prof_out=False): image = self.image() alpha_band = False if image.mode in ("LA", "PA", "RGBA"): bands = image.split() alpha_band = bands[-1] image = Image.merge(image.mode[:-1], bands[:-1]) sRGB = ImageCms.createProfile("sRGB") if "icc_profile" in image.info: inputProfile = ImageCms.ImageCmsProfile(StringIO(image.info["icc_profile"])) else: if image.mode == "CMYK": inputProfile = (dirpath(__file__) or ".") + "/Fogra27L.icm" elif image.mode == "LAB": inputProfile = ImageCms.createProfile("LAB") else: image = image.convert("RGB") inputProfile = sRGB if prof_out: outputProfile = prof_out else: outputProfile = sRGB new_image = ImageCms.profileToProfile(image, inputProfile, outputProfile, outputMode="RGB") if alpha_band: new_image.putalpha(alpha_band) return new_image
def test_extensions(self): # extensions i = Image.open("Tests/images/rgb.jpg") p = ImageCms.getOpenProfile(BytesIO(i.info["icc_profile"])) self.assertEqual( ImageCms.getProfileName(p).strip(), 'IEC 61966-2.1 Default RGB colour space - sRGB')
def _channels_data_to_PIL(channels_data, channel_types, size, depth, icc_profile): if Image is None: raise Exception("This module requires PIL (or Pillow) installed.") if size == (0, 0): return bands = {} for channel, channel_type in zip(channels_data, channel_types): pil_band = channel_id_to_PIL(channel_type) if pil_band is None: warnings.warn("Unsupported channel type (%d)" % channel_type) continue if channel.compression in [Compression.RAW, Compression.ZIP, Compression.ZIP_WITH_PREDICTION]: if depth == 8: im = _from_8bit_raw(channel.data, size) elif depth == 16: im = _from_16bit_raw(channel.data, size) elif depth == 32: im = _from_32bit_raw(channel.data, size) else: warnings.warn("Unsupported depth (%s)" % depth) continue elif channel.compression == Compression.PACK_BITS: if depth != 8: warnings.warn("Depth %s is unsupported for PackBits compression" % depth) continue im = frombytes('L', size, channel.data, "packbits", 'L') else: if Compression.is_known(channel.compression): warnings.warn("Compression method is not implemented (%s)" % channel.compression) else: warnings.warn("Unknown compression method (%s)" % channel.compression) continue bands[pil_band] = im.convert('L') mode = _get_mode(bands.keys()) merged_image = Image.merge(mode, [bands[band] for band in mode]) if mode == 'CMYK': # invert CMYK data merged_image = frombytes('CMYK', size, merged_image.tobytes(), 'raw', 'CMYK;I') # convert with inner profile, better brightness merged_image = merged_image.convert('RGB') elif icc_profile is not None: display_profile = ImageCms.createProfile('sRGB') # XXX: ImageCms.get_display_profile()? ImageCms.profileToProfile(merged_image, icc_profile, display_profile, inPlace=True) return merged_image
def test_profile_object(self): # same, using profile object p = ImageCms.createProfile("sRGB") # self.assertEqual(ImageCms.getProfileName(p).strip(), # 'sRGB built-in - (lcms internal)') # self.assertEqual(ImageCms.getProfileInfo(p).splitlines(), # ['sRGB built-in', '', 'WhitePoint : D65 (daylight)', '', '']) self.assertEqual(ImageCms.getDefaultIntent(p), 0) self.assertEqual(ImageCms.isIntentSupported( p, ImageCms.INTENT_ABSOLUTE_COLORIMETRIC, ImageCms.DIRECTION_INPUT), 1)
def adobe_to_srgb(img): srgb = ImageCms.createProfile('sRGB') #icc = open('AdobeRGB.icc') #icc = open(r'C:\Users\Joshua\cmdutils\AdobeRGB.icc', 'rb') icc = open(os.path.join(ICC_DATA_DIR, 'AdobeRGB.icc'), 'rb') img = ImageCms.profileToProfile(img, icc, srgb) #img = ImageCms.profileToProfile(img, icc, srgb, renderingIntent = ImageCms.INTENT_SATURATION) return img
def test_lab_roundtrip(): # check to see if we're at least internally consistent. pLab = ImageCms.createProfile("LAB") t = ImageCms.buildTransform(SRGB, pLab, "RGB", "LAB") t2 = ImageCms.buildTransform(pLab, SRGB, "LAB", "RGB") i = ImageCms.applyTransform(lena(), t) out = ImageCms.applyTransform(i, t2) assert_image_similar(lena(), out, 2)
def test_lab_srgb(): pLab = ImageCms.createProfile("LAB") t = ImageCms.buildTransform(pLab, SRGB, "LAB", "RGB") img = Image.open('Tests/images/lena.Lab.tif') img_srgb = ImageCms.applyTransform(img, t) # img_srgb.save('temp.srgb.tif') # visually verified vs ps. assert_image_similar(lena(), img_srgb, 30)
def test_lab_color(): pLab = ImageCms.createProfile("LAB") t = ImageCms.buildTransform(SRGB, pLab, "RGB", "LAB") # need to add a type mapping for some PIL type to TYPE_Lab_8 in findLCMSType, # and have that mapping work back to a PIL mode. (likely RGB) i = ImageCms.applyTransform(lena(), t) assert_image(i, "LAB", (128, 128)) # i.save('temp.lab.tif') # visually verified vs PS. target = Image.open('Tests/images/lena.Lab.tif') assert_image_similar(i, target, 30)
def test_exceptions(self): # the procedural pyCMS API uses PyCMSError for all sorts of errors self.assertRaises( ImageCms.PyCMSError, lambda: ImageCms.profileToProfile(lena(), "foo", "bar")) self.assertRaises( ImageCms.PyCMSError, lambda: ImageCms.buildTransform("foo", "bar", "RGB", "RGB")) self.assertRaises( ImageCms.PyCMSError, lambda: ImageCms.getProfileName(None)) self.assertRaises( ImageCms.PyCMSError, lambda: ImageCms.isIntentSupported(SRGB, None, None))
def test_auxiliary_channels_isolated(self): # test data in aux channels does not affect non-aux channels aux_channel_formats = [ # format, profile, color-only format, source test image ('RGBA', 'sRGB', 'RGB', hopper('RGBA')), ('RGBX', 'sRGB', 'RGB', hopper('RGBX')), ('LAB', 'LAB', 'LAB', Image.open('Tests/images/hopper.Lab.tif')), ] for src_format in aux_channel_formats: for dst_format in aux_channel_formats: for transform_in_place in [True, False]: # inplace only if format doesn't change if transform_in_place and src_format[0] != dst_format[0]: continue # convert with and without AUX data, test colors are equal source_profile = ImageCms.createProfile(src_format[1]) destination_profile = ImageCms.createProfile(dst_format[1]) source_image = src_format[3] test_transform = ImageCms.buildTransform(source_profile, destination_profile, inMode=src_format[0], outMode=dst_format[0]) # test conversion from aux-ful source if transform_in_place: test_image = source_image.copy() ImageCms.applyTransform(test_image, test_transform, inPlace=True) else: test_image = ImageCms.applyTransform(source_image, test_transform, inPlace=False) # reference conversion from aux-less source reference_transform = ImageCms.buildTransform(source_profile, destination_profile, inMode=src_format[2], outMode=dst_format[2]) reference_image = ImageCms.applyTransform(source_image.convert(src_format[2]), reference_transform) self.assert_image_equal(test_image.convert(dst_format[2]), reference_image)
def get_transform(from_name, to_name, to_intent='perceptual', proof_name=None, proof_intent=None, use_black_pt=False): global icc_transform flags = 0 if proof_name is not None: if hasattr(ImageCms, 'FLAGS'): # supporting multiple versions of lcms...sigh.. flags |= ImageCms.FLAGS['SOFTPROOFING'] else: flags |= ImageCms.SOFTPROOFING if use_black_pt: if hasattr(ImageCms, 'FLAGS'): flags |= ImageCms.FLAGS['BLACKPOINTCOMPENSATION'] else: flags |= ImageCms.BLACKPOINTCOMPENSATION key = get_transform_key(from_name, to_name, to_intent, proof_name, proof_intent, flags) try: output_transform = icc_transform[key] except KeyError: # try to build transform on the fly try: if not (proof_name is None): output_transform = ImageCms.buildProofTransform( profile[from_name].path, profile[to_name].path, profile[proof_name].path, 'RGB', 'RGB', renderingIntent=intents[to_intent], proofRenderingIntent=intents[proof_intent], flags=flags) else: output_transform = ImageCms.buildTransform( profile[from_name].path, profile[to_name].path, 'RGB', 'RGB', renderingIntent=intents[to_intent], flags=flags) icc_transform[key] = output_transform except Exception as e: raise Exception("Failed to build profile transform: %s" % (str(e))) return output_transform
def test_lab_roundtrip(self): # check to see if we're at least internally consistent. pLab = ImageCms.createProfile("LAB") t = ImageCms.buildTransform(SRGB, pLab, "RGB", "LAB") t2 = ImageCms.buildTransform(pLab, SRGB, "LAB", "RGB") i = ImageCms.applyTransform(hopper(), t) self.assertEqual(i.info['icc_profile'], ImageCmsProfile(pLab).tobytes()) out = ImageCms.applyTransform(i, t2) self.assert_image_similar(hopper(), out, 2)
def test_lab_srgb(self): pLab = ImageCms.createProfile("LAB") t = ImageCms.buildTransform(pLab, SRGB, "LAB", "RGB") img = Image.open('Tests/images/lena.Lab.tif') img_srgb = ImageCms.applyTransform(img, t) # img_srgb.save('temp.srgb.tif') # visually verified vs ps. self.assert_image_similar(lena(), img_srgb, 30) self.assertTrue(img_srgb.info['icc_profile']) profile = ImageCmsProfile(BytesIO(img_srgb.info['icc_profile'])) self.assertTrue('sRGB' in ImageCms.getProfileDescription(profile))
def test_deprecations(self): self.skip_missing() o = ImageCms.getOpenProfile(SRGB) p = o.profile def helper_deprecated(attr, expected): result = self.assert_warning(DeprecationWarning, getattr, p, attr) self.assertEqual(result, expected) # p.color_space helper_deprecated("color_space", "RGB") # p.pcs helper_deprecated("pcs", "XYZ") # p.product_copyright helper_deprecated( "product_copyright", "Copyright International Color Consortium, 2009" ) # p.product_desc helper_deprecated("product_desc", "sRGB IEC61966-2-1 black scaled") # p.product_description helper_deprecated("product_description", "sRGB IEC61966-2-1 black scaled") # p.product_manufacturer helper_deprecated("product_manufacturer", "") # p.product_model helper_deprecated( "product_model", "IEC 61966-2-1 Default RGB Colour Space - sRGB" )
def srgb(self): try: if not isinstance(self.engine, PILEngine): logger.warn('Could not perform profileToProfile conversion: engine is not PIL engine') return if (ImageCms is None): logger.warn('ImageCms is not installed. Could not perform profileToProfile conversion') return image = self.engine.image embedded_profile = image.info.get('icc_profile') if not embedded_profile: logger.debug('Image does not have embedded profile. Assuming already in sRGB') return embedded_profile = BytesIO(embedded_profile) srgb_profile = BytesIO(tiny_srgb) output_mode = 'RGBA' if 'A' in image.mode else 'RGB' image = ImageCms.profileToProfile(image, embedded_profile, srgb_profile, renderingIntent=0, outputMode=output_mode) self.engine.image = image self.engine.icc_profile = image.info.get('icc_profile') except Exception as err: logger.exception(err)
def icc_profile_apply(self, profile=None): # Check whether input image has color management. if not self.engine.icc_profile: logger.info('ICC: Image has no embedded profile. Skipping this image.') return # Sanitize profile parameter. if profile != None: profile = os.path.basename(profile).lstrip('.') if len(profile) == 0: logger.warning('ICC: Invalid profile name.') return # Find output profile. outprofile = self._find_profile(profile) if not outprofile: logger.warning('ICC: Failed to load profile: {:s}'.format(profile)) return try: ext = self.engine.extension fmt = Image.EXTENSION[ext.lower()] except: logger.exception('ICC: Failed to determine image format and extension before attempting to apply profile: {:s}'.format(profile)) return try: inmode = self.engine.get_image_mode() insize = self.engine.size inimg = Image.frombytes(inmode, insize, self.engine.get_image_data()) # In PIL>=3.0.0 / Thumbor 6, icc_profile is sometimes a tuple :/ # https://github.com/python-pillow/Pillow/issues/1462 profile_data = self.engine.icc_profile if type(profile_data) == tuple: profile_data = profile_data[0] inprofile = StringIO(profile_data) outmode = 'RGBA' if 'A' in inmode else 'RGB' except: logger.exception('ICC: Failed to determine image properties before attempting to apply profile: {:s}'.format(profile)) return logger.info('ICC: Attempting to apply profile: {:s}, inmode: {:s}, outmode: {:s}'.format(profile, inmode, outmode)) try: outimg = ImageCms.profileToProfile(inimg, inprofile, outprofile, outputMode=outmode) except: logger.exception('ICC: Failed to apply profile: {:s}, inmode: {:s}, outmode: {:s}'.format(profile, inmode, outmode)) return # Reload the image into the engine. outbuf = StringIO() try: outimg.save(outbuf, fmt) self.engine.load(outbuf.getvalue(), ext) except: logger.exception('ICC: Failed load the image with an applied profile: {:s}, inmode: {:s}, outmode: {:s}'.format(profile, inmode, outmode)) return finally: outbuf.close()
def prep_for_flickr(self): """ prepares image for upload to flickr """ # create a PNG im_master = Image.open(self.fn_master) try: pf = ImageCms.core.profile_fromstring(im_master.info['icc_profile']) except AttributeError as e: raise type(e), type(e)(e.message + " no icc profile defined on master image '%s'" % self.fn_master), sys.exc_info()[2] else: im_flickr2 = ImageCms.profileToProfile(im_master, pf, PROFILE_SRGB) path = join(self.path, 'flickr2') try: makedirs(path) except OSError as exception: if exception.errno != errno.EEXIST: raise fn = join(path, self.id + '.png') if exists(fn): raise IOError("'file exists :'%s'" % fn) else: im_flickr2.save(fn, format='PNG') self.fn_flickr2 = fn # subprocess.call("exiftool -tagsFromFile %s %s" % (self.fn_master, fn)) # create metadata self.make_flickr_caption()
def test_lab_color(self): psRGB = ImageCms.createProfile("sRGB") pLab = ImageCms.createProfile("LAB") t = ImageCms.buildTransform(psRGB, pLab, "RGB", "LAB") # Need to add a type mapping for some PIL type to TYPE_Lab_8 in # findLCMSType, and have that mapping work back to a PIL mode # (likely RGB). i = ImageCms.applyTransform(hopper(), t) self.assert_image(i, "LAB", (128, 128)) # i.save('temp.lab.tif') # visually verified vs PS. target = Image.open('Tests/images/hopper.Lab.tif') self.assert_image_similar(i, target, 3.5)
def convert_profile_pil_transform(image_pil, transform, inPlace=False): if not have_cms: return image_pil image_out = ImageCms.applyTransform(image_pil, transform, inPlace) if inPlace: return image_pil return image_out
def adobe_to_srgb__fast(img): global COLOR_PROFILES srgb = COLOR_PROFILES['srgb'] icc = COLOR_PROFILES['argb'] img = ImageCms.profileToProfile(img, icc, srgb) #img = ImageCms.profileToProfile(img, icc, srgb, renderingIntent = ImageCms.INTENT_SATURATION) return img
def get_transform(from_name, to_name, to_intent='perceptual', proof_name=None, proof_intent=None, use_black_pt=False): global icc_transform flags = 0 if not (proof_name is None): flags |= ImageCms.SOFTPROOFING if use_black_pt: flags |= ImageCms.BLACKPOINTCOMPENSATION key = get_transform_key(from_name, to_name, to_intent, proof_name, proof_intent, flags) try: output_transform = icc_transform[key] except KeyError: # try to build transform on the fly try: if not (proof_name is None): output_transform = ImageCms.buildProofTransform( profile[from_name], profile[to_name], profile[proof_name], 'RGB', 'RGB', renderingIntent=intents[to_intent], proofRenderingIntent=intents[proof_intent], flags=flags) else: output_transform = ImageCms.buildTransform( profile[from_name], profile[to_name], 'RGB', 'RGB', renderingIntent=intents[to_intent], flags=flags) icc_transform[key] = output_transform except Exception as e: raise Exception("Failed to build profile transform: %s" % (str(e))) return output_transform
def test_simple_lab(): i = Image.new('RGB', (10, 10), (128, 128, 128)) pLab = ImageCms.createProfile("LAB") t = ImageCms.buildTransform(SRGB, pLab, "RGB", "LAB") i_lab = ImageCms.applyTransform(i, t) assert_equal(i_lab.mode, 'LAB') k = i_lab.getpixel((0, 0)) assert_equal(k, (137, 128, 128)) # not a linear luminance map. so L != 128 L = i_lab.getdata(0) a = i_lab.getdata(1) b = i_lab.getdata(2) assert_equal(list(L), [137] * 100) assert_equal(list(a), [128] * 100) assert_equal(list(b), [128] * 100)
def test_extended_information(self): self.skip_missing() o = ImageCms.getOpenProfile(SRGB) p = o.profile self.assertEqual(p.attributes, 4294967296) self.assertEqual(p.blue_colorant, ((0.14306640625, 0.06060791015625, 0.7140960693359375), (0.1558847490315394, 0.06603820639433387, 0.06060791015625))) self.assertEqual(p.blue_primary, ((0.14306641366715667, 0.06060790921083026, 0.7140960805782015), (0.15588475410450106, 0.06603820408959558, 0.06060790921083026))) self.assertEqual(p.chromatic_adaptation, (((1.04791259765625, 0.0229339599609375, -0.050201416015625), (0.02960205078125, 0.9904632568359375, -0.0170745849609375), (-0.009246826171875, 0.0150604248046875, 0.7517852783203125)), ((1.0267159024652783, 0.022470062342089134, 0.0229339599609375), (0.02951378324103937, 0.9875098886387147, 0.9904632568359375), (-0.012205438066465256, 0.01987915407854985, 0.0150604248046875)))) self.assertEqual(p.chromaticity, None) self.assertEqual(p.clut, {0: (False, False, True), 1: (False, False, True), 2: (False, False, True), 3: (False, False, True)}) self.assertEqual(p.color_space, 'RGB') self.assertEqual(p.colorant_table, None) self.assertEqual(p.colorant_table_out, None) self.assertEqual(p.colorimetric_intent, None) self.assertEqual(p.connection_space, 'XYZ ') self.assertEqual(p.copyright, 'Copyright International Color Consortium, 2009') self.assertEqual(p.creation_date, datetime.datetime(2009, 2, 27, 21, 36, 31)) self.assertEqual(p.device_class, 'mntr') self.assertEqual(p.green_colorant, ((0.3851470947265625, 0.7168731689453125, 0.097076416015625), (0.32119769927720654, 0.5978443449048152, 0.7168731689453125))) self.assertEqual(p.green_primary, ((0.3851470888162112, 0.7168731974161346, 0.09707641738998518), (0.32119768793686687, 0.5978443567149709, 0.7168731974161346))) self.assertEqual(p.header_flags, 0) self.assertEqual(p.header_manufacturer, '\x00\x00\x00\x00') self.assertEqual(p.header_model, '\x00\x00\x00\x00') self.assertEqual(p.icc_measurement_condition, {'backing': (0.0, 0.0, 0.0), 'flare': 0.0, 'geo': 'unknown', 'observer': 1, 'illuminant_type': 'D65'}) self.assertEqual(p.icc_version, 33554432) self.assertEqual(p.icc_viewing_condition, None) self.assertEqual(p.intent_supported, {0: (True, True, True), 1: (True, True, True), 2: (True, True, True), 3: (True, True, True)}) self.assertEqual(p.is_matrix_shaper, True) self.assertEqual(p.luminance, ((0.0, 80.0, 0.0), (0.0, 1.0, 80.0))) self.assertEqual(p.manufacturer, None) self.assertEqual(p.media_black_point, ((0.012054443359375, 0.0124969482421875, 0.01031494140625), (0.34573304157549234, 0.35842450765864337, 0.0124969482421875))) self.assertEqual(p.media_white_point, ((0.964202880859375, 1.0, 0.8249053955078125), (0.3457029219802284, 0.3585375327567059, 1.0))) self.assertEqual(p.media_white_point_temperature, 5000.722328847392) self.assertEqual(p.model, 'IEC 61966-2-1 Default RGB Colour Space - sRGB') self.assertEqual(p.pcs, 'XYZ') self.assertEqual(p.perceptual_rendering_intent_gamut, None) self.assertEqual(p.product_copyright, 'Copyright International Color Consortium, 2009') self.assertEqual(p.product_desc, 'sRGB IEC61966-2-1 black scaled') self.assertEqual(p.product_description, 'sRGB IEC61966-2-1 black scaled') self.assertEqual(p.product_manufacturer, '') self.assertEqual(p.product_model, 'IEC 61966-2-1 Default RGB Colour Space - sRGB') self.assertEqual(p.profile_description, 'sRGB IEC61966-2-1 black scaled') self.assertEqual(p.profile_id, b')\xf8=\xde\xaf\xf2U\xaexB\xfa\xe4\xca\x839\r') self.assertEqual(p.red_colorant, ((0.436065673828125, 0.2224884033203125, 0.013916015625), (0.6484536316398539, 0.3308524880306778, 0.2224884033203125))) self.assertEqual(p.red_primary, ((0.43606566581047446, 0.22248840582960838, 0.013916015621759925), (0.6484536250319214, 0.3308524944738204, 0.22248840582960838))) self.assertEqual(p.rendering_intent, 0) self.assertEqual(p.saturation_rendering_intent_gamut, None) self.assertEqual(p.screening_description, None) self.assertEqual(p.target, None) self.assertEqual(p.technology, 'CRT ') self.assertEqual(p.version, 2.0) self.assertEqual(p.viewing_condition, 'Reference Viewing Condition in IEC 61966-2-1') self.assertEqual(p.xcolor_space, 'RGB ')
def convert_color_profile(self): icc_profile = self.image.info.get('icc_profile') if not icc_profile: return self try: image_profile = ImageCms.ImageCmsProfile(BytesIO(icc_profile)) image = ImageCms.profileToProfile( self.image, image_profile, RGB_PROFILE) except Exception: return self return self.new_engine_image(image)
def test_profile_tobytes(self): i = Image.open("Tests/images/rgb.jpg") p = ImageCms.getOpenProfile(BytesIO(i.info["icc_profile"])) p2 = ImageCms.getOpenProfile(BytesIO(p.tobytes())) # not the same bytes as the original icc_profile, # but it does roundtrip self.assertEqual(p.tobytes(), p2.tobytes()) self.assertEqual(ImageCms.getProfileName(p), ImageCms.getProfileName(p2)) self.assertEqual(ImageCms.getProfileDescription(p), ImageCms.getProfileDescription(p2))
def assert_aux_channel_preserved(self, mode, transform_in_place, preserved_channel): def create_test_image(): # set up test image with something interesting in the tested aux # channel. nine_grid_deltas = [ # noqa: E128 (-1, -1), (-1, 0), (-1, 1), (0, -1), (0, 0), (0, 1), (1, -1), (1, 0), (1, 1), ] chans = [] bands = ImageMode.getmode(mode).bands for band_ndx in range(len(bands)): channel_type = 'L' # 8-bit unorm channel_pattern = hopper(channel_type) # paste pattern with varying offsets to avoid correlation # potentially hiding some bugs (like channels getting mixed). paste_offset = ( int(band_ndx / float(len(bands)) * channel_pattern.size[0]), int(band_ndx / float(len(bands) * 2) * channel_pattern.size[1]) ) channel_data = Image.new(channel_type, channel_pattern.size) for delta in nine_grid_deltas: channel_data.paste( channel_pattern, tuple(paste_offset[c] + delta[c] * channel_pattern.size[c] for c in range(2)), ) chans.append(channel_data) return Image.merge(mode, chans) source_image = create_test_image() source_image_aux = source_image.getchannel(preserved_channel) # create some transform, it doesn't matter which one source_profile = ImageCms.createProfile("sRGB") destination_profile = ImageCms.createProfile("sRGB") t = ImageCms.buildTransform( source_profile, destination_profile, inMode=mode, outMode=mode) # apply transform if transform_in_place: ImageCms.applyTransform(source_image, t, inPlace=True) result_image = source_image else: result_image = ImageCms.applyTransform( source_image, t, inPlace=False) result_image_aux = result_image.getchannel(preserved_channel) self.assert_image_equal(source_image_aux, result_image_aux)
def test_lab_roundtrip(): # check to see if we're at least internally consistent. psRGB = ImageCms.createProfile("sRGB") pLab = ImageCms.createProfile("LAB") t = ImageCms.buildTransform(psRGB, pLab, "RGB", "LAB") t2 = ImageCms.buildTransform(pLab, psRGB, "LAB", "RGB") i = ImageCms.applyTransform(hopper(), t) assert i.info["icc_profile"] == ImageCmsProfile(pLab).tobytes() out = ImageCms.applyTransform(i, t2) assert_image_similar(hopper(), out, 2)
def convert(source_dir='.', target_dir='.', available_formats=['jpg']): print("converting...") filenames = os.listdir(source_dir) filenames = [ filename for filename in filenames if filename.split('.')[-1] in available_formats ] total = len(filenames) print("total {} files".format(total)) for i in range(total): sys.stdout.write("\r%4d/%d" % (i + 1, total)) sys.stdout.flush() image = Image.open(filenames[i]) if image.mode == 'CMYK': image = ImageCms.profileToProfile(image, 'USWebCoatedSWOP.icc', 'sRGB Color Space Profile.icm', renderingIntent=0, outputMode='RGB') image.save(open(os.path.join(target_dir, filename), 'wb')) print("done")
def __init__(self): # load the sRGB2014 ICC color profile iccpath = pathlib.Path( __file__).absolute().parent / "icc" / "sRGB2014.icc" srgb = ImageCms.getOpenProfile(str(iccpath)) # construct the correct pdf dict. first the output profile # N=3 is required for RGB colorspaces op = pdfrw.IndirectPdfDict(N=3, Alternate=pdfrw.PdfName("DeviceRGB")) op.stream = srgb.tobytes().decode("latin-1") # then the outputintents array oi = pdfrw.IndirectPdfDict( Type=pdfrw.PdfName("OutputIntent"), S=pdfrw.PdfName("GTS_PDFA1"), OutputConditionIdentifier="sRGB", DestOutputProfile=op, Info=srgb.profile.profile_description, # I am not sure whether this is correct, but it doesn't fail RegistryName="http://color.org/srgbprofiles.xalter") self.output_intent = [oi]
def ensure_srgb(image): """ Process an image file of unknown color profile. Transform to sRGB profile and return the result. """ if not SRGB_PROFILE or image.mode in (u'L', u'LA', u'I'): return image with NamedTemporaryFile(suffix='.icc', delete=True) as icc_file: profile = image.info.get('icc_profile') if profile: icc_file.write(profile) icc_file.flush() try: output_mode = 'RGBA' if is_transparent(image) else 'RGB' image = ImageCms.profileToProfile(image, icc_file.name, SRGB_PROFILE, outputMode=output_mode) except PyCMSError: log.error("Unable to apply color profile!") pass return image
def icc(self) -> Optional[ImageCms.ImageCmsProfile]: """If an ICC profile is attached, return a Pillow object that describe it. Most of the information may be found in ``icc.profile``. """ if self.colorspace not in ('/ICCBased', '/Indexed'): return None if not self._icc: iccstream = self._iccstream iccbuffer = iccstream.get_stream_buffer() iccbytesio = BytesIO(iccbuffer) try: self._icc = ImageCms.ImageCmsProfile(iccbytesio) except OSError as e: if str(e) == 'cannot open profile from string': # ICC profile is corrupt raise UnsupportedImageTypeError( "ICC profile corrupt or not readable" ) from e return self._icc
def _get_specific_monitor_primaries(filename="./icc_profile/gamut.icc"): """ iccプロファイルからモニターのprimary情報を取得する Parameters ---------- filename : string filename of the icc profile. Returns ------- array_like prmaries. [[rx, ry], [gx, gy], [bx, by], [rx, ry]] """ icc_profile = ImageCms.getOpenProfile(filename) r = icc_profile.profile.red_primary g = icc_profile.profile.green_primary b = icc_profile.profile.blue_primary primaries = [r[1][:-1], g[1][:-1], b[1][:-1], r[1][:-1]] return np.array(primaries)
def test_lab_color_profile(self): ImageCms.createProfile("LAB", 5000) ImageCms.createProfile("LAB", 6500)
def test_description(self): self.skip_missing() self.assertEqual( ImageCms.getProfileDescription(SRGB).strip(), 'sRGB IEC61966-2-1 black scaled')
def test_display_profile(self): # try fetching the profile for the current display device ImageCms.get_display_profile()
def test_extensions(): # extensions i = Image.open("Tests/images/rgb.jpg") p = ImageCms.getOpenProfile(BytesIO(i.info["icc_profile"])) assert_equal(ImageCms.getProfileName(p).strip(), 'IEC 61966-2.1 Default RGB colour space - sRGB')
def test_model(self): self.skip_missing() self.assertEqual( ImageCms.getProfileModel(SRGB).strip(), 'IEC 61966-2-1 Default RGB Colour Space - sRGB')
def test_sanity(): # basic smoke test. # this mostly follows the cms_test outline. v = ImageCms.versions() # should return four strings assert_equal(v[0], '0.1.0 pil') assert_equal(map(type, v), [str, str, str, str]) # internal version number assert_match(ImageCms.core.littlecms_version, "\d+\.\d+$") i = ImageCms.profileToProfile(lena(), SRGB, SRGB) assert_image(i, "RGB", (128, 128)) t = ImageCms.buildTransform(SRGB, SRGB, "RGB", "RGB") i = ImageCms.applyTransform(lena(), t) assert_image(i, "RGB", (128, 128)) p = ImageCms.createProfile("sRGB") o = ImageCms.getOpenProfile(SRGB) t = ImageCms.buildTransformFromOpenProfiles(p, o, "RGB", "RGB") i = ImageCms.applyTransform(lena(), t) assert_image(i, "RGB", (128, 128)) t = ImageCms.buildProofTransform(SRGB, SRGB, SRGB, "RGB", "RGB") assert_equal(t.inputMode, "RGB") assert_equal(t.outputMode, "RGB") i = ImageCms.applyTransform(lena(), t) assert_image(i, "RGB", (128, 128)) # get profile information for file assert_equal( ImageCms.getProfileName(SRGB).strip(), 'IEC 61966-2.1 Default RGB colour space - sRGB') assert_equal( ImageCms.getProfileInfo(SRGB).splitlines(), [ 'sRGB IEC61966-2.1', '', 'Copyright (c) 1998 Hewlett-Packard Company', '', 'WhitePoint : D65 (daylight)', '', 'Tests/icc/sRGB.icm' ]) assert_equal(ImageCms.getDefaultIntent(SRGB), 0) assert_equal( ImageCms.isIntentSupported(SRGB, ImageCms.INTENT_ABSOLUTE_COLORIMETRIC, ImageCms.DIRECTION_INPUT), 1) # same, using profile object p = ImageCms.createProfile("sRGB") assert_equal( ImageCms.getProfileName(p).strip(), 'sRGB built-in - (lcms internal)') assert_equal( ImageCms.getProfileInfo(p).splitlines(), ['sRGB built-in', '', 'WhitePoint : D65 (daylight)', '', '']) assert_equal(ImageCms.getDefaultIntent(p), 0) assert_equal( ImageCms.isIntentSupported(p, ImageCms.INTENT_ABSOLUTE_COLORIMETRIC, ImageCms.DIRECTION_INPUT), 1) # extensions i = Image.open("Tests/images/rgb.jpg") p = ImageCms.getOpenProfile(StringIO(i.info["icc_profile"])) assert_equal( ImageCms.getProfileName(p).strip(), 'IEC 61966-2.1 Default RGB colour space - sRGB') # the procedural pyCMS API uses PyCMSError for all sorts of errors assert_exception(ImageCms.PyCMSError, lambda: ImageCms.profileToProfile(lena(), "foo", "bar")) assert_exception( ImageCms.PyCMSError, lambda: ImageCms.buildTransform("foo", "bar", "RGB", "RGB")) assert_exception(ImageCms.PyCMSError, lambda: ImageCms.getProfileName(None)) assert_exception(ImageCms.PyCMSError, lambda: ImageCms.isIntentSupported(SRGB, None, None)) # test PointTransform convenience API im = lena().point(t) # try fetching the profile for the current display device assert_no_exception(lambda: ImageCms.get_display_profile())
def test_exceptions(): # the procedural pyCMS API uses PyCMSError for all sorts of errors assert_exception(ImageCms.PyCMSError, lambda: ImageCms.profileToProfile(lena(), "foo", "bar")) assert_exception(ImageCms.PyCMSError, lambda: ImageCms.buildTransform("foo", "bar", "RGB", "RGB")) assert_exception(ImageCms.PyCMSError, lambda: ImageCms.getProfileName(None)) assert_exception(ImageCms.PyCMSError, lambda: ImageCms.isIntentSupported(SRGB, None, None))
from PIL import Image, ImageCms im = Image.open(image_path) if im.mode != "RGB": im = im.convert("RGB") srgb_profile = ImageCms.createProfile("sRGB") lab_profile = ImageCms.createProfile("LAB") rgb2lab_transform = ImageCms.buildTransformFromOpenProfiles( srgb_profile, lab_profile, "RGB", "LAB") lab_im = ImageCms.applyTransform(im, rgb2lab_transform)
def test_lab_color_profile(): pLab = ImageCms.createProfile("LAB", 5000) pLab = ImageCms.createProfile("LAB", 6500)
def Selected_ICC(self, icc): self.popUpModal.close() profile = ImageCms.getOpenProfile('icc/CMYK/' + icc) self.layout.Assign_Icc(profile) self.CheckLayOut()
if not flat: key_img = key_img.rotate(-self.rotation_angle, resample=Image.BILINEAR, expand=1) return key_img def model(self, scene): # create model, then rotate and place model = self.create_model(scene) location, res = self.get_model_location(), self.model_res model.rotation_euler = (0, 0, math.radians(-self.rotation_angle)) model.location = (-location[0] * res, location[1] * res, 0) return model srgb_profile, lab_profile = ImageCms.createProfile( 'sRGB'), ImageCms.createProfile('LAB', colorTemp=5000) rgb2lab_transform = ImageCms.buildTransformFromOpenProfiles( srgb_profile, lab_profile, 'RGB', 'LAB') lab2rgb_transform = ImageCms.buildTransformFromOpenProfiles( lab_profile, srgb_profile, 'LAB', 'RGB') @functools.lru_cache() def open_base_img(full_profile, res, base_color, color): # get base image according to profile and perceptual gray of key color base_num = str([0xE0, 0xB0, 0x80, 0x50, 0x20].index(base_color) + 1) # open image and convert to Lab with Image.open('images/{0}_{1}{2}.png'.format(*full_profile, base_num)) as img: key_img = img.resize((int(s * res / 200) for s in img.size),
def test_name(self): self.skip_missing() # get profile information for file self.assertEqual( ImageCms.getProfileName(SRGB).strip(), 'IEC 61966-2-1 Default RGB Colour Space - sRGB')
async def icc_profile_apply(self, profile=None): """ Optain an RGB(A) image by applying the given profile. """ # Check whether input image has color management. if not self.engine.icc_profile: logger.info("ICC: Image has no embedded profile. " "Skipping this image.") return # Sanitize profile parameter. if profile is not None: profile = os.path.basename(profile).lstrip(".") if not profile: logger.warning("ICC: Invalid profile name.") return # Find output profile. outprofile = self._find_profile(profile) if not outprofile: logger.warning("ICC: Failed to load profile: {:s}".format(profile)) return try: ext = self.engine.extension fmt = Image.EXTENSION[ext.lower()] except Exception: logger.exception("ICC: Failed to determine image format and " "extension before attempting to apply " "profile: {:s}".format(profile)) return try: inmode = self.engine.get_image_mode() insize = self.engine.size indata = self.engine.get_image_data() inimg = Image.frombytes(inmode, insize, indata) inprofile = BytesIO(self.engine.icc_profile) outmode = "RGBA" if "A" in inmode else "RGB" except Exception: logger.exception("ICC: Failed to determine image " "properties before attempting to apply " "profile: {:s}".format(profile)) return logger.info("ICC: Attempting to apply profile: {:s}, inmode: {:s}, " "outmode: {:s}".format(profile, inmode, outmode)) try: outimg = ImageCms.profileToProfile(inimg, inprofile, outprofile, outputMode=outmode) except Exception: logger.exception("ICC: Failed to apply profile: {:s}, " "inmode: {:s}, " "outmode: {:s}".format(profile, inmode, outmode)) return # Reload the image into the engine. outbuf = BytesIO() try: outimg.save(outbuf, fmt) self.engine.load(outbuf.getvalue(), ext) except Exception: logger.exception("ICC: Failed load the image with an applied " "profile: {:s}, inmode: {:s}, " "outmode: {:s}".format(profile, inmode, outmode)) return finally: outbuf.close()
def test_manufacturer(self): self.skip_missing() self.assertEqual(ImageCms.getProfileManufacturer(SRGB).strip(), '')
def test_extended_information(self): self.skip_missing() o = ImageCms.getOpenProfile(SRGB) p = o.profile def assert_truncated_tuple_equal(tup1, tup2, digits=10): # Helper function to reduce precision of tuples of floats # recursively and then check equality. power = 10**digits def truncate_tuple(tuple_or_float): return tuple( truncate_tuple(val) if isinstance(val, tuple ) else int(val * power) / power for val in tuple_or_float) self.assertEqual(truncate_tuple(tup1), truncate_tuple(tup2)) self.assertEqual(p.attributes, 4294967296) assert_truncated_tuple_equal( p.blue_colorant, ((0.14306640625, 0.06060791015625, 0.7140960693359375), (0.1558847490315394, 0.06603820639433387, 0.06060791015625))) assert_truncated_tuple_equal( p.blue_primary, ((0.14306641366715667, 0.06060790921083026, 0.7140960805782015), (0.15588475410450106, 0.06603820408959558, 0.06060790921083026))) assert_truncated_tuple_equal( p.chromatic_adaptation, (((1.04791259765625, 0.0229339599609375, -0.050201416015625), (0.02960205078125, 0.9904632568359375, -0.0170745849609375), (-0.009246826171875, 0.0150604248046875, 0.7517852783203125)), ((1.0267159024652783, 0.022470062342089134, 0.0229339599609375), (0.02951378324103937, 0.9875098886387147, 0.9904632568359375), (-0.012205438066465256, 0.01987915407854985, 0.0150604248046875)))) self.assertIsNone(p.chromaticity) self.assertEqual( p.clut, { 0: (False, False, True), 1: (False, False, True), 2: (False, False, True), 3: (False, False, True) }) self.assertEqual(p.color_space, 'RGB') self.assertIsNone(p.colorant_table) self.assertIsNone(p.colorant_table_out) self.assertIsNone(p.colorimetric_intent) self.assertEqual(p.connection_space, 'XYZ ') self.assertEqual(p.copyright, 'Copyright International Color Consortium, 2009') self.assertEqual(p.creation_date, datetime.datetime(2009, 2, 27, 21, 36, 31)) self.assertEqual(p.device_class, 'mntr') assert_truncated_tuple_equal( p.green_colorant, ((0.3851470947265625, 0.7168731689453125, 0.097076416015625), (0.32119769927720654, 0.5978443449048152, 0.7168731689453125))) assert_truncated_tuple_equal( p.green_primary, ((0.3851470888162112, 0.7168731974161346, 0.09707641738998518), (0.32119768793686687, 0.5978443567149709, 0.7168731974161346))) self.assertEqual(p.header_flags, 0) self.assertEqual(p.header_manufacturer, '\x00\x00\x00\x00') self.assertEqual(p.header_model, '\x00\x00\x00\x00') self.assertEqual( p.icc_measurement_condition, { 'backing': (0.0, 0.0, 0.0), 'flare': 0.0, 'geo': 'unknown', 'observer': 1, 'illuminant_type': 'D65' }) self.assertEqual(p.icc_version, 33554432) self.assertIsNone(p.icc_viewing_condition) self.assertEqual( p.intent_supported, { 0: (True, True, True), 1: (True, True, True), 2: (True, True, True), 3: (True, True, True) }) self.assertTrue(p.is_matrix_shaper) self.assertEqual(p.luminance, ((0.0, 80.0, 0.0), (0.0, 1.0, 80.0))) self.assertIsNone(p.manufacturer) assert_truncated_tuple_equal( p.media_black_point, ((0.012054443359375, 0.0124969482421875, 0.01031494140625), (0.34573304157549234, 0.35842450765864337, 0.0124969482421875))) assert_truncated_tuple_equal( p.media_white_point, ((0.964202880859375, 1.0, 0.8249053955078125), (0.3457029219802284, 0.3585375327567059, 1.0))) assert_truncated_tuple_equal((p.media_white_point_temperature, ), (5000.722328847392, )) self.assertEqual(p.model, 'IEC 61966-2-1 Default RGB Colour Space - sRGB') self.assertEqual(p.pcs, 'XYZ') self.assertIsNone(p.perceptual_rendering_intent_gamut) self.assertEqual(p.product_copyright, 'Copyright International Color Consortium, 2009') self.assertEqual(p.product_desc, 'sRGB IEC61966-2-1 black scaled') self.assertEqual(p.product_description, 'sRGB IEC61966-2-1 black scaled') self.assertEqual(p.product_manufacturer, '') self.assertEqual(p.product_model, 'IEC 61966-2-1 Default RGB Colour Space - sRGB') self.assertEqual(p.profile_description, 'sRGB IEC61966-2-1 black scaled') self.assertEqual(p.profile_id, b')\xf8=\xde\xaf\xf2U\xaexB\xfa\xe4\xca\x839\r') assert_truncated_tuple_equal( p.red_colorant, ((0.436065673828125, 0.2224884033203125, 0.013916015625), (0.6484536316398539, 0.3308524880306778, 0.2224884033203125))) assert_truncated_tuple_equal( p.red_primary, ((0.43606566581047446, 0.22248840582960838, 0.013916015621759925), (0.6484536250319214, 0.3308524944738204, 0.22248840582960838))) self.assertEqual(p.rendering_intent, 0) self.assertIsNone(p.saturation_rendering_intent_gamut) self.assertIsNone(p.screening_description) self.assertIsNone(p.target) self.assertEqual(p.technology, 'CRT ') self.assertEqual(p.version, 2.0) self.assertEqual(p.viewing_condition, 'Reference Viewing Condition in IEC 61966-2-1') self.assertEqual(p.xcolor_space, 'RGB ')
def test_display_profile(): # try fetching the profile for the current display device assert_no_exception(lambda: ImageCms.get_display_profile())
def test_sanity(self): # basic smoke test. # this mostly follows the cms_test outline. v = ImageCms.versions() # should return four strings self.assertEqual(v[0], '1.0.0 pil') self.assertEqual(list(map(type, v)), [str, str, str, str]) # internal version number self.assertRegexpMatches(ImageCms.core.littlecms_version, r"\d+\.\d+$") self.skip_missing() i = ImageCms.profileToProfile(hopper(), SRGB, SRGB) self.assert_image(i, "RGB", (128, 128)) i = hopper() ImageCms.profileToProfile(i, SRGB, SRGB, inPlace=True) self.assert_image(i, "RGB", (128, 128)) t = ImageCms.buildTransform(SRGB, SRGB, "RGB", "RGB") i = ImageCms.applyTransform(hopper(), t) self.assert_image(i, "RGB", (128, 128)) i = hopper() t = ImageCms.buildTransform(SRGB, SRGB, "RGB", "RGB") ImageCms.applyTransform(hopper(), t, inPlace=True) self.assert_image(i, "RGB", (128, 128)) p = ImageCms.createProfile("sRGB") o = ImageCms.getOpenProfile(SRGB) t = ImageCms.buildTransformFromOpenProfiles(p, o, "RGB", "RGB") i = ImageCms.applyTransform(hopper(), t) self.assert_image(i, "RGB", (128, 128)) t = ImageCms.buildProofTransform(SRGB, SRGB, SRGB, "RGB", "RGB") self.assertEqual(t.inputMode, "RGB") self.assertEqual(t.outputMode, "RGB") i = ImageCms.applyTransform(hopper(), t) self.assert_image(i, "RGB", (128, 128)) # test PointTransform convenience API hopper().point(t)
def apply_corrections(result): result = result.strip() result = result.replace('/', '7') result = result.replace('&', '8') result = result.replace('S', '5') result = result.replace(' ', '') result = result[:5] result = result.lower() return result im = Image.open('captcha.png') # Convert to L*a*b colorspace is more complex: rgb = ImageCms.createProfile(colorSpace='sRGB') lab = ImageCms.createProfile(colorSpace='LAB') transform = ImageCms.buildTransform(inputProfile=rgb, outputProfile=lab, inMode='RGB', outMode='LAB') lab_im = ImageCms.applyTransform(im=im, transform=transform) lab_im = rescale(lab_im) l, a, b = lab_im.split() # Convert to numpy array and apply the threshold to remove lines np_a = np.array(a) threshold = 180 np_a[np_a < threshold] = 0
def test_copyright(self): self.skip_missing() self.assertEqual( ImageCms.getProfileCopyright(SRGB).strip(), 'Copyright International Color Consortium, 2009')
from PIL import ImageFile ImageFile.LOAD_TRUNCATED_IMAGES = True # https://docs.opencv.org/master/index.html import cv2 import numpy # drop an image on this script file img_path = Path(sys.argv[1]) # open image with Pillow and convert it to RGB if the image is CMYK img = Image.open(str(img_path)) if img.mode == "CMYK": img = ImageCms.profileToProfile( img, "Color Profiles\\USWebCoatedSWOP.icc", "Color Profiles\\sRGB_Color_Space_Profile.icm", outputMode="RGB") img = cv2.cvtColor(numpy.array(img), cv2.COLOR_RGB2BGR) gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) threshed = cv2.threshold(gray, 240, 255, cv2.THRESH_BINARY_INV)[1] kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (11, 11)) morphed = cv2.morphologyEx(threshed, cv2.MORPH_CLOSE, kernel) contours = cv2.findContours(morphed, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)[-2] mask = numpy.zeros(img.shape, numpy.uint8) mask = cv2.drawContours(mask, contours, -1, (255, 255, 255), -1) new_name_path = str(
import sys sys.path.insert(0, ".") from PIL import Image from PIL import ImageCms try: filename = sys.argv[1] except IndexError: filename = "../pil-archive/cmyk.jpg" i = Image.open(filename) print(i.format) print(i.mode) print(i.size) print(i.tile) p = ImageCms.getMemoryProfile(i.info["icc_profile"]) print(repr(p.product_name)) print(repr(p.product_info)) o = ImageCms.createProfile("sRGB") t = ImageCms.buildTransformFromOpenProfiles(p, o, i.mode, "RGB") i = ImageCms.applyTransform(i, t) i.show()
def resize_img(path, size): files_exten = [ 'jpg', 'JPG', 'JPEG', 'png', 'tiff', 'tif', 'TIFF', 'PNG', ] print(f'Path to search: {path}') files = [] for file in os.listdir(path): x = file.split('.') if len(x) > 1: if x[1] in files_exten: files.append(file) extentions = [] for ext in files: if '.' in ext: extention = ext.split('.') extentions.append(extention[1]) print(f'{len(extentions)} find!') if os.path.isdir(path + '/resized_to_' + str(size) + 'px'): pass else: os.mkdir(path + '/resized_to_' + str(size) + 'px') count = 0 for x in files: if extentions[count] in files_exten: dir_img = path + '/' + files[count] img = Image.open(dir_img) if img.mode == 'RGBA': img = img.convert('RGB') icc = img.info.get('icc_profile', '') if icc: handler = io.BytesIO(icc) src_profile = ImageCms.ImageCmsProfile(handler) dst_profile = ImageCms.createProfile('sRGB') img = ImageCms.profileToProfile(img, src_profile, dst_profile) new_size_y = int(size) / (int(img.size[0]) / int(img.size[1])) rezized = img.resize((size, int(new_size_y)), Image.LANCZOS) new_name = files[count].split('.') save_file = path + '/resized_to_' + str(size) + 'px/' + str( new_name[0]) + '.jpeg' rezized.save(save_file, 'JPEG', quality=90) print(f'image {files[count]} resized!') count += 1 else: print(f'{x} not rezized') count += 1 return count
def __init__(self, source): #Pass in the argument image location #get the location of the image self.source = source #determine if the image is local or hosted, then open it if 'http' in self.source: if(_verbose): print 'Reading from URL' file = cStringIO.StringIO(urllib.urlopen(self.source).read()) self.image = Image.open(file) else: try: self.image = Image.open(self.source) except IOError: print self.source print "Cannot load image. Be sure to include 'http://'' if loading from a website!" sys.exit() sRGB = ImageCms.createProfile("sRGB") pLab = ImageCms.createProfile("LAB") t = ImageCms.buildTransform(sRGB, pLab, "RGB", "LAB") self.labImage = ImageCms.applyTransform(self.image, t) self.imageWidth, self.imageHeight = self.image.size #Set width and height, which correspond to tuple values from self.image.size self.screenWidth, self.screenHeight = int(screen.split()[7]), int(screen.split()[9][:-1]) self.lost_res = 0.0 self.lost_aspect = 0.0 self.temp_rating = self.calcAvgImageTemp() self.final_rating = self.calcImageScore()