Example #1
0
def image_tint(path: str, tint: str) -> Image:
    src = Image.open(path)
    if src.mode not in ("RGB", "RGBA"):
        raise TypeError(f"Unsupported source image mode: {src.mode}")
    src.load()

    tr, tg, tb = getrgb(tint)
    tl = getcolor(tint, "L")  # tint color's overall luminosity
    if not tl:
        tl = 1  # avoid division by zero
    tl = float(tl)  # compute luminosity preserving tint factors
    sr, sg, sb = map(lambda tv: tv / tl, (tr, tg, tb))  # per component
    # adjustments
    # create look-up tables to map luminosity to adjusted tint
    # (using floating-point math only to compute table)
    luts = (tuple(map(lambda lr: int(lr * sr + 0.5), range(256))) +
            tuple(map(lambda lg: int(lg * sg + 0.5), range(256))) +
            tuple(map(lambda lb: int(lb * sb + 0.5), range(256))))
    l = grayscale(src)  # 8-bit luminosity version of whole image
    if Image.getmodebands(src.mode) < 4:
        merge_args: tuple = (src.mode, (l, l, l)
                             )  # for RGB verion of grayscale
    else:  # include copy of src image's alpha layer
        a = Image.new("L", src.size)
        a.putdata(src.getdata(3))
        merge_args = (src.mode, (l, l, l, a))  # for RGBA verion of grayscale
        luts += tuple(range(256))  # for 1:1 mapping of copied alpha values

    image = Image.merge(*merge_args).point(luts)
    new_image = Image.new("RGBA", image.size,
                          "WHITE")  # Create a white rgba background
    new_image.paste(image, (0, 0), image)
    return new_image
Example #2
0
def image_tint(image, tint=None):
	if tint is None:
		return image
	if image.mode not in ['RGB', 'RGBA']:
		image = image.convert('RGBA')

	tr, tg, tb = ImageColor.getrgb(tint)
	tl = ImageColor.getcolor(tint, "L")  # tint color's overall luminosity
	if not tl:
		tl = 1  # avoid division by zero
	tl = float(tl)  # compute luminosity preserving tint factors
	sr, sg, sb = map(lambda tv: tv / tl, (tr, tg, tb)
						)  # per component adjustments

	# create look-up tables to map luminosity to adjusted tint
	# (using floating-point math only to compute table)
	luts = (tuple(map(lambda lr: int(lr * sr + 0.5), range(256))) +
			tuple(map(lambda lg: int(lg * sg + 0.5), range(256))) +
			tuple(map(lambda lb: int(lb * sb + 0.5), range(256))))
	l = ImageOps.grayscale(image)  # 8-bit luminosity version of whole image
	if Image.getmodebands(image.mode) < 4:
		merge_args = (image.mode, (l, l, l))  # for RGB verion of grayscale
	else:  # include copy of image's alpha layer
		a = Image.new("L", image.size)
		a.putdata(image.getdata(3))
		merge_args = (image.mode, (l, l, l, a))  # for RGBA verion of grayscale
		luts += tuple(range(256))  # for 1:1 mapping of copied alpha values

	return Image.merge(*merge_args).point(luts)
Example #3
0
def image_tint(src, tint=None):
    r = lambda: random.randint(0,255)
    tint = tint or '#{:02X}{:02X}{:02X}'.format(r(), r(), r())
    if Image.isStringType(src):  # file path?
        src = Image.open(src)
    if src.mode not in ['RGB', 'RGBA']:
        raise TypeError('Unsupported source image mode: {}'.format(src.mode))
    src.load()

    tr, tg, tb = ImageColor.getrgb(tint)
    tl = ImageColor.getcolor(tint, "L")  # tint color's overall luminosity
    if not tl: tl = 1  # avoid division by zero
    tl = float(tl)  # compute luminosity preserving tint factors
    sr, sg, sb = map(lambda tv: tv/tl, (tr, tg, tb))  # per component adjustments

    # create look-up tables to map luminosity to adjusted tint
    # (using floating-point math only to compute table)
    luts = (map(lambda lr: int(lr*sr + 0.5), range(256)) +
            map(lambda lg: int(lg*sg + 0.5), range(256)) +
            map(lambda lb: int(lb*sb + 0.5), range(256)))
    l = ImageOps.grayscale(src)  # 8-bit luminosity version of whole image
    if Image.getmodebands(src.mode) < 4:
        merge_args = (src.mode, (l, l, l))  # for RGB verion of grayscale
    else:  # include copy of src image's alpha layer
        a = Image.new("L", src.size)
        a.putdata(src.getdata(3))
        merge_args = (src.mode, (l, l, l, a))  # for RGBA verion of grayscale
        luts += range(256)  # for 1:1 mapping of copied alpha values

    return (Image.merge(*merge_args).point(luts), tint)
Example #4
0
def image_tint(image, tint=None):
    if tint is None:
        return image
    if image.mode not in ['RGB', 'RGBA']:
        image = image.convert('RGBA')

    tr, tg, tb = ImageColor.getrgb(tint)
    tl = ImageColor.getcolor(tint, "L")  # tint color's overall luminosity
    if not tl:
        tl = 1  # avoid division by zero
    tl = float(tl)  # compute luminosity preserving tint factors
    sr, sg, sb = map(lambda tv: tv / tl,
                     (tr, tg, tb))  # per component adjustments

    # create look-up tables to map luminosity to adjusted tint
    # (using floating-point math only to compute table)
    luts = (tuple(map(lambda lr: int(lr * sr + 0.5), range(256))) +
            tuple(map(lambda lg: int(lg * sg + 0.5), range(256))) +
            tuple(map(lambda lb: int(lb * sb + 0.5), range(256))))
    l = ImageOps.grayscale(image)  # 8-bit luminosity version of whole image
    if Image.getmodebands(image.mode) < 4:
        merge_args = (image.mode, (l, l, l))  # for RGB verion of grayscale
    else:  # include copy of image's alpha layer
        a = Image.new("L", image.size)
        a.putdata(image.getdata(3))
        merge_args = (image.mode, (l, l, l, a))  # for RGBA verion of grayscale
        luts += tuple(range(256))  # for 1:1 mapping of copied alpha values

    return Image.merge(*merge_args).point(luts)
Example #5
0
def _is_multichannel(mode: str) -> bool:
    """Returns true if the color mode uses more than one channel.

    We need an easy way to test for this to, for example, figure out which
    dimension to rotate when we encounter an exif rotation flag. I didn't find a
    good way to do this using pillow, so instead we have a local list of all
    (currently) supported modes.

    If somebody comes across a better way to do this, in particular if it
    automatically grabs available modes from pillow a PR is very welcome :)

    Parameters
    ----------
    mode : str
        A valid pillow mode string

    Returns
    -------
    is_multichannel : bool
        True if the image uses more than one channel to represent a color, False
        otherwise.

    """
    multichannel = {
        "BGR;15": True,
        "BGR;16": True,
        "BGR;24": True,
        "BGR;32": True,
    }

    if mode in multichannel:
        return multichannel[mode]

    return Image.getmodebands(mode) > 1
Example #6
0
def image_tint(im, tint='#ff0000'):

    src = Image.new('RGB', im.size)
    src.paste(im)

    tr, tg, tb = getrgb(tint)
    tl = getcolor(tint, "L")  # tint color's overall luminosity
    if not tl: tl = 1  # avoid division by zero
    tl = float(tl)  # compute luminosity preserving tint factors
    sr, sg, sb = map(lambda tv: tv / tl,
                     (tr, tg, tb))  # per component adjustments

    # create look-up tables to map luminosity to adjusted tint
    # (using floating-point math only to compute table)
    luts = (list(map(lambda lr: int(lr * sr + 0.5), range(256))) +
            list(map(lambda lg: int(lg * sg + 0.5), range(256))) +
            list(map(lambda lb: int(lb * sb + 0.5), range(256))))
    l = grayscale(src)  # 8-bit luminosity version of whole image
    if Image.getmodebands(src.mode) < 4:
        merge_args = (src.mode, (l, l, l))  # for RGB verion of grayscale
    else:  # include copy of src image's alpha layer
        a = Image.new("L", src.size)
        a.putdata(src.getdata(3))
        merge_args = (src.mode, (l, l, l, a))  # for RGBA verion of grayscale
        luts += range(256)  # for 1:1 mapping of copied alpha values

    return Image.merge(*merge_args).point(luts)
Example #7
0
def image_tint(src, tint='#fffab5'):
    if Image.isStringType(src):  # file path?
        src = Image.open(src)
    if src.mode not in ['RGB', 'RGBA']:
        raise TypeError('Unsupported source image mode: {}'.format(src.mode))
    src.load()

    tr, tg, tb = getrgb(tint)
    tl = getcolor(tint, "L")  # tint color's overall luminosity
    if not tl: tl = 1  # avoid division by zero
    tl = float(tl)  # compute luminosity preserving tint factors
    sr, sg, sb = map(lambda tv: tv/tl, (tr, tg, tb))  # per component
                                                      # adjustments
    # create look-up tables to map luminosity to adjusted tint
    # (using floating-point math only to compute table)
    luts = (tuple(map(lambda lr: int(lr*sr + 0.5), range(256))) +
            tuple(map(lambda lg: int(lg*sg + 0.5), range(256))) +
            tuple(map(lambda lb: int(lb*sb + 0.5), range(256))))
    l = grayscale(src)  # 8-bit luminosity version of whole image
    if Image.getmodebands(src.mode) < 4:
        merge_args = (src.mode, (l, l, l))  # for RGB verion of grayscale
    else:  # include copy of src image's alpha layer
        a = Image.new("L", src.size)
        a.putdata(src.getdata(3))
        merge_args = (src.mode, (l, l, l, a))  # for RGBA verion of grayscale
        luts += tuple(range(256))  # for 1:1 mapping of copied alpha values
    return Image.merge(*merge_args).point(luts)
Example #8
0
def image_tint(src,
               tint="#ffffff"):  # From https://stackoverflow.com/a/12310820
    if src.mode not in ["RGB", "RGBA"]:
        raise TypeError("Unsupported source image mode: {}".format(src.mode))
    src.load()

    tr, tg, tb = getrgb(tint)
    tl = getcolor(tint, "L")
    if not tl:
        tl = 1
    tl = float(tl)
    sr, sg, sb = map(lambda tv: tv / tl, (tr, tg, tb))
    luts = (tuple(map(lambda lr: int(lr * sr + 0.5), range(256))) +
            tuple(map(lambda lg: int(lg * sg + 0.5), range(256))) +
            tuple(map(lambda lb: int(lb * sb + 0.5), range(256))))
    l = grayscale(src)
    if Image.getmodebands(src.mode) < 4:
        merge_args = (src.mode, (l, l, l))
    else:
        a = Image.new("L", src.size)
        a.putdata(src.getdata(3))

        luts += tuple(range(256))

    return Image.merge(*merge_args).point(luts)
Example #9
0
    def image_tint(self, source_path, tint='#ffffff'):
        '''
        Take an image from a path and convert it to a tinted string for sprite coloration.
        :param source_path: sting path to image
        :param tint: string color code in hex
        :return: string of modified image
        '''

        img_source = Image.open(source_path)                # Get the image from specified path
        tint_red, tint_green, tint_blue = getrgb(tint)      # Get color tint of each color
        tint_lum = getcolor(tint, "L")                      # Tint color luminosity

        if tint_lum == 0:   # Avoid division by 0
            tint_lum = 1

        tint_lum = float(tint_lum)  # Compute luminosity preserving tint factors
        sr, sg, sb = map(lambda tv: tv / tint_lum, (tint_red, tint_green, tint_blue))  # per component adjustments

        # create look-up tables to map luminosity to adjusted tint
        # (using floating-point math only to compute table)
        luts = (list(map(lambda lr: int(lr * sr + 0.5), range(256))) +
                list(map(lambda lg: int(lg * sg + 0.5), range(256))) +
                list(map(lambda lb: int(lb * sb + 0.5), range(256))))

        l = grayscale(img_source)  # 8-bit luminosity version of whole image

        if Image.getmodebands(img_source.mode) < 4:
            merge_args = (img_source.mode, (l, l, l))  # for RGB verion of grayscale
        else:  # include copy of img_source image's alpha layer
            a = Image.new("L", img_source.size)
            a.putdata(img_source.getdata(3))
            merge_args = (img_source.mode, (l, l, l, a))  # for RGBA verion of grayscale
            luts += range(256)  # for 1:1 mapping of copied alpha values

        return Image.merge(*merge_args).point(luts)     # Return string of image
Example #10
0
 def check(mode, *result):
     signature = (
         Image.getmodebase(mode),
         Image.getmodetype(mode),
         Image.getmodebands(mode),
         Image.getmodebandnames(mode),
     )
     assert signature == result
Example #11
0
 def check(mode, *result):
     signature = (
         Image.getmodebase(mode),
         Image.getmodetype(mode),
         Image.getmodebands(mode),
         Image.getmodebandnames(mode),
     )
     self.assertEqual(signature, result)
Example #12
0
def averageColorUnlessIsBackground(img, key_color, key_thres, key_ratio):
  count = 0
  avgc = MapFold(Averager, Image.getmodebands(img.mode))
  for px in imagePixels(img):
    avgc.accept(px)
    distances = map(lambda ab: abs(ab[0] - ab[1]), zip(px, key_color))
    if sum(distances) < key_thres: count += 1
  return map(int, avgc.finish()) if count < key_ratio*(img.width*img.height) else None
Example #13
0
 def check(mode, *result):
     signature = (
         Image.getmodebase(mode),
         Image.getmodetype(mode),
         Image.getmodebands(mode),
         Image.getmodebandnames(mode),
     )
     self.assertEqual(signature, result)
Example #14
0
def averageColor(img, key_color, thres):
    def dist(a, b):
        return abs(a - b)  #< color distance

    averager = MapFold(Averager, Image.getmodebands(img.mode))
    n_inthres = 0
    for pix in imagePixels(img):
        averager.accept(pix)
        dists = map(lambda ab: dist(ab[0], ab[1]), zip(key_color, pix))
        if sum(dists) < thres: n_inthres += 1
    return (averager.finish(), n_inthres)
def averageColor(img, keyc) -> Tuple[tuple, int]:
  def dist(a, b): return abs(a - b) #< color distance
  averager = MapFold(Averager, Image.getmodebands(img.mode))
  n_thres = 0
  for y in range(0, img.height):
    for x in range(0, img.width):
      rgb = img.getpixel((x, y))
      averager.accept(rgb)
      dists = map(lambda ab: dist(ab[0], ab[1]), zip(keyc.color, rgb) )
      if sum(dists) > keyc.thres: n_thres += 1
  return (averager.finish(), n_thres)
Example #16
0
    def image_tint(image, tint='#ffffff'):
        """
        Function to merge two images without alpha

        Parameters:
        image (str): Path to the image
        tint (str): Hex code for the tint

        Returns:
        Image object for further use
        """
        image = image.convert('RGBA')
        image.load()

        tr, tg, tb = getrgb(tint)
        tl = getcolor(tint, "L")  # tint color's overall luminosity
        tl = 1 if not tl else tl  # avoid division by zero
        tl = float(tl)  # compute luminosity preserving tint factors
        sr, sg, sb = map(lambda tv: tv / tl, (tr, tg, tb))  # per component
        # adjustments
        # create look-up tables to map luminosity to adjusted tint
        # (using floating-point math only to compute table)
        luts = (tuple(map(lambda lr: int(lr * sr + 0.5), range(256))) +
                tuple(map(lambda lg: int(lg * sg + 0.5), range(256))) +
                tuple(map(lambda lb: int(lb * sb + 0.5), range(256))))
        lum = grayscale(image)  # 8-bit luminosity version of whole image
        if Image.getmodebands(image.mode) < 4:
            merge_args = (image.mode, (lum, lum, lum)
                          )  # for RGB verion of grayscale
        else:  # include copy of image image's alpha layer
            a = Image.new("L", image.size)
            a.putdata(image.getdata(3))
            merge_args = (image.mode, (lum, lum, lum, a)
                          )  # for RGBA verion of grayscale
            luts += tuple(range(256))  # for 1:1 mapping of copied alpha values

        return Image.merge(*merge_args).point(luts)
Example #17
0
 def color(mode):
     bands = Image.getmodebands(mode)
     if bands == 1:
         return 1
     else:
         return tuple(range(1, bands + 1))
Example #18
0
 def color(mode):
     bands = Image.getmodebands(mode)
     if bands == 1:
         return 1
     else:
         return tuple(range(1, bands + 1))
def channelHistogram(img) -> Tuple:
    n_channels = Pillow.getmodebands(img.mode)
    hist = img.histogram()
    return tuple(hist[i:i + 256] for i in range(0, n_channels * 256, 256))
Example #20
0
def ingest_data(self, uploadSession_id, imageDir):
  ''' task for the ingest route, to ingest the data an upload sessions points to '''
  import voxel_globe.ingest.models as IngestModels
  import numpy
  from voxel_globe.tools.camera import save_krt

  uploadSession = IngestModels.UploadSession.objects.get(id=uploadSession_id);
  #directories = uploadSession.directory.all();
  #imageDirectory = directories.filter(name='image')
  #metaDirectory = directories.filter(name='meta')

  imageCollection = voxel_globe.meta.models.ImageCollection.create(name="Generic Upload %s (%s)" % (uploadSession.name, uploadSession_id), service_id = self.request.id);
  imageCollection.save();

  r = numpy.eye(3);
  t = [0, 0, 0];

  gpsList = []
  gpsList2 = []

  for d in glob(os.path.join(imageDir, '*'+os.path.sep), False):
    files = glob(os.path.join(d, '*'), False);
    files.sort()
    for f in files:
      self.update_state(state='PROCESSING', 
                        meta={'stage':'File %s of %d' % (f, len(files))})
      zoomifyName = f[:-4] + '_zoomify'
      pid = Popen(['vips', 'dzsave', f, zoomifyName, '--layout', 'zoomify'])
      pid.wait();

      #convert the slashes to URL slashes 
      relFilePath = urllib.pathname2url(os.path.relpath(f, env['VIP_IMAGE_SERVER_ROOT']));
      basename = os.path.split(f)[-1]
      relZoomPath = urllib.pathname2url(os.path.relpath(zoomifyName, env['VIP_IMAGE_SERVER_ROOT']));

      with open(f, 'rb') as fid:
        magic = fid.read(4)
        
      image_info = {}
      if magic == '49492A00'.decode('hex') or \
         magic == '4D4D002A'.decode('hex'):
        logger.debug('Tifffile: %s', f)
        from tifffile import TiffFile

        with TiffFile(f) as image:
          if image.pages[0].dtype == 's':
            image_info['dtype'] = numpy.dtype('S')
          else:
            image_info['dtype'] = numpy.dtype(image.pages[0].dtype)
          image_info['bps'] = image.pages[0].bits_per_sample
          image_info['height'] = image.pages[0].shape[0] #Yep, y,x,z order
          image_info['width'] = image.pages[0].shape[1]
          try:
            image_info['bands'] = image.pages[0].shape[2]
          except IndexError:
            image_info['bands'] = 1
      else:
        logger.debug('Pil: %s', f)
        from PIL import Image
        
        with Image.open(f) as image:
          #The getmode* commands do not give you the REAL datatypes. I need the
          #REAL (numpy in this case) bps, not some random PIL designation
          image_info['dtype'] = numpy.dtype(Image._MODE_CONV[image.mode][0])
          #probably doesn't work well for bool... Oh well
          image_info['bps'] = image_info['dtype'].itemsize*8
          image_info['width'] = image.size[0] #Yep, x,y order
          image_info['height'] = image.size[1]
          image_info['bands'] = Image.getmodebands(image.mode)

      img = voxel_globe.meta.models.Image.create(
                             name="Generic Upload %s (%s) Frame %s" % (uploadSession.name, uploadSession_id, basename), 
                             imageWidth=image_info['width'], 
                             imageHeight=image_info['height'], 
                             numberColorBands=image_info['bands'],
                             pixelFormat=image_info['dtype'].char,
                             fileFormat='zoom',
                             imageUrl='%s://%s:%s/%s/%s/' % (env['VIP_IMAGE_SERVER_PROTOCOL'], 
                                                             env['VIP_IMAGE_SERVER_HOST'], 
                                                             env['VIP_IMAGE_SERVER_PORT'], 
                                                             env['VIP_IMAGE_SERVER_URL_PATH'], 
                                                             relZoomPath),
                             originalImageUrl='%s://%s:%s/%s/%s' % (env['VIP_IMAGE_SERVER_PROTOCOL'], 
                                                                    env['VIP_IMAGE_SERVER_HOST'], 
                                                                    env['VIP_IMAGE_SERVER_PORT'], 
                                                                    env['VIP_IMAGE_SERVER_URL_PATH'], 
                                                                    relFilePath),
                             service_id = self.request.id);
      img.save();

      imageCollection.images.add(img);
      
      origin = [0,0,0];
      logger.debug('Origin is: %s' % origin)

      k = numpy.eye(3);
      k[0,2] = image_info['width']/2;
      k[1,2] = image_info['height']/2;      
      save_krt(self.request.id, img, k, r, t, origin);

  voxel_globe.meta.models.Scene.create(name="Generic origin %s (%s)" % (uploadSession.name, uploadSession_id), 
                                       service_id = self.request.id,
                                       geolocated=False,
                                       origin='POINT(%0.12f %0.12f %0.12f)' % \
                                       (0,0,0)).save()
  uploadSession.delete()