def convert_image(image_path):
    # Take an image pathname
    # Returns an Image object with the profile converted
    img = Image.open(image_path)

    # If there is an embedded profile, write it and use it for conversion
    if 'icc_profile' in img.info:

        with open('/tmp/profile.icc', 'wb') as f:
            f.write(img.info.get('icc_profile'))
        result = profileToProfile(img,
                                  '/tmp/profile.icc',
                                  'sRGB.icm',
                                  outputMode='RGB')
        return result

    elif 'CMYK' in img.mode:
        result = profileToProfile(img,
                                  'CMYK.icc',
                                  'sRGB.icm',
                                  outputMode='RGB')
        return result

    else:
        return img
Exemple #2
0
    def _run_transform(self, target_fp, image_request, kdu_cmd, fifo_fp):
        try:
            # Start the kdu shellout. Blocks until the pipe is empty
            kdu_expand_proc = subprocess.Popen(kdu_cmd,
                                               shell=True,
                                               bufsize=-1,
                                               stderr=subprocess.PIPE,
                                               env=self.env)
            with open(fifo_fp, 'rb') as f:
                # read from the named pipe
                p = Parser()
                while True:
                    s = f.read(1024)
                    if not s:
                        break
                    p.feed(s)
                im = p.close()  # a PIL.Image
        finally:
            stdoutdata, stderrdata = kdu_expand_proc.communicate()
            kdu_exit = kdu_expand_proc.returncode
            if kdu_exit != 0:
                map(logger.error, stderrdata)
            unlink(fifo_fp)

        if self.map_profile_to_srgb and image_request.info.color_profile_bytes:  # i.e. is not None
            emb_profile = cStringIO.StringIO(
                image_request.info.color_profile_bytes)
            im = profileToProfile(im, emb_profile, self.srgb_profile_fp)

        self._derive_with_pil(im, target_fp, image_request, crop=False)
Exemple #3
0
    def transform(self, src_fp, target_fp, image_request):

        # kdu writes to this:
        fifo_fp = self._make_tmp_fp()

        # kdu command
        #q = '-quiet'
        t = '-num_threads %s' % (self.num_threads,)
        i = '-i "%s"' % (src_fp,)
        o = '-o %s' % (fifo_fp,)
        reduce_arg = self._scales_to_reduce_arg(image_request)
        red = '-reduce %s' % (reduce_arg,) if reduce_arg else ''
        region_arg = self._region_to_kdu_arg(image_request.region_param)
        reg = '-region %s' % (region_arg,) if region_arg else ''

        #kdu_cmd = ' '.join((self.kdu_expand,q,i,t,reg,red,o))
        kdu_cmd = 'LD_LIBRARY_PATH=/opt/kakadu/current/apps/make ' + ' '.join((self.kdu_expand,i,t,reg,red,o))

        # make the named pipe
        mkfifo_call = '%s %s' % (self.mkfifo, fifo_fp)
        logger.debug('Calling %s' % (mkfifo_call,))
        resp = subprocess.check_call(mkfifo_call, shell=True)

        try:
            # Start the kdu shellout. Blocks until the pipe is empty
            logger.debug('Calling: %s' % (kdu_cmd,))
            kdu_expand_proc = subprocess.Popen(kdu_cmd, shell=True, bufsize=-1,
                stderr=subprocess.PIPE, env=self.env)
        
            f = open(fifo_fp, 'rb')
            logger.debug('Opened %s' % fifo_fp)

             # read from the named pipe
            p = Parser()
            while True:
                s = f.read(1024)
                if not s:
                    break
                p.feed(s)
            im = p.close() # a PIL.Image

            # finish kdu
            kdu_exit = kdu_expand_proc.wait()
            if kdu_exit != 0:
                map(logger.error, kdu_expand_proc.stderr)

            if self.map_profile_to_srgb and image_request.info.color_profile_bytes:  # i.e. is not None
                emb_profile = cStringIO.StringIO(image_request.info.color_profile_bytes)
                im = profileToProfile(im, emb_profile, self.srgb_profile_fp)

            self._derive_with_pil(im, target_fp, image_request, crop=False)
        except:
            raise
        finally:
            kdu_exit = kdu_expand_proc.wait()
            if kdu_exit != 0:
                map(logger.error, map(string.strip, kdu_expand_proc.stderr))
            unlink(fifo_fp)
Exemple #4
0
    def transform(self, src_fp, target_fp, image_request):
        # opj writes to this:
        fifo_fp = self._make_tmp_fp()

        # make the named pipe
        mkfifo_call = '%s %s' % (self.mkfifo, fifo_fp)
        logger.debug('Calling %s' % (mkfifo_call, ))
        resp = subprocess.check_call(mkfifo_call, shell=True)
        if resp != 0:
            logger.error('Problem with mkfifo')
        # how to handle CalledProcessError; would have to be a 500?

        # opj_decompress command
        i = '-i "%s"' % (src_fp, )
        o = '-o %s' % (fifo_fp, )
        region_arg = self._region_to_opj_arg(image_request.region_param)
        reg = '-d %s' % (region_arg, ) if region_arg else ''
        reduce_arg = self._scales_to_reduce_arg(image_request)
        red = '-r %s' % (reduce_arg, ) if reduce_arg else ''

        opj_cmd = ' '.join((self.opj_decompress, i, reg, red, o))

        logger.debug('Calling: %s' % (opj_cmd, ))

        # Start the shellout. Blocks until the pipe is empty
        with open(devnull, 'w') as fnull:
            opj_decompress_proc = subprocess.Popen(opj_cmd,
                                                   shell=True,
                                                   bufsize=-1,
                                                   stderr=fnull,
                                                   stdout=fnull,
                                                   env=self.env)

        f = open(fifo_fp, 'rb')
        logger.debug('Opened %s' % fifo_fp)

        # read from the named pipe
        p = Parser()
        while True:
            s = f.read(1024)
            if not s:
                break
            p.feed(s)
        im = p.close()  # a PIL.Image

        # finish opj
        opj_exit = opj_decompress_proc.wait()
        if opj_exit != 0:
            map(logger.error, opj_decompress_proc.stderr)
        unlink(fifo_fp)

        if self.map_profile_to_srgb and image_request.info.color_profile_bytes:  # i.e. is not None
            emb_profile = cStringIO.StringIO(
                image_request.info.color_profile_bytes)
            im = profileToProfile(im, emb_profile, self.srgb_profile_fp)

        self._derive_with_pil(im, target_fp, image_request, crop=False)
Exemple #5
0
    def transform(self, src_fp, target_fp, image_request):
        # opj writes to this:
        fifo_fp = self._make_tmp_fp()

        # make the named pipe
        mkfifo_call = '%s %s' % (self.mkfifo, fifo_fp)
        logger.debug('Calling %s' % (mkfifo_call,))
        resp = subprocess.check_call(mkfifo_call, shell=True)
        if resp != 0:
            logger.error('Problem with mkfifo')
        # how to handle CalledProcessError; would have to be a 500?

        # opj_decompress command
        i = '-i "%s"' % (src_fp,)
        o = '-o %s' % (fifo_fp,)
        region_arg = self._region_to_opj_arg(image_request.region_param)
        reg = '-d %s' % (region_arg,) if region_arg else ''
        reduce_arg = self._scales_to_reduce_arg(image_request)
        red = '-r %s' % (reduce_arg,) if reduce_arg else ''

        opj_cmd = ' '.join((self.opj_decompress,i,reg,red,o))

        logger.debug(fifo_fp)
        logger.debug('Calling: %s' % (opj_cmd,))
        logger.debug(fifo_fp)

        # Start the shellout. Blocks until the pipe is empty
        with open(devnull, 'w') as fnull:
            logger.debug('opening devnull')
            opj_decompress_proc = subprocess.Popen(opj_cmd, shell=True, bufsize=-1,
                stderr=fnull, stdout=fnull, env=self.env)
    
        logger.debug('opening fifo')
        f = open(fifo_fp, 'rb')
        logger.debug('Opened %s' % fifo_fp)

        # read from the named pipe
        p = Parser()
        while True:
            s = f.read(1024)
            if not s:
                break
            p.feed(s)
        im = p.close() # a PIL.Image

        # finish opj
        opj_exit = opj_decompress_proc.wait()
        if opj_exit != 0:
            map(logger.error, opj_decompress_proc.stderr)
        unlink(fifo_fp)

        if self.map_profile_to_srgb and image_request.info.color_profile_bytes:  # i.e. is not None
            emb_profile = cStringIO.StringIO(image_request.info.color_profile_bytes)
            im = profileToProfile(im, emb_profile, self.srgb_profile_fp)

        self._derive_with_pil(im, target_fp, image_request, crop=False)
def convert_to_rgb(img):
    """
    Convert an image to RGB if it isn't already RGB or grayscale
    """
    if img.mode == 'CMYK' and HAS_PROFILE_TO_PROFILE:
        profile_dir = os.path.join(os.path.dirname(__file__), 'profiles')
        input_profile = os.path.join(profile_dir, "USWebUncoated.icc")
        output_profile = os.path.join(profile_dir, "sRGB_v4_ICC_preference.icc")
        return profileToProfile(img, input_profile, output_profile, outputMode='RGB')
    return img
Exemple #7
0
def get_tiff_from_pillow(filepath):
    print 'making tiff using pillow from', filepath
    new_file_path = get_output_file_path(filepath, 'tiff')
    im = Image.open(filepath)
    if 'icc_profile' in im.info:
        print "converting profile"
        src_profile = cStringIO.StringIO(im.info['icc_profile'])
        im = profileToProfile(im, src_profile, srgb_profile_fp)
    im.save(new_file_path)  # , compression=None)

    image_mode = im.mode
    return new_file_path, image_mode
Exemple #8
0
    def __generate_master__(self):
        """
        create a master file from the original already in the package and set all metadata
        """
        # open original
        # capture existing ICC profile (if there is one)
        # if no ICC profile, assign sRGB
        # if ICC profile and != sRGB, convert to sRGB
        # save as uncompressed TIFF

        logger = logging.getLogger(sys._getframe().f_code.co_name)

        profile_srgb2 = os.path.join(
            os.path.dirname(os.path.abspath(__file__)), 'icc',
            'sRGB_IEC61966-2-1_black_scaled.icc')
        profile_srgb4 = os.path.join(
            os.path.dirname(os.path.abspath(__file__)), 'icc',
            'sRGB_v4_ICC_preference.icc')
        original_path = os.path.join(self.path, self.original)
        original_image = Image.open(original_path)
        try:
            raw_profile = original_image.info['icc_profile']
        except KeyError:
            raw_profile = getOpenProfile(profile_srgb2).tobytes()
            logger.warning(
                '{original} does not have an internal ICC color profile'.
                format(original=self.original))
        else:
            logger.debug(
                'detected internal ICC color profile in {original}'.format(
                    original=self.original))
        original_profile = getOpenProfile(BytesIO(raw_profile))
        original_profile_name = getProfileName(original_profile).strip()
        target_profile = getOpenProfile(profile_srgb4)
        target_profile_name = getProfileName(target_profile).strip()
        logger.debug(
            'attempting to convert from "{original}" to "{target}"'.format(
                original=original_profile_name, target=target_profile_name))
        converted_image = profileToProfile(original_image, original_profile,
                                           target_profile)
        master_path = os.path.join(self.path, 'master.tif')
        tiffinfo = TiffImagePlugin.ImageFileDirectory()
        tiffinfo[TiffImagePlugin.ICCPROFILE] = target_profile.tobytes()
        tiffinfo.tagtype[
            TiffImagePlugin.ICCPROFILE] = 1  # byte according to TiffTags.TYPES
        converted_image.DEBUG = True
        converted_image.save(master_path, tiffinfo=tiffinfo)
        hash_master = hash_of_file(master_path)
        logger.debug('saved converted master image to {master}'.format(
            master=master_path))
        self.__append_event__(
            'created master.tif file at {master}'.format(master=master_path))
        self.manifest.set('master.tif', hash_master)
def convert_to_rgb(img):
    """
    Convert an image to RGB if it isn't already RGB or grayscale
    """
    if img.mode == 'CMYK' and HAS_PROFILE_TO_PROFILE:
        profile_dir = os.path.join(os.path.dirname(__file__), 'profiles')
        input_profile = os.path.join(profile_dir, "USWebUncoated.icc")
        output_profile = os.path.join(profile_dir,
                                      "sRGB_v4_ICC_preference.icc")
        return profileToProfile(img,
                                input_profile,
                                output_profile,
                                outputMode='RGB')
    return img
Exemple #10
0
def get_tiff_from_pillow(filepath):
    print 'making tiff using pillow from', filepath
    new_file_path = get_output_file_path(filepath, 'tiff')
    im = Image.open(filepath)
    orientation = get_orientation(im)
    if orientation is not None and orientation > 1:
        im = rotate_as_required(im, orientation)
    if 'icc_profile' in im.info:
        print "converting profile"
        src_profile = cStringIO.StringIO(im.info['icc_profile'])
        im = profileToProfile(im, src_profile, srgb_profile_fp, outputMode='RGB')
    im.save(new_file_path)  # , compression=None)

    image_mode = im.mode
    return new_file_path, image_mode
Exemple #11
0
    def __generate_master__(self):
        """
        create a master file from the original already in the package and set all metadata
        """
        # open original
        # capture existing ICC profile (if there is one)
        # if no ICC profile, assign sRGB
        # if ICC profile and != sRGB, convert to sRGB
        # save as uncompressed TIFF

        logger = logging.getLogger(sys._getframe().f_code.co_name)

        profile_srgb2 = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'icc', 'sRGB_IEC61966-2-1_black_scaled.icc')
        profile_srgb4 = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'icc', 'sRGB_v4_ICC_preference.icc')
        original_path = os.path.join(self.path, self.original)
        original_image = Image.open(original_path)
        try:
            raw_profile = original_image.info['icc_profile']
        except KeyError:
            raw_profile = getOpenProfile(profile_srgb2).tobytes()
            logger.warning('{original} does not have an internal ICC color profile'.format(original=self.original))
        else:
            logger.debug('detected internal ICC color profile in {original}'.format(original=self.original))
        original_profile = getOpenProfile(BytesIO(raw_profile))
        original_profile_name = getProfileName(original_profile).strip()
        target_profile = getOpenProfile(profile_srgb4)
        target_profile_name = getProfileName(target_profile).strip()
        logger.debug('attempting to convert from "{original}" to "{target}"'.format(original=original_profile_name, target=target_profile_name))
        converted_image = profileToProfile(original_image, original_profile, target_profile)
        master_path = os.path.join(self.path, 'master.tif')
        tiffinfo = TiffImagePlugin.ImageFileDirectory()
        tiffinfo[TiffImagePlugin.ICCPROFILE] = target_profile.tobytes()
        tiffinfo.tagtype[TiffImagePlugin.ICCPROFILE] = 1 # byte according to TiffTags.TYPES
        converted_image.DEBUG=True
        converted_image.save(master_path, tiffinfo=tiffinfo)
        hash_master = hash_of_file(master_path)
        logger.debug('saved converted master image to {master}'.format(master=master_path))
        self.__append_event__('created master.tif file at {master}'.format(master=master_path))
        self.manifest.set('master.tif', hash_master)
Exemple #12
0
 def _map_im_profile_to_srgb(self, im, input_profile):
     return profileToProfile(im, input_profile, self.srgb_profile_fp)
Exemple #13
0
    def transform(self, src_fp, target_fp, image_request):

        # kdu writes to this:
        fifo_fp = self._make_tmp_fp()

        # kdu command
        q = '-quiet'
        t = '-num_threads %s' % (self.num_threads, )
        i = '-i "%s"' % (src_fp, )
        o = '-o %s' % (fifo_fp, )
        reduce_arg = self._scales_to_reduce_arg(image_request)
        red = '-reduce %s' % (reduce_arg, ) if reduce_arg else ''
        region_arg = self._region_to_kdu_arg(image_request.region_param)
        reg = '-region %s' % (region_arg, ) if region_arg else ''

        kdu_cmd = ' '.join((self.kdu_expand, q, i, t, reg, red, o))

        # make the named pipe
        mkfifo_call = '%s %s' % (self.mkfifo, fifo_fp)
        logger.debug('Calling %s' % (mkfifo_call, ))
        resp = subprocess.check_call(mkfifo_call, shell=True)

        try:
            # Start the kdu shellout. Blocks until the pipe is empty
            logger.debug('Calling: %s' % (kdu_cmd, ))
            kdu_expand_proc = subprocess.Popen(kdu_cmd,
                                               shell=True,
                                               bufsize=-1,
                                               stderr=subprocess.PIPE,
                                               env=self.env)

            f = open(fifo_fp, 'rb')
            logger.debug('Opened %s' % fifo_fp)

            # read from the named pipe
            p = Parser()
            while True:
                s = f.read(1024)
                if not s:
                    break
                p.feed(s)
            im = p.close()  # a PIL.Image

            # finish kdu
            kdu_exit = kdu_expand_proc.wait()
            if kdu_exit != 0:
                map(logger.error, kdu_expand_proc.stderr)

            if self.map_profile_to_srgb and image_request.info.color_profile_bytes:  # i.e. is not None
                emb_profile = cStringIO.StringIO(
                    image_request.info.color_profile_bytes)
                im = profileToProfile(im, emb_profile, self.srgb_profile_fp)

            self._derive_with_pil(im, target_fp, image_request, crop=False)
        except:
            raise
        finally:
            kdu_exit = kdu_expand_proc.wait()
            if kdu_exit != 0:
                map(logger.error, map(string.strip, kdu_expand_proc.stderr))
            unlink(fifo_fp)
import sys
import os
import time
from PIL import Image
from PIL.ImageCms import profileToProfile

files = sys.argv[1]#drag and drop
if os.path.exists(files):
    filename = os.path.basename(files)
    DisplayP3_PROFILE = "icc/DisplayP3-v4.icc"
    Acer_X27_PROFILE = "icc/Acer_X27.icm"
    SRGB_PROFILE = "icc/sRGB.icm"

    oldImg = Image.open(sys.argv[1])

    newImg = profileToProfile(oldImg, Acer_X27_PROFILE,  DisplayP3_PROFILE)# path before after
    newImg_path = "DisplayP3_"+filename
    newImg.save(newImg_path)

    print(filename+" change successfully!")
    time.sleep( 2 )

Exemple #15
0
def lambda_handler(event, context, size=(256, 256)):
    """
    This lambda function triggered by AWS S3 when any file uploaded to media bucket,
    and tries to create thumbnails to target bucket with desired sizes.
    """
    s3_client = boto3.client('s3')
    for record in event['Records']:
        bucket_name = record['s3']['bucket']['name']
        object_key = record['s3']['object']['key']
        local_key = '/tmp/{}'.format(object_key)
        s3_client.download_file(bucket_name, object_key, local_key)

        try:
            with Image.open(open(local_key, 'rb')) as image:
                image.thumbnail(size)

                # Check and convert icc profile if required and set alpha layer
                if image.mode in ('RGBA',
                                  'LA') or (image.mode == 'P'
                                            and 'transparency' in image.info):
                    output_mode = 'RGBA'
                else:
                    output_mode = 'RGB'

                if image.info.get('icc_profile', None):
                    try:
                        temp_icc_path = tempfile.mkstemp(suffix='.icc')[1]
                        with open(temp_icc_path, 'w+b') as image_orginal_icc:
                            image_orginal_icc.write(
                                image.info.get('icc_profile'))
                        if not getProfileName(temp_icc_path) == getProfileName(
                                desired_icc):
                            image = profileToProfile(image,
                                                     temp_icc_path,
                                                     desired_icc,
                                                     outputMode=output_mode,
                                                     renderingIntent=0)
                            if output_mode == 'RGBA' and image.split()[-1]:
                                image.putalpha(image.split()[-1])
                    except Exception:
                        pass  # icc related failure is not important!
                else:
                    image = image.convert(output_mode)

                # Rotate image if required (for mostly smart phone pictures)
                for tag in ExifTags.TAGS.keys():
                    if ExifTags.TAGS[tag] == 'Orientation':
                        break
                exif = dict(image._getexif().items())
                if exif[tag] == 3:
                    image = image.rotate(180, expand=True)
                elif exif[tag] == 6:
                    image = image.rotate(270, expand=True)
                elif exif[tag] == 8:
                    image = image.rotate(90, expand=True)

                thumbnail_key = '{}_resized.png'.format(local_key)
                image.save(thumbnail_key,
                           "PNG",
                           optimize=True,
                           dpi=[72, 72],
                           compress_level=5,
                           icc_profile=image.info.get('icc_profile'))
                s3_client.upload_file(thumbnail_key, target_bucket_name,
                                      '{}_resized.png'.format(object_key))
        except IOError:
            pass  # PIL could not open file as image.
	def transform(self, src_fp, target_fp, image_request):
		# kdu writes to this:
		fifo_fp = JP2_Transformer._make_tmp_fp(self.tmp_dp, 'bmp')

		# make the named pipe
		mkfifo_call = '%s %s' % (self.mkfifo, fifo_fp)
		logger.debug('Calling %s' % (mkfifo_call,))
		resp = subprocess.check_call(mkfifo_call, shell=True)
		if resp == 0:
			logger.debug('OK')
		# how to handle CalledProcessError; would have to be a 500?

		# kdu command
		q = '-quiet'
		t = '-num_threads 8'
		i = '-i %s' % (src_fp,)
		o = '-o %s' % (fifo_fp,)

		region_arg = JP2_Transformer._region_to_kdu(image_request.region_param)
		reduce_arg = JP2_Transformer._scales_to_kdu_reduce(image_request)

		# kdu can do the rotation if it's a multiple of 90:
		if int(image_request.rotation_param.uri_value) % 90 == 0:
			rotate_downstream = False
			kdu_rotation_arg = JP2_Transformer._rotation_to_kdu(image_request.rotation_param)
			kdu_cmd = ' '.join((self.kdu_expand,q,i,t,region_arg,reduce_arg,kdu_rotation_arg,o))
		else:
			rotate_downstream = True
			kdu_cmd = ' '.join((self.kdu_expand,q,i,t,region_arg,reduce_arg,o))


		logger.debug('Calling: %s' % (kdu_cmd,))

		# Start the kdu shellout. Blocks until the pipe is empty
		kdu_expand_proc = subprocess.Popen(kdu_cmd, shell=True, bufsize=-1, 
			stderr=subprocess.PIPE,	env=self.env)

		f = open(fifo_fp, 'rb')
		logger.debug('Opened %s' % fifo_fp)

		# read from the named pipe
		p = Parser()
		while True:
			s = f.read(1024)
			if not s:
				break
			p.feed(s)
		im = p.close() # a PIL.Image


		# finish kdu
		kdu_exit = kdu_expand_proc.wait()
		if kdu_exit != 0:
			map(logger.error, kdu_expand_proc.stderr)
		unlink(fifo_fp)

		if self.map_profile_to_srgb and image_request.info.color_profile_bytes:	 # i.e. is not None
			emb_profile = cStringIO.StringIO(image_request.info.color_profile_bytes)
			im = profileToProfile(im, emb_profile, self.srgb_profile_fp)

		JP2_Transformer._derive_with_pil(im, target_fp, image_request, rotate=rotate_downstream, crop=False)