Example #1
0
    def test_png_rotate_has_alpha_transparency(self):
        ident = 'test.png'
        rotate = '45'
        request_path = '/%s/full/full/%s/default.png' % (ident, rotate)
        resp = self.client.get(request_path)

        self.assertEqual(resp.status_code, 200)

        image = None
        bytes = StringIO(resp.data)
        p = Parser()
        p.feed(bytes.read())  # all in one gulp!
        image = p.close()
        bytes.close()

        # Get the alpha channel as an itertools.imap
        alpha = self.get_alpha_channel(image)

        # Instantiate transparency as False
        transparency = False

        # Loop on the alpha channel and see if we have a value of
        # 0 which means there's a transparent pixel there
        if alpha != None:
            for i in alpha:
                if i == 0:
                    transparency = True

        self.assertTrue(transparency)
Example #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)
Example #3
0
	def get_image(cls, url):
		"""
		Returned Image instance has response url.
		This might be different than the url param because of redirects.
		"""
		from PIL.ImageFile import Parser as PILParser

		length = 0
		raw_image = None
		with closing(requests.get(url, stream=True)) as response:
			response.raise_for_status()
			response_url = response.url
			parser = PILParser()
			for chunk in response.iter_content(CHUNK_SIZE):
				length += len(chunk)
				if length > IMAGE_MAX_BYTESIZE:
					del parser
					raise cls.MaxBytesException
				parser.feed(chunk)
				# comment this to get the whole file
				if parser.image and parser.image.size:
					raw_image = parser.image
					del parser # free some memory
					break
			# or this to get just the size and format
			# raw_image = parser.close()
		if length == 0:
			raise cls.ZeroBytesException
		if not raw_image:
			raise cls.NoImageException
		image = Image(response_url, raw_image.size, raw_image.format)
		return image
Example #4
0
    def _run_transform(self, target_fp, image_request, image_info, 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:
            _, stderrdata = kdu_expand_proc.communicate()
            kdu_exit = kdu_expand_proc.returncode
            if kdu_exit != 0:
                map(logger.error, stderrdata)
            unlink(fifo_fp)

        try:
            if self.map_profile_to_srgb and image_info.color_profile_bytes:
                emb_profile = BytesIO(image_info.color_profile_bytes)
                im = self._map_im_profile_to_srgb(im, emb_profile)
        except PyCMSError as err:
            logger.warn('Error converting %r to sRGB: %r', im, err)

        self._derive_with_pil(
            im=im,
            target_fp=target_fp,
            image_request=image_request,
            image_info=image_info,
            crop=False
        )
Example #5
0
    def get_image(cls, url):
        """
        Returned Image instance has response url.
        This might be different than the url param because of redirects.
        """
        from PIL.ImageFile import Parser as PILParser

        length = 0
        raw_image = None
        with closing(request.get(url, stream=True)) as response:
            response.raise_for_status()
            response_url = response.url
            parser = PILParser()
            for chunk in response.iter_content(config.CHUNK_SIZE):
                length += len(chunk)
                if length > config.IMAGE_MAX_BYTESIZE:
                    del parser
                    raise cls.MaxBytesException
                parser.feed(chunk)
                # comment this to get the whole file
                if parser.image and parser.image.size:
                    raw_image = parser.image
                    del parser # free some memory
                    break
            # or this to get just the size and format
            # raw_image = parser.close()
        if length == 0:
            raise cls.ZeroBytesException
        if not raw_image:
            raise cls.NoImageException
        image = Image(response_url, raw_image.size, raw_image.format)
        return image
Example #6
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
        # TODO: If this command hangs, the server never returns.
        # Surely that can't be right!
        with open(devnull, 'w') as fnull:
            opj_decompress_proc = subprocess.Popen(opj_cmd,
                                                   shell=True,
                                                   bufsize=-1,
                                                   stderr=fnull,
                                                   stdout=fnull,
                                                   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

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

        try:
            if self.map_profile_to_srgb and image_request.info.color_profile_bytes:  # i.e. is not None
                emb_profile = BytesIO(image_request.info.color_profile_bytes)
                im = self._map_im_profile_to_srgb(im, emb_profile)
        except PyCMSError as err:
            logger.warn('Error converting %r to sRGB: %r', im, err)

        self._derive_with_pil(im, target_fp, image_request, crop=False)
Example #7
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)
Example #8
0
	def transform(self, src_fp, target_fp, image_request):
		self._check_format(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'
		i = '-i %s' % (src_fp,)
		o = '-o %s' % (fifo_fp,)
		region_arg = self._region_to_kdu(image_request.region_param)

		# 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 = self._rotation_to_kdu(image_request.rotation_param)
			kdu_cmd = ' '.join((self.kdu_expand,q,i,region_arg,kdu_rotation_arg,o))
		else:
			rotate_downstream = True
			kdu_cmd = ' '.join((self.kdu_expand,q,i,region_arg,o))


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

		# Start the kdu shellout. Blocks until the pipe is emptied
		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
		# itertools.takewhile() ?
		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)

		JP2_Transformer._derive_with_pil(im, target_fp, image_request, rotate=rotate_downstream)
Example #9
0
    def _init_fs(self, fs):
        kwargs = super(UploadImage, self)._init_fs(fs)

        parser = ImageParser()
        for chunk in read_chunks(fs.file):
            parser.feed(chunk)
        self.image = parser.close()

        return kwargs
Example #10
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)
Example #11
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 __init__(self, **kw):
     object.__init__(self)
     [self.__setattr__(k, kw[k]) for k in page.keys]
     quietFns = {False: (self._prnfn, self._nlfn), True: (nopfn, nopfn)}
     self.prnfn, self.nlfn = quietFns[self.quiet]
     if self.contents:
         parser = Parser()
         parser.feed(kw["infile"])
         self.orig = parser.close()
     else:
         self.orig = Image.open(self.infile)
     self.img = self._prepare()
     self.frames = self._getFrames()
Example #13
0
def mk_tile_subproc():
    opj_bin = '/usr/local/bin/opj_decompress'
    opj_lib = '/usr/local/lib/libopenjp2.so'
    pipe_o = '/tmp/mypipe.bmp'
    out_jpg = '/tmp/test.jpg'
    mkfifo_cmd = '/usr/bin/mkfifo %s' % (pipe_o, )
    rmfifo_cmd = '/bin/rm %s' % (pipe_o, )
    i = '../tests/img/01/02/0001.jp2'
    r = 2  # reduce
    # d = '256,256,512,512'
    d = '0,0,256,256'

    opj_cmd = '%s -i %s -o %s -d %s -r %s' % (opj_bin, i, pipe_o, d, r)

    # make a named pipe
    mkfifo_resp = subprocess.check_call(mkfifo_cmd, shell=True)
    if mkfifo_resp != 0:
        sys.stderr.write('mkfifo not OK\n')

    # write opj_decompress's output to the named pipe
    opj_proc = subprocess.Popen(opj_cmd,
                                shell=True,
                                bufsize=-1,
                                stderr=subprocess.PIPE,
                                stdout=subprocess.PIPE,
                                env={'LD_LIBRARY_PATH': opj_lib})

    # open the named pipe and parse the stream
    im = None
    with open(pipe_o, 'rb') as f:
        p = Parser()
        while True:
            s = f.read(1024)
            if not s:
                break
            p.feed(s)
        im = p.close()

    # finish opj
    opj_exit = opj_proc.wait()
    if opj_exit != 0:
        map(sys.stderr.write, opj_proc.stderr)
    else:
        # opj was successful, save to a jpg
        # map(sys.stdout.write, opj_proc.stdout)
        im.save(out_jpg, quality=95)

    # remove the named pipe
    rmfifo_resp = subprocess.check_call(rmfifo_cmd, shell=True)
    if rmfifo_resp != 0:
        sys.stderr.write('rm fifo not OK\n')
Example #14
0
def generate_exemplar(grammar, **kwargs):
    """
    Using CFDG, creates an exemplar from the provided grammar,
    retrieves the image data, and returns the image data

    Available kwargs:
    'maxshapes': maximum number of shapes
    'width': width, in pixels, of image
    'height': height, in pixels, of image

    :return: Exemplar instance
    """
    commandstr = "cfdg"

    # process keyword arguments
    if 'maxshapes' in kwargs:
        commandstr += " -m {0}".format(kwargs['maxshapes'])
    else:
        commandstr += " -m {0}".format(MAX_SHAPES)

    if 'width' in kwargs:
        commandstr += " -w {0}".format(kwargs['width'])
    if 'height' in kwargs:
        commandstr += " -h {0}".format(kwargs['height'])

    # specify to cfdg that grammar file will come from stdin
    commandstr += " -"

    # run cfdg, passing in grammar.body as the input
    try:
        cfdg_proccess = proc.Popen(commandstr, shell=True,
                                   stdin=proc.PIPE, stdout=proc.PIPE)
        comm = cfdg_proccess.communicate(input=clean_body(grammar))
        cfdg_output = comm[0]
        if cfdg_output == '':
            raise Exception("CFDG output is empty.")
    except Exception as e:
        print("Error using CFDG to parse grammar '{0}'".format(grammar.name))
        raise e

    # parse output of cfdg into an image file, ready to save
    try:
        p = Parser()
        p.feed(cfdg_output)
        image = p.close()
    except IOError as e:
        print("Error parsing CFDG output for grammar '{0}' into an image file".format(grammar.name))
        raise e

    ex = Exemplar(image=image)
    return ex
Example #15
0
def size_filter(image_url):
    try:
        file = urlopen(image_url)
    except HTTPError:
        return None
    data = file.read(1024)
    file.close()
    parser = ImageParser()
    parser.feed(data)
    if parser.image:
        if parser.image.size[0] > MIN_LINK_THUMB_WIDTH and \
            parser.image.size[1] > MIN_LINK_THUMB_HEIGHT:
            print image_url, parser.image.size
            return image_url
Example #16
0
def mk_tile_subproc():
	opj_bin = '/usr/local/bin/opj_decompress'
	opj_lib = '/usr/local/lib/libopenjp2.so'
	pipe_o = '/tmp/mypipe.bmp'
	out_jpg = '/tmp/test.jpg'
	mkfifo_cmd = '/usr/bin/mkfifo %s' % (pipe_o,)
	rmfifo_cmd = '/bin/rm %s' % (pipe_o,)
	i = '../tests/img/01/02/0001.jp2'
	r = 2 # reduce
	# d = '256,256,512,512'
	d = '0,0,256,256'

	opj_cmd = '%s -i %s -o %s -d %s -r %s' % (opj_bin, i, pipe_o, d, r)

	# make a named pipe
	mkfifo_resp = subprocess.check_call(mkfifo_cmd, shell=True)
	if mkfifo_resp != 0:
	    sys.stderr.write('mkfifo not OK\n')

	# write opj_decompress's output to the named pipe 
	opj_proc = subprocess.Popen(opj_cmd, shell=True, 
	    bufsize=-1, stderr=subprocess.PIPE, stdout=subprocess.PIPE,
	    env={ 'LD_LIBRARY_PATH' : opj_lib })

	# open the named pipe and parse the stream
	im = None
	with open(pipe_o, 'rb') as f:
	    p = Parser()
	    while True:
	        s = f.read(1024)
	        if not s:
	            break
	        p.feed(s)
	    im = p.close()

	# finish opj
	opj_exit = opj_proc.wait()
	if opj_exit != 0:
	    map(sys.stderr.write, opj_proc.stderr)
	else:
	    # opj was successful, save to a jpg
	    # map(sys.stdout.write, opj_proc.stdout)
	    im.save(out_jpg, quality=95)

	# remove the named pipe
	rmfifo_resp = subprocess.check_call(rmfifo_cmd, shell=True)
	if rmfifo_resp != 0:
	    sys.stderr.write('rm fifo not OK\n')
Example #17
0
    def test_allows_jp2_upsample(self):
        # Makes a request rather than building everything from scratch
        ident = self.test_jp2_color_id
        request_path = '/%s/full/pct:110/0/default.jpg' % (ident,)
        resp = self.client.get(request_path)

        self.assertEqual(resp.status_code, 200)

        image = None
        bytes = StringIO(resp.data)
        p = Parser()
        p.feed(bytes.read()) # all in one gulp!
        image = p.close()
        bytes.close()
        expected_dims = tuple(int(d*1.10) for d in self.test_jp2_color_dims)

        self.assertEqual(expected_dims, image.size)
Example #18
0
    def test_allows_jp2_upsample(self):
        # Makes a request rather than building everything from scratch
        ident = self.test_jp2_color_id
        request_path = '/%s/full/pct:110/0/default.jpg' % (ident, )
        resp = self.client.get(request_path)

        self.assertEqual(resp.status_code, 200)

        image = None
        bytes = StringIO(resp.data)
        p = Parser()
        p.feed(bytes.read())  # all in one gulp!
        image = p.close()
        bytes.close()
        expected_dims = tuple(int(d * 1.10) for d in self.test_jp2_color_dims)

        self.assertEqual(expected_dims, image.size)
Example #19
0
  def import_image(cls, file_path):
    image_parser = Parser()

    f = open(file_path, 'rb')
    while True:
      buf = f.read(8192)
      if buf:
        image_parser.feed(buf)
        continue
      break
    image_parser.close()
    im_hash = cls.hash_image(f)
    if cls.objects.filter(hash = im_hash).exists():
      print "Skipping duplicate (%s)"%im_hash
    else:
      cls.objects.create(
        image = File(f),
        hash = im_hash,
        )
Example #20
0
    def import_image(cls, file_path):
        image_parser = Parser()

        f = open(file_path, 'rb')
        while True:
            buf = f.read(8192)
            if buf:
                image_parser.feed(buf)
                continue
            break
        image_parser.close()
        im_hash = cls.hash_image(f)
        if cls.objects.filter(hash=im_hash).exists():
            print "Skipping duplicate (%s)" % im_hash
        else:
            cls.objects.create(
                image=File(f),
                hash=im_hash,
            )
class InterceptingProxyClient(ProxyClient):
    def __init__(self, *args, **kwargs):
        ProxyClient.__init__(self, *args, **kwargs)
        self.image_parser = None

    def handleHeader(self, key, value):
        if key == "Content-Type" and value in ["image/jpeg", "image/gif", "image/png"]:
            self.image_parser = Parser()
        if key == "Content-Length" and self.image_parser:
            pass
        else:
            ProxyClient.handleHeader(self, key, value)

    def handleEndHeaders(self):
        if self.image_parser:
            pass #Need to calculate and send Content-Length first
        else:
            ProxyClient.handleEndHeaders(self)

    def handleResponsePart(self, buffer):
        if self.image_parser:
            self.image_parser.feed(buffer)
        else:
            ProxyClient.handleResponsePart(self, buffer)

    def handleResponseEnd(self):
        if self.image_parser:
            image = self.image_parser.close()
            try:
                format = image.format
                image = image.rotate(180)
                s = StringIO()
                image.save(s, format)
                buffer = s.getvalue()
            except:
                buffer = ""
            ProxyClient.handleHeader(self, "Content-Length", len(buffer))
            ProxyClient.handleEndHeaders(self)
            ProxyClient.handleResponsePart(self, buffer)
        ProxyClient.handleResponseEnd(self)
Example #22
0
 def __init__(self, **kw):
     """A page object.
     Valid keyword parameters:
     startRow (default:0):
         Which row to start analyzing from. This is typically used for analyzing the first
         page of a comic where some top part of the page contains the title (which we need
         to skip)
     lignore, rignore (default:0 for both):
         Scanned pages might have some non-white color on one or both of the edges which
         interfere with gutter detection. These paramters tell the gutter detection
         algorithm to adjust the left boundary by lignore and right boundary by
         rignore when locating gutters
     contents (default: True):
         True => "infile" is a string consisting of page contents
         False => "infile" is a string holding the name of the page file to open
     infile:
         A String holding page contents or the page file name (depending on the contents
         parameter)
     pgNum (default:1):
         Page number (used when processing a whole book)
     quiet:
         Don't print any status messages
     debug:
         Enable debug prints
     fwidth, fheight:
         Minimum width (height resp) of a frame"""
     object.__init__(self)
     [self.__setattr__(k, kw[k]) for k in page.keys]
     quietFns = {False: (self._prnfn, self._nlfn), True: (nopfn, nopfn)}
     self.prnfn, self.nlfn = quietFns[self.quiet]
     if self.contents:
         parser = Parser()
         parser.feed(kw["infile"])
         self.orig = parser.close()
     else:
         self.orig = Image.open(self.infile)
     self.img = self._prepare()
     self.frames = self._getFrames()
Example #23
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)
Example #24
0
# write kdu_expand's output to the named pipe
kdu_expand_proc = subprocess.Popen(kdu_cmd,
                                   shell=True,
                                   bufsize=-1,
                                   stderr=subprocess.PIPE,
                                   stdout=subprocess.PIPE,
                                   env={'LD_LIBRARY_PATH': LIB_KDU})

# open the named pipe and parse the stream
with open(pipe_fp, 'rb') as f:
    p = Parser()
    while True:
        s = f.read(1024)
        if not s:
            break
        p.feed(s)
    im = p.close()

# finish kdu
kdu_exit = kdu_expand_proc.wait()
if kdu_exit != 0:
    map(sys.stderr.write, kdu_expand_proc.stderr)
else:
    # if kdu was successful, save to a jpg
    map(sys.stdout.write, kdu_expand_proc.stdout)
    im = im.resize((719, 900), resample=Image.ANTIALIAS)
    im.save(OUT_JPG, quality=95)

# remove the named pipe
rmfifo_resp = subprocess.check_call(rmfifo_cmd, shell=True)
if rmfifo_resp == 0:
Example #25
0
def get_reduced_image_from_kdu(jp2, size):
    # This is basically like an IIIF op /full/!size,size/0/default.jpg
    # uses kdu via fifo as per Loris
    # returns PIL image object
    print 'making new pillow image for derivs at size', size
    im = None
    # extract the smallest possible resolution as the starting point for our transform ops
    req_w, req_h = confine(jp2.width, jp2.height, size, size)

    # mostly taken from transforms.py in Loris, but we want to return a Pillow image
    # color profile stuff has been removed for now

    n = ''.join(random.choice(string.ascii_uppercase + string.digits) for _ in range(6))
    fifo_fp = os.path.join(TMP_DIR, n + '.bmp')

    # kdu command
    q = '' # '-quiet'
    t = '-num_threads 4'
    i = '-i "%s"' % (jp2.path,)
    o = '-o %s' % (fifo_fp,)
    reduce_arg = scales_to_reduce_arg(jp2, size)
    red = '-reduce %s' % (reduce_arg,) if reduce_arg else ''

    # kdu_expand -usage:
    # -reduce <discard levels>
    #    Set the number of highest resolution levels to be discarded.  The image
    #    resolution is effectively divided by 2 to the power of the number of
    #    discarded levels.


    kdu_cmd = ' '.join((KDU_EXPAND,q,i,t,red,o))

    # make the named pipe
    mkfifo_call = '%s %s' % (MKFIFO, fifo_fp)
    print 'Calling %s' % (mkfifo_call,)
    resp = subprocess.check_call(mkfifo_call, shell=True)

    expand_env = {
        'LD_LIBRARY_PATH': KDU_LIB,
        'PATH': KDU_EXPAND
    }

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

        f = open(fifo_fp, 'rb')
        print 'Opened %s' % fifo_fp

        # read from the named pipe into PIL
        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:
            print 'KDU ERROR'
            for e in kdu_expand_proc.stderr:
                print e

        imw, imh = im.size
        print 'we now have a PIL image %s x %s' % (imw, imh)
        if imw != req_w or imh != req_h:
            im = im.resize((req_w, req_h), resample=Image.ANTIALIAS)

    except:
        raise
    finally:
        kdu_exit = kdu_expand_proc.wait()
        if kdu_exit != 0:
            map(logger.error, map(string.strip, kdu_expand_proc.stderr))
        os.unlink(fifo_fp)

    return im
Example #26
0
if mkfifo_resp == 0:
    print 'mkfifo OK'

# write kdu_expand's output to the named pipe 
kdu_expand_proc = subprocess.Popen(kdu_cmd, shell=True, 
    bufsize=-1, stderr=subprocess.PIPE, stdout=subprocess.PIPE,
    env={ 'LD_LIBRARY_PATH' : LIB_KDU })

# open the named pipe and parse the stream
with open(pipe_fp, 'rb') as f:
    p = Parser()
    while True:
        s = f.read(1024)
        if not s:
            break
        p.feed(s)
    im = p.close()

# finish kdu
kdu_exit = kdu_expand_proc.wait()
if kdu_exit != 0:
    map(sys.stderr.write, kdu_expand_proc.stderr)
else:
    # if kdu was successful, save to a jpg
    map(sys.stdout.write, kdu_expand_proc.stdout)
    im = im.resize((719,900), resample=Image.ANTIALIAS)
    im.save(OUT_JPG, quality=95)

# remove the named pipe
rmfifo_resp = subprocess.check_call(rmfifo_cmd, shell=True)
if rmfifo_resp == 0:
Example #27
0
def get_reduced_image_from_kdu(jp2, size):
    # This is basically like an IIIF op /full/!size,size/0/default.jpg
    # uses kdu via fifo as per Loris
    # returns PIL image object
    print 'making new pillow image for derivs at size', size
    im = None
    # extract the smallest possible resolution as the starting point for our transform ops
    req_w, req_h = confine(jp2.width, jp2.height, size, size)

    # mostly taken from transforms.py in Loris, but we want to return a Pillow image
    # color profile stuff has been removed for now

    n = ''.join(random.choice(string.ascii_uppercase + string.digits) for _ in range(6))
    fifo_fp = os.path.join(TMP_DIR, n + '.bmp')

    # kdu command
    q = ''  # '-quiet'
    t = '-num_threads 4'
    i = '-i "%s"' % (jp2.path,)
    o = '-o %s' % (fifo_fp,)
    reduce_arg = scales_to_reduce_arg(jp2, size)
    red = '-reduce %s' % (reduce_arg,) if reduce_arg else ''

    # kdu_expand -usage:
    # -reduce <discard levels>
    #    Set the number of highest resolution levels to be discarded.  The image
    #    resolution is effectively divided by 2 to the power of the number of
    #    discarded levels.

    kdu_cmd = ' '.join((KDU_EXPAND, q, i, t, red, o))

    # make the named pipe
    mkfifo_call = '%s %s' % (MKFIFO, fifo_fp)
    print 'Calling %s' % (mkfifo_call,)
    resp = subprocess.check_call(mkfifo_call, shell=True)

    expand_env = {
        'LD_LIBRARY_PATH': KDU_LIB,
        'PATH': KDU_EXPAND
    }

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

        f = open(fifo_fp, 'rb')
        print 'Opened %s' % fifo_fp

        # read from the named pipe into PIL
        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:
            print 'KDU ERROR'
            for e in kdu_expand_proc.stderr:
                print e

        if im.mode != "RGB":
            im = im.convert("RGB")

        imw, imh = im.size
        print 'we now have a PIL image %s x %s' % (imw, imh)
        if imw != req_w or imh != req_h:
            im = im.resize((req_w, req_h), resample=Image.ANTIALIAS)

    except:
        raise
    finally:
        kdu_exit = kdu_expand_proc.wait()
        if kdu_exit != 0:
            # TODO : add logging!
            # map(logger.error, map(string.strip, kdu_expand_proc.stderr))
            pass
        os.unlink(fifo_fp)

    return im