예제 #1
0
	def process(self, image):
		red = 1.0  # (0.1 - 1.0)
		green = 0.5  # (0.1 - 0.5)
		red_r = red
		red_g = (1. - red) / 2.
		red_b = (1. - red) / 2.
		cyan_r = 0
		cyan_g = green
		cyan_b = 1. - green
		yield 'Red layer', image
		redlayer = image.copy()
		redlayer = colors.color_mixer_monochrome(redlayer, red_r, red_g, red_b)
		redlayer = ImageChops.invert(redlayer)
		redlayer = colors.apply_color(redlayer, (255, 0, 0))
		redlayer = ImageChops.invert(redlayer)
		yield 'Cyan layer', redlayer
		cyanlayer = image.copy()
		cyanlayer = colors.color_mixer_monochrome(cyanlayer, cyan_r, cyan_g, cyan_b)
		cyanlayer = ImageChops.invert(cyanlayer)
		cyanlayer = colors.apply_color(cyanlayer, (0, 255, 255))
		cyanlayer = ImageChops.invert(cyanlayer)
		yield 'Cyan + Red...', cyanlayer
		image = ImageChops.multiply(cyanlayer, redlayer)
		yield 'Yellow layer', image
		yellowlayer = image.copy()
		colors.fill_with_color(yellowlayer, (255, 255, 240))
		image = ImageChops.multiply(image, yellowlayer)
		yield 'Contrast...', image
		image = ImageEnhance.Contrast(image).enhance(1.1)
		yield 'Sharpness...', image
		image = ImageEnhance.Sharpness(image).enhance(1.1)
		yield 'Done', image
def Problem1ImageSolver():

	[dirImagesQuestions, dirImagesAnswers] = get_images_for_directory("Representations/Frames/Problem 1/")
	print "Problem 1 Image Questions: \n=================="
	compare_k = dirImagesQuestions.keys()[0]
	compare_v = dirImagesQuestions[compare_k]
	compare_v = ImageChops.invert(compare_v)
	compare_v = findRelevantBoxEdges(compare_v)
	# print compare_k
	for k,v in dirImagesQuestions.iteritems():
		temp_v = ImageChops.invert(dirImagesQuestions[k])
		temp_v = findRelevantBoxEdges(temp_v)
		image_equality = check_shape_equality(compare_v, temp_v)
		equality_string = ""
		if not image_equality:
			equality_string = "different"
		else:
			equality_string = "equal with " + image_equality[1] + " transformation"
		print str(k) + " and " + str(compare_k) + " are " + equality_string

	print "\nProblem 1 Image Answers: \n=================="
	for k,v in dirImagesAnswers.iteritems():
		temp_v = ImageChops.invert(dirImagesAnswers[k])
		temp_v = findRelevantBoxEdges(temp_v)
		# if compare_v.size != temp_v.size:
		# 	print str(compare_k) + " is " + str(compare_v.size) + " but " + str(k) + " is " + str(temp_v.size)
		image_equality = check_shape_equality(compare_v, temp_v)
		equality_string = ""
		if not image_equality:
			equality_string = "different"
		else:
			equality_string = "equal with " + image_equality[1] + " transformation"
		print str(k) + " and " + str(compare_k) + " are " + equality_string
예제 #3
0
def vignette(image, off=0.2, stop=0.7, center_w=0.5, center_h=0.5):
	width, height = image.size
	vlayer = create_circular_gradient(image.size, 1.3, center_w, center_h, False)
	curv = list(curves.create_curve([(0, 0), (96, 200), (255, 255)]))
	vlayer = curves.apply_curves(vlayer, curv)
	vlayer = vlayer.filter(ImageFilter.BLUR).convert("RGB")
	clouds = create_clouds_bw(vlayer.size, 3)
	clouds = ImageEnhance.Brightness(clouds).enhance(3)
	clouds = ImageEnhance.Contrast(clouds).enhance(0.9)
	clouds = ImageChops.multiply(clouds, ImageChops.invert(vlayer))
	return ImageChops.multiply(image, ImageChops.invert(clouds))
예제 #4
0
 def invert_image(self, imagein):
     outstr = ""
     outfile = StringIO.StringIO(outstr)
     img = Image.open(StringIO.StringIO(imagein))                            
     out = ImageChops.invert(img)                                               
     out.save(outfile, img.format)
     return outfile.getvalue()
예제 #5
0
def tex2img(tex, filename="equ.png", font_size=20):

    font_size = 20

    figure = matplotlib.figure.Figure(None, facecolor=(0, 0, 0, 0))
    canvas = matplotlib.backends.backend_agg.FigureCanvasAgg(figure)

    font_size = font_size

    tex = "${0}$".format(tex)

    figure.clear()
    figure.text(0.05, 0.5, tex, size=font_size)

    canvas.draw()

    png = "equ.png"

    figure.savefig(png, transparent=True, dpi=300, format="png")

    img = Image.open(png)

    imginv = ImageChops.invert(img.convert('L'))

    box = imginv.getbbox()

    img = img.crop(box)

    img = ImageOps.expand(img, border=10, fill=(255, 255, 255, 0))

    img.save(png, format="png")

    return img
예제 #6
0
 def __init__(self, pathDataFilename = "", worldImageFilename = "", resolution = 0.01):
     self.worldImageFilename = worldImageFilename
     self.pathDataFilename = pathDataFilename
     self.outfile = ""
     self.app = 0
     path = pyrobotdir()
     self.fontFilename = path + "/tools/pilfonts/courR08.pil"
     self.symbols = 1        # activates/deactivates symbol mode
     self.color = "0"          # activates/deactivates color
     self.length = 10     # the length of lines in non-symbol mode
     # the resolution given for the bitmap in the world file
     self.resolution = resolution
     self.interval = 2       # frequency datapoints should be displayed
     self.robotPathData = self.readDataFile()
     im = Image.open(self.worldImageFilename)
     if self.color == "0":
         self.imageData = ImageChops.invert(im)
     self.imageData = im.convert("RGB")
     self.convertXPositionData(self.imageData, self.robotPathData)
     self.drawObj = ImageDraw.Draw(self.imageData)
     self.textDict = {}
     self.symbolDict = {}
     self.symbolSet = SymbolSet()
     self.colorSet = ColorSet()
     self.quitWhenDone = 1
예제 #7
0
    def do_invert(self):
        """usage: invert <image:pic1>

        Invert the top image.
        """
        import ImageChops
        self.push(ImageChops.invert(self.do_pop()))
예제 #8
0
def draw_caption(img, text, outline=2, top=False):
	text_img = Image.new('RGBA', img.size, (0, 0, 0, 0))
	draw = ImageDraw.Draw(text_img)
	w = img.size[0]
	s = 100
	while w >= (img.size[0] - 20):
		font = ImageFont.truetype('HelveticaNeue-CondensedBlack', s)
		w, h = draw.textsize(text, font=font)
		s -= 1
		if s <= 12: break
	text_y = 0 if top else img.size[1] - h
	draw.text((10, text_y), text, font=font, fill='black')
	kernel = [0, 1, 2, 1, 0,
	          1, 2, 4, 2, 1,
	          2, 4, 0, 4, 1,
	          1, 2, 4, 2, 1,
	          0, 1, 2, 1, 0]
	myfilter = ImageFilter.Kernel((5, 5), kernel, scale = 0.25 * sum(kernel))
	for i in xrange(outline):
		print 'Processing image... ' + str(int(float(i)/outline * 100)) + '%'
		text_img = text_img.filter(myfilter)
	print 'Processing done.'
	draw = ImageDraw.Draw(text_img)
	draw.text((10, text_y), text, font = font, fill = 'white')
	mask_img = ImageChops.invert(text_img)
	result_img = Image.composite(img, text_img, mask_img)
	return result_img
예제 #9
0
def _save(im, fp, filename):

    try:
        rawmode = RAWMODE[im.mode]
    except KeyError:
        raise IOError("cannot write mode %s as JPEG" % im.mode)

    info = im.encoderinfo

    dpi = info.get("dpi", (0, 0))

    # get keyword arguments
    im.encoderconfig = (
        info.get("quality", 0),
        # "progressive" is the official name, but older documentation
        # says "progression"
        # FIXME: issue a warning if the wrong form is used (post-1.1.5)
        info.has_key("progressive") or info.has_key("progression"),
        info.get("smooth", 0),
        info.has_key("optimize"),
        info.get("streamtype", 0),
        dpi[0], dpi[1]
        )

    if im.mode == "CMYK":
        # invert it so it's handled correctly in Photoshop/etc. - Kevin Cazabon.
        im = ImageChops.invert(im)

    ImageFile._save(im, fp, [("jpeg", (0,0)+im.size, 0, rawmode)])
예제 #10
0
    def contrast(self, cropped_img):
        """
        Provides a high contrast board image for input into Tesseract OCR
        """

        # Convert the board image into greyscal

        bwImg = cropped_img.convert("L")

        # Multiply board image with inverted image so that text is black

        bwImgM = ImageChops.multiply(ImageChops.invert(bwImg), bwImg)

        # Increase contrast

        enhancedImg = ImageEnhance.Contrast(bwImgM)
        bwImgM = enhancedImg.enhance(5.0)

        # Produce pixel image object (array) for operation (operates in place)

        bwMDat = bwImgM.load()

        # If the pixel value is not black, make it white
        # (No colours any more, I want them to turn black)

        for i in range(0, bwImgM.size[1]):
            for j in range(0, bwImgM.size[0]):
                if bwMDat[j, i] != 0:
                    bwMDat[j, i] = 255
        # Debugging
        # bwImgM.show()

        return bwImgM
예제 #11
0
def img_from_tex(tex, font_size=20):

    figure = matplotlib.figure.Figure(None, facecolor='white')
    #canvas = matplotlib.backends.backend_wxagg.FigureCanvasWxAgg(None, -1, figure)
    canvas = matplotlib.backends.backend_wxagg.FigureCanvasAgg(figure)

    font_size = font_size

    tex = "${0}$".format(tex)

    figure.clear()
    figure.text(0.05, 0.5, tex, size=font_size)
    canvas.draw()

    filename = 'equ.png'

    figure.savefig(filename, dpi=600)

    img = Image.open(filename)

    imginv = ImageChops.invert(img.convert('L'))

    box = imginv.getbbox()
    img = img.crop(box)

    img = ImageOps.expand(img, border=10, fill=(255, 255, 255))

    img.save(filename)

    return img
예제 #12
0
    def OnSaveToFileBtn(self, event):

        if not self.math_panel.renderError:

            filename = 'equ.png'
            self.math_panel.figure.savefig(filename, dpi=300)

            pilImg = Image.open(filename)

            # Find the ordinates of the minimally enclosing bounding box.
            #
            # Create a simplified and inverted version of the original image to examine.
            invertedImage = ImageChops.invert(pilImg.convert('L'))

            # Get the bounding box's ordinates. Works on any image with a black background.
            box = invertedImage.getbbox()
            pilImg = pilImg.crop(box)

            # Add back a thin border padding
            pilImg = ImageOps.expand(pilImg, border=10, fill=(255, 255, 255))

            # Save the image to a disk file. Only PNG and TIFF formats are non-destructive.
            pilImg.save(filename)

        else:
            pass
예제 #13
0
def prepare(filename):
    img = Image.open(filename)
    img = ImageChops.invert(img)
    #img = img.convert("L").convert("RGB")
    img = img.resize((img.size[0]*2, img.size[1]*2), Image.BILINEAR)
    img = img.filter(ImageFilter.MedianFilter(3))

    return img
예제 #14
0
def invert(image, amount=100):
    image = imtools.convert_safe_mode(image)
    inverted = ImageChops.invert(image)
    if amount < 100:
        inverted = imtools.blend(image, inverted, amount / 100.0)
    if imtools.has_alpha(image):
        inverted.putalpha(imtools.get_alpha(image))
    return inverted
예제 #15
0
def round_image(image,cache={},radius=100,fill=255,pos=ROUNDED_POS, back_colour='#FFFFFF'):
    if image.mode != 'RGBA':
        image = image.convert('RGBA')
    mask    = create_rounded_rectangle(image.size,cache,radius,fill,pos)
    image.paste(Image.new('RGB',image.size,back_colour),(0,0),
        ImageChops.invert(mask))
    image.putalpha(mask)
    return image
예제 #16
0
 def dilate(self, image):
     paddedImage = self.createPaddedImage(image, 1)
     thresholdImg = paddedImage.point(lambda i, v=128: i > v and 255)
     thresholdImg = ImageChops.invert(thresholdImg)
     filteredImg = thresholdImg.filter(ImageFilter.FIND_EDGES)
     thresholdImg = filteredImg.point(lambda i, v=128: i > v and 255)
     arithImg = ImageChops.add(paddedImage, thresholdImg)
     box = (1, 1, arithImg.size[0]-1, arithImg.size[1]-1)
     outImage = arithImg.crop(box)
     return outImage
예제 #17
0
 def invertDstImage_(self, sender):
     image = self.dstImageView.image()
     if(image):
         # Turn this NSImage into a PIL image and invert it
         rep = image.representations()[0]
         height = rep.pixelsHigh()
         width = rep.pixelsWide()  
         bitmapData = rep.bitmapData()
         img = Image.frombuffer('L', (width, height), bitmapData).transpose(Image.FLIP_TOP_BOTTOM)
         # Invert and save to a temp file
         ImageChops.invert(img).save('/tmp/pippo.tiff')
         
         # Update the destination NSImageView
         newImage = NSImage.alloc().initWithContentsOfFile_('/tmp/pippo.tiff')
         if(newImage):
             self.dstImageView.setImage_(newImage)
         
         self.invertDstImage = not self.invertDstImage
     return
예제 #18
0
 def updateDstImageView(self, imgData):
     # FIXME: support non grey-scale images as well
     img = Image.frombuffer('L', imgData.shape, imgData.tostring())
     if (self.invertDstImage):
         img = ImageChops.invert(img)
     img.transpose(Image.FLIP_TOP_BOTTOM).save('/tmp/pippo.tiff')
     
     newImage = NSImage.alloc().initWithContentsOfFile_('/tmp/pippo.tiff')
     if(newImage):
         self.dstImageView.setImage_(newImage)
     return
예제 #19
0
def seg_mask(iseries, sbinfilepath, segmaskfilepath, segsbfilepath,origfilepath,expfilepath,segexpfilepath,segorigfilepath):
	#iseries is a filename, without jpg on the end and with sb on the end
	# First, apply mask to sb image - mask is black (or grey) on white background
	filename = re.sub('_mask','',iseries) + '.jpg' #this is the sb image
	# print 'Initial', filename

	maskim = Image.open(segmaskfilepath+ re.sub('.jpg','_mask.jpg',filename)).convert("L")
	# Mask not always black so first make sure it is
	threshold = 141
	maskim = maskim.point(lambda p: p > threshold and 255)

	threshfilename = re.sub('_sb','_sbthres', filename)
	sbim = Image.open(sbinfilepath + threshfilename)
	try:
		# print 'Get thresh'
		seg_sb = ImageChops.lighter(sbim,maskim)
		seg_sb.save(segsbfilepath+ re.sub('.jpg','_seg.jpg',threshfilename) )
	except IOError:
		print 'error in file'

	#Now open the original image - get rid of sb from filename
	filename = re.sub('_sb','', filename)
	origim = Image.open(origfilepath + filename).convert("L")
	seg_orig = ImageChops.lighter(origim,maskim)
	seg_orig.save(segorigfilepath+ re.sub('.jpg','_seg_orig.jpg',filename))

	#Now open the exp image and apply mask
	# First make mask white on black
	maskim = ImageChops.invert(maskim)

	# Now extract all the pixels that are white and make this region a transparent region on the mask
	maskim = maskim.convert('LA')
	datas = maskim.getdata()
	newData = list()
	for item in datas:
		if item[0] == 255:
			newData.append((255, 0))
		else:
			newData.append(item)

	maskim.putdata(newData)
	#img.save("img2.png", "PNG")
	l,a = maskim.split()

	# Check that exp file exists
	if os.path.exists(expfilepath +  re.sub('ish','exp',filename)):
		#seg_exp = ImageChops.logical_and(expim,maskim)
		expim = Image.open(expfilepath +  re.sub('ish','exp',filename)).convert("LA") # should be a grayscale image
		expim.paste(maskim, mask = a)
		expim = expim.convert("L")
		expim.save(segexpfilepath+ re.sub('.jpg','_seg_exp.tif',filename))
	else: print 'N'
예제 #20
0
파일: main.py 프로젝트: imgqb/sketch-py
 def ConvertImage(self, e):
     '''
     convert the origin image to sketch image
     '''
     if not(self.rightRadius()):
         return
     
     image = self.OpenImage
     disColourImg = image.convert("L")
     invertImg = ImageChops.invert(disColourImg)
     gaussblurImg = invertImg.filter(ImageFilter.GaussianBlur(radius=self.input.GetValue()))
     dodgeImg = self.dodgeColor(disColourImg, gaussblurImg)
     self.OnImagePanel(dodgeImg)
예제 #21
0
	def process(self, image):
		yield 'Layer...', image
		lay = image.copy()
		lay = lay.filter(ImageFilter.BLUR)
		yield 'Brightness...', lay
		lay = ImageEnhance.Brightness(lay).enhance(1.0)
		yield 'Contrast...', lay
		lay = ImageEnhance.Contrast(lay).enhance(1.0)
		yield 'Mask...', lay
		mask = lay.convert("L")
		mask = ImageChops.invert(mask)
		image = Image.composite(image, lay, mask)
		yield 'Done', image
예제 #22
0
 def test_L_symmetry(self):
     """
     image and negated image have the same keypoints
     """
     ref = simple(self.im640)
     self.assert_(len(ref) != 0) # if no hits in the image, have a test bug
     result = simple(ImageChops.invert(self.im640))
     self.assertEqual(len(ref), len(result))
     for (a,e) in zip(sorted(result), sorted(ref)):
         self.assertAlmostEqual(a[0], e[0], 3)
         self.assertAlmostEqual(a[1], e[1], 3)
         self.assertAlmostEqual(a[2], e[2], 3)
         self.assertAlmostEqual(a[3], -e[3], 3)
예제 #23
0
	def process(self, base):
		yield 'Desaturate...', base
		lay1 = colors.convert_to_luminosity(base)
		yield 'Invert...', lay1
		lay1 = ImageChops.invert(lay1)
		yield 'Smoth...', lay1
		lay1 = lay1.filter(ImageFilter.BLUR)
		yield 'Merge...', lay1
		lay2 = base.copy()
		lay2 = ImageChops.blend(lay1, lay2, 0.75)
		yield 'Mege softlight...', lay2
		image = base.copy()
		image = layers.merge_layers_soft_light(image, lay2, 0.9)
		yield 'Done', image
예제 #24
0
파일: photo.py 프로젝트: kif/imagizer
    def contrastMask(self, outfile):
        """Ceci est un filtre de debouchage de photographies, aussi appelé masque de contraste,
        il permet de rattrapper une photo trop contrasté, un contre jour, ...
        Écrit par Jérôme Kieffer, avec l'aide de la liste python@aful,
        en particulier A. Fayolles et F. Mantegazza avril 2006
        necessite numpy et PIL.

        @param: the name of the output file (JPEG)
        @return: filtered Photo instance
        """

        try:
            import numpy
#            import scipy.signal as signal
        except:
            logger.error("This filter needs the numpy library available on https://sourceforge.net/projects/numpy/files/")
            return

        t0 = time.time()
        dimX, dimY = self.pil.size

        ImageFile.MAXBLOCK = dimX * dimY
        img_array = numpy.fromstring(self.pil.tostring(), dtype="UInt8").astype("float32")
        img_array.shape = (dimY, dimX, 3)
        red, green, blue = img_array[:, :, 0], img_array[:, :, 1], img_array[:, :, 2]
        # nota: this is faster than desat2=(ar.max(axis=2)+ar.min(axis=2))/2
        desat_array = (numpy.minimum(numpy.minimum(red, green), blue) + numpy.maximum(numpy.maximum(red, green), blue)) / 2.0
        inv_desat = 255. - desat_array
        blured_inv_desat = self._gaussian.blur(inv_desat, config.ContrastMaskGaussianSize)
        bisi = numpy.round(blured_inv_desat).astype("uint8")
        k = Image.fromarray(bisi, "L").convert("RGB")
        S = ImageChops.screen(self.pil, k)
        M = ImageChops.multiply(self.pil, k)
        F = ImageChops.add(ImageChops.multiply(self.pil, S), ImageChops.multiply(ImageChops.invert(self.pil), M))
        dst_filename = op.join(config.DefaultRepository, outfile)
        F.save(dst_filename, quality=80, progressive=True, Optimize=True)
        try:
            os.chmod(dst_filename, config.DefaultFileMode)
        except IOError:
            logger.error("Unable to chmod %s" % outfile)
        exifJpeg = Exif(dst_filename)
        exifJpeg.read()
        self.exif.copy(exifJpeg)
        exifJpeg.comment = self.exif.comment
        logger.debug("Write metadata to %s", dst_filename)
        exifJpeg.write()
        logger.info("The whoole contrast mask took %.3f" % (time.time() - t0))
        res = Photo(outfile)
        res.autorotate()
        return res
예제 #25
0
    def _open(self):

        s = self.fp.read(1)

        if ord(s[0]) != 255:
            raise SyntaxError("not a JPEG file")

        # Create attributes
        self.bits = self.layers = 0

        # JPEG specifics (internal)
        self.layer = []
        self.huffman_dc = {}
        self.huffman_ac = {}
        self.quantization = {}
        self.app = {}  # compatibility
        self.applist = []

        while 1:

            s = s + self.fp.read(1)

            i = i16(s)

            if MARKER.has_key(i):
                name, description, handler = MARKER[i]
                # print hex(i), name, description
                if handler is not None:
                    handler(self, i)
                if i == 0xFFDA:  # start of scan
                    rawmode = self.mode
                    # patch by Kevin Cazabon to comment this out - nobody should be using Photoshop 2.5 any more (and it breaks newer versions)
                    # CMYK images are still inverted, we'll fix that just before returning.
                    #if self.mode == "CMYK" and self.info.has_key("adobe"):
                    #    rawmode = "CMYK;I" # Photoshop 2.5 is broken!

                    self.tile = [("jpeg", (0, 0) + self.size, 0, (rawmode, ""))
                                 ]
                    # self.__offset = self.fp.tell()
                    break
                s = self.fp.read(1)
            elif i == 0 or i == 65535:
                # padded marker or junk; move on
                s = "\xff"
            else:
                raise SyntaxError("no marker found")

        # patch by Kevin Cazabon to re-invert CMYK JPEG files
        if self.mode == "CMYK":
            self.im = ImageChops.invert(self).im
예제 #26
0
파일: round.py 프로젝트: Reimilia/Camellia
def round_image(image, cache={}, round_all=True, rounding_type=None,
        radius=100, opacity=255, pos=ROUNDED_POS, back_color='#FFFFFF'):
    if image.mode != 'RGBA':
        image = image.convert('RGBA')

    if round_all:
        pos = 4 * (rounding_type, )

    mask = create_rounded_rectangle(image.size, cache, radius, opacity, pos)

    imtools.paste(image, Image.new('RGB', image.size, back_color), (0, 0),
        ImageChops.invert(mask))
    image.putalpha(mask)
    return image
예제 #27
0
def main():
    print 'Started'

    os.system('mkdir tmp')

    effects = [
        # LocalWarpEffect((50, 20), (80, 40), 30),
        # RadianSqrtEffect(),
        # LensWarpEffect(lambda x, y: (sign(x) * x ** 2, sign(y) * y ** 2)),
        # RadianFormulaEffect(lambda r, phi: (r ** 2, phi), 4), 
        GlobalWaveEffect(1, 0.5),
        # LensWarpEffect(lambda x, y: (sin(x * math.pi / 2), sin(y * math.pi / 2))),
        # RadianFormulaEffect(lambda r, phi: (r ** 1.5 * math.cos(r), phi)),
               ] 

    # if os.path.exists('z.jpg'):
    #     img = Image.open('z.jpg')
    # else:
    #     img = Image.new("RGBA", (300, 300), (255, 255, 255, 255))

    characters = string.letters + string.digits
    char_img = {} 
    for ch in characters:
        img = Image.open('Images/%s.png' % ch)
        char_img[ch] = Character(img)

    text = ''.join(random.choice(string.letters) for i in xrange(4))

    img = Image.new("RGBA", (100, 40), (255, 255, 255, 255))
    font = ImageFont.truetype("UbuntuMono-R.ttf", 33)
    # draw = ImageDraw.Draw(img) 
    # draw.setfont(font) 
    # draw.text((10, 0), text, (0, 0, 0)) 

    last = random.choice(characters)
    offset = 15
    for i in range(5):
        ch = random.choice(characters)
        img.paste(char_img[ch].img,
                  (offset, 0),
                  ImageChops.invert(char_img[ch].img.split()[1]))
        last = ch
        offset += char_img[last].width - 1

    for index, effect in enumerate(effects):
        for i in xrange(1):
            merge_origin_and_new(img, effect).save('tmp/%d-%d.jpg' % (index, i), quality=90)
        print '.',
    print 'done'
예제 #28
0
    def _open(self):

        s = self.fp.read(1)

        if ord(s[0]) != 255:
            raise SyntaxError("not a JPEG file")

        # Create attributes
        self.bits = self.layers = 0

        # JPEG specifics (internal)
        self.layer = []
        self.huffman_dc = {}
        self.huffman_ac = {}
        self.quantization = {}
        self.app = {} # compatibility
        self.applist = []

        while 1:

            s = s + self.fp.read(1)

            i = i16(s)

            if MARKER.has_key(i):
                name, description, handler = MARKER[i]
                # print hex(i), name, description
                if handler is not None:
                    handler(self, i)
                if i == 0xFFDA: # start of scan
                    rawmode = self.mode
                    # patch by Kevin Cazabon to comment this out - nobody should be using Photoshop 2.5 any more (and it breaks newer versions)
                    # CMYK images are still inverted, we'll fix that just before returning.
                    #if self.mode == "CMYK" and self.info.has_key("adobe"):
                    #    rawmode = "CMYK;I" # Photoshop 2.5 is broken!

                    self.tile = [("jpeg", (0,0) + self.size, 0, (rawmode, ""))]
                    # self.__offset = self.fp.tell()
                    break
                s = self.fp.read(1)
            elif i == 0 or i == 65535:
                # padded marker or junk; move on
                s = "\xff"
            else:
                raise SyntaxError("no marker found")

        # patch by Kevin Cazabon to re-invert CMYK JPEG files
        if self.mode == "CMYK":
            self.im = ImageChops.invert(self).im
예제 #29
0
    def __init__(self, filename):
        """
        this filter allows add a signature to an image
        """
        self.img = None
        self.sig = Image.open(filename)
        self.sig.convert("RGB")
        (self.xs, self.ys) = self.sig.size
        self.bigsig = self.sig
        #The signature file is entented to be white on a black background, this inverts the color if necessary
        if ImageStat.Stat(self.sig)._getmean() > 127:
            self.sig = ImageChops.invert(self.sig)

        self.orientation = -1 #this is an impossible value
        (self.x, self.y) = (self.xs, self.ys)
예제 #30
0
    def process(self):
        # Try to open image and convert it to black and white
        try:
            self.image = ImageChops.invert(Image.open(self.filename).convert("L"))
        except IOError(e):
            return (False, str(e), None, None)
        
        sx, sy = self.image.size
        
        # Extract bins to internal data structures
        self.extractBins()

        # Extract BGA array geometry from bins
        self.extractArrayFromBins()
        
        return (True, "", self.bgaArray.copy(), self.image)
예제 #31
0
def draw_bins(filename, sourceImage, nx, ny, bgaArray):
    """
    Draw an image containing the bins and detected ball positions, for
    user verification.
    
    Parameters:
    * filename: filename to use for saving processed image
    * sourceImage: source image that was processed to extract the bga array
    * nx: number of bins on X axis in image
    * ny: number of bins on Y axis in image
    * bgaArray: boolean array of occupied ball positions
    """
    # Get a new drawing context
    newImage = sourceImage.copy()
    newImage = ImageChops.invert(newImage).convert("RGB")
    gc = ImageDraw.Draw(newImage)
    sx, sy = newImage.size

    # Draw a circle in every detected pad bin
    for py in range(ny):
        for px in range(nx):
            xmin, ymin, xmax, ymax = get_bin_bounds(sourceImage, nx, ny, px,
                                                    py)
            gc.line([(0, ymax), (sx, ymax)], fill="blue")
            gc.line([(xmax, 0), (xmax, sy)], fill="blue")

            width = (xmax - xmin) + 1
            height = (ymax - ymin) + 1

            xmin2 = xmin + round(float(width) * 0.4)
            xmax2 = xmin + round(float(width) * 0.6)
            ymin2 = ymin + round(float(height) * 0.4)
            ymax2 = ymin + round(float(height) * 0.6)

            if bgaArray[py, px]:
                gc.ellipse((xmin2, ymin2, xmax2, ymax2),
                           outline="red",
                           fill="red")
    del gc

    try:
        newImage.save(filename)
    except IOError:
        return None

    return filename
예제 #32
0
    def OnSaveToFileBtn( self, event ) :

        if not self.math_panel.renderError :

            filename = 'Rendered_Equation.png'
            self.math_panel.figure.savefig( filename, dpi=300 )
            print('\n----  Equation Graphic Saved to File [ %s ]' % filename)

            # See if the PIL package is installed.
            pilIsInstalled = True
            try :
                # Try to crop the image to its near-minimum extent.
                import Image        # PIL (Python Image Library)
                import ImageChops   # Image Channel Operations library
                import ImageStat    # Image Statistics library
                import ImageOps     # Various whole image operations.

            except :
                pilIsInstalled = False   # Image will not get auto-cropped.
            #end try

            if pilIsInstalled :      # Auto-crop the image.
                pilImg = Image.open( filename )

                # Find the ordinates of the minimally enclosing bounding box.
                #
                # Create a simplified and inverted version of the original image to examine.
                invertedImage = ImageChops.invert( pilImg.convert( 'L' ) )   # BG must be black to examine.

                # Get the bounding box's ordinates. Works on any image with a black background.
                box = invertedImage.getbbox()
                pilImg = pilImg.crop( box )

                # Add back a thin border padding. This is arbitrary, but seems reasonable.
                pilImg = ImageOps.expand( pilImg, border=10, fill=(255, 255, 255) )

                # Save the image to a disk file. Only PNG and TIFF formats are non-destructive.
                pilImg.save( filename )
                print('      Cropped Equation Graphic Saved')

            #end if

        else :
            print('\n---- Tex Rendering Error:  Figure Image NOT SAVED to a File.')
예제 #33
0
def draw_bins(filename, sourceImage, nx, ny, bgaArray):
    """
    Draw an image containing the bins and detected ball positions, for
    user verification.
    
    Parameters:
    * filename: filename to use for saving processed image
    * sourceImage: source image that was processed to extract the bga array
    * nx: number of bins on X axis in image
    * ny: number of bins on Y axis in image
    * bgaArray: boolean array of occupied ball positions
    """
    # Get a new drawing context
    newImage = sourceImage.copy()
    newImage = ImageChops.invert(newImage).convert("RGB")
    gc = ImageDraw.Draw(newImage)
    sx, sy = newImage.size
    
    # Draw a circle in every detected pad bin
    for py in range(ny):
        for px in range(nx):
            xmin, ymin, xmax, ymax = get_bin_bounds(sourceImage, nx, ny, px, py)
            gc.line([(0,ymax),(sx,ymax)], fill = "blue")
            gc.line([(xmax,0),(xmax,sy)], fill = "blue")
            
            width = (xmax - xmin) + 1
            height = (ymax - ymin) + 1
            
            xmin2 = xmin + round(float(width) * 0.4)
            xmax2 = xmin + round(float(width) * 0.6)
            ymin2 = ymin + round(float(height) * 0.4)
            ymax2 = ymin + round(float(height) * 0.6)
            
            if bgaArray[py,px]:
                gc.ellipse((xmin2, ymin2, xmax2, ymax2), outline = "red", fill = "red")
    del gc
    
    try:
        newImage.save(filename)
    except IOError:
        return None    
    
    return filename
예제 #34
0
def local_histogram_normalization(im):
    try:
        imr, img, imb = im.split()
    except:
        try:
            imr, img, imb, ima = im.split()
        except:
            img = im  # given image is not rgb
    w, h = img.size
    img.save('img.png')
    xwin = w / 6 + 1
    ywin = h / 5 + 1
    for x in range(0, w, xwin):
        for y in range(0, h, ywin):
            im_loc = img.crop((x, y, min(x + xwin, w), min(y + ywin, h)))
            local_max = ImageStat.Stat(im_loc).extrema[0][1]
            im_loc_norm = ImageChops.invert(
                im_loc.point(lambda i: local_max - i))
            img.paste(im_loc_norm, (x, y))
    return img
예제 #35
0
def moveimages(originfolder, origfilename, maskinfolder, maskfilename,expinfolder, expfilename,outorigfolder,outexpfolder):
	'''
	Function for moving images into the centre - we didn't use this
	'''

	try:
		segorigimage = Image.open(originfolder +origfilename).convert("L")
		segexpimage = Image.open(expinfolder +expfilename).convert("L")
		maskim =  Image.open(maskinfolder + maskfilename).convert("L") # need to convert to 8 bit (not rgb)
	except IOError:
		print origfilename, 'Image failed'
		return

	threshold = 141
	maskim = maskim.point(lambda p: p > threshold and 255)
	maskim = ImageChops.invert(maskim)
	com = ndimage.measurements.center_of_mass(np.array(maskim))
	dwidth = int(com[1] - 525) # centre of mass - 600 (so leftwards will be negative)
	dheight = int(com[0] - 430) # centre of mass - 450 (so upwards will be negative)
	newsegimage = Image.new('L', (1200,900), (255) ) # white image for seg orig
	newexpimage = Image.new('L', (1200,900), (0) ) # black image for seg orig
	print dwidth, dheight
	le = up = 0; ri = segorigimage.size[0]; lo = segorigimage.size[1];left = upper = 0
	if dwidth > 0:le = int(dwidth)
	else: ri = segorigimage.size[0] +  int(dwidth); left = -dwidth
	if dheight > 0: up = int(dheight)
	else: lo = segorigimage.size[1]  + int(dheight); upper = -dheight
	box = (le, up, ri, lo)

	newsegorigimage = segorigimage.crop(box)
	newsegexpimage = segexpimage.crop(box)

	newsegimage.paste(newsegorigimage, (left,upper,left + newsegorigimage.size[0],upper + newsegorigimage.size[1])) # left, upper, right, lower
	newsegimage.save(outorigfolder +  origfilename)
	newexpimage.paste(newsegexpimage, (left,upper,left + newsegexpimage.size[0],upper + newsegexpimage.size[1])) # left, upper, right, lower
	newexpimage.save(outexpfolder +  expfilename)
예제 #36
0
#The lines below are pango/cairo code
surface = cairo.ImageSurface(cairo.FORMAT_A8, 400, 100)
context = cairo.Context(surface)

pc = pangocairo.CairoContext(context)

layout = pc.create_layout()
layout.set_font_description(pango.FontDescription('Lohit Bengali 15'))
layout.set_text(
    "কুকুর হাহা কুকুর হাহা কুকুর হাহা কুকুর হাহা কুকুর হাহা কুকুর হাহা কুকুর হাহা কুকুর হাহা\n কি হল কি হল কি হল কি হল কি হল কি হল কি হল কি হল কি হল কি হল কি হল কি হল কি হল"
)

# Next four lines take care of centering the text. Feel free to ignore ;-)
width, height = surface.get_width(), surface.get_height()
w, h = layout.get_pixel_size()
position = (10, 10)  #(width/2.0 - w/2.0, height/2.0 - h/2.0)
context.move_to(*position)
pc.show_layout(layout)
surface.write_to_png("text")

temp_image = Image.open("text")  #black background, white text
draw = ImageDraw.Draw(temp_image)
bbox = temp_image.getbbox()
#print bbox
inverted_image = ImageChops.invert(temp_image)  #White background, black text
draw = ImageDraw.Draw(inverted_image)  #Lets transfer "draw" to the new image
#draw.rectangle(bbox,None,100) #draw the bounding box
inverted_image.save("single.tif", "TIFF")  #save the symbol to a file
os.unlink("text")
예제 #37
0
def draw(font_string, font_size, lang, alphabets
         ):  # language, font file name, font full path, font size, characters
    """ Generates tif images and box files"""

    image_dir = lang + "." + "images"
    if (os.path.exists(image_dir)):
        pass
    else:
        os.mkdir(image_dir)

    #Using a font
    #font= ImageFont.truetype(font,fsz)
    boxfile = image_dir + "/" + "bigimage.box"
    f = open(boxfile, "w")

    bigimage = Image.new("L", (2000, 2000), 255)
    bigdraw = ImageDraw.Draw(bigimage)
    x = y = 10
    count = 0
    for akshar in alphabets:
        akshar.strip()  #remove nasty characters

        #I shall now create an image with black bgc and white font color. One
        #getbbox() determines the bounding box values I shall invert the image.
        #This has to be done since getbbox() only finds bounding box values for
        #non-zero pixels (read as white), but tesseract-ocr runs on the exact
        #opposite bgc fgc combination. Contact [email protected].

        #The lines below are pango/cairo code
        surface = cairo.ImageSurface(cairo.FORMAT_A8, font_size * 4,
                                     font_size * 3)
        context = cairo.Context(surface)

        pc = pangocairo.CairoContext(context)

        layout = pc.create_layout()
        layout.set_font_description(pango.FontDescription(font_string))
        layout.set_text(akshar)
        print akshar

        #  lines take care of centering the text.
        width, height = surface.get_width(), surface.get_height()
        w, h = layout.get_pixel_size()
        position = (10, 10)  #(width/2.0 - w/2.0, height/2.0 - h/2.0)
        context.move_to(*position)
        pc.show_layout(layout)
        surface.write_to_png("pango.png")
        #iter=layout.get_iter()
        #print iter.get_char_extents()

        #Here we open the generated image using PIL functions
        temp_image = Image.open("pango.png")  #black background, white text
        draw = ImageDraw.Draw(temp_image)
        bbox = temp_image.getbbox()
        deltax = bbox[2] - bbox[0]
        deltay = bbox[3] - bbox[1]

        print bbox
        new_image = temp_image.crop(bbox)
        temp_image = temp_image.load()
        inverted_image = ImageChops.invert(
            new_image)  #White background, black text

        inverted_image.save(image_dir + "/" + str(count) + ".png")
        count = count + 1

        bigimage.paste(inverted_image, (x, y))
        #bigimage.load()
        bigbox = (x, y, x + deltax, y + deltay)
        print bigbox
        draw = ImageDraw.Draw(bigimage)
        #draw.rectangle(bigbox,None,100)
        x = bigbox[2] + 5
        if x > 1950:
            x = 10
            y = y + 40

        os.unlink("pango.png")  #delete the pango generated png

        line = akshar + " " + str(bigbox[0] - 1) + " " + str(2000 - (
            bigbox[1] + deltay) - 1) + " " + str(bigbox[2] + 1) + " " + str(
                2000 - (bigbox[3] - deltay) +
                1)  # this is the line to be added to the box file
        f.write(line + '\n')

        #degrade code starts
        strip = [deltax * .2, deltax * .4, deltax * .7]
        for values in range(0, 3):
            distort2 = inverted_image
            for wai in range(0, deltay):
                for ex in range(strip[values], strip[values] + 1):
                    distort2.putpixel((ex, wai), 255)
            bigbox = (x, y, x + deltax, y + deltay)
            #draw.rectangle(bigbox,None,10)
            line = akshar + " " + str(bigbox[0] - 1) + " " + str(
                2000 - (bigbox[1] + deltay) -
                1) + " " + str(bigbox[2] + 1) + " " + str(
                    2000 - (bigbox[3] - deltay) +
                    1)  # this is the line to be added to the box file
            f.write(line + '\n')
            bigimage.paste(distort2, (x, y))
            x = bigbox[2] + 5
            if x > 1950:
                x = 10
                y = y + 40

#degrade code ends

#distort.distort(filename2,bbox,fsz,akshar)

    bigimage.save(image_dir + "/" + "bigimage.tif", "TIFF")
    f.close()
예제 #38
0
def drop_shadow(image,
                horizontal_offset=5,
                vertical_offset=5,
                background_color=(255, 255, 255, 0),
                shadow_color=0x444444,
                border=8,
                shadow_blur=3,
                force_background_color=False,
                cache=None):
    """Add a gaussian blur drop shadow to an image.

    :param image: The image to overlay on top of the shadow.
    :param type: PIL Image
    :param offset:

        Offset of the shadow from the image as an (x,y) tuple.
        Can be positive or negative.

    :type offset: tuple of integers
    :param background_color: Background color behind the image.
    :param shadow_color: Shadow color (darkness).
    :param border:

        Width of the border around the image.  This must be wide
        enough to account for the blurring of the shadow.

    :param shadow_blur:

        Number of times to apply the filter.  More shadow_blur
        produce a more blurred shadow, but increase processing time.
    """
    if cache is None:
        cache = {}

    if has_transparency(image) and image.mode != 'RGBA':
        # Make sure 'LA' and 'P' with trasparency are handled
        image = image.convert('RGBA')

    #get info
    size = image.size
    mode = image.mode

    back = None

    #assert image is RGBA
    if mode != 'RGBA':
        if mode != 'RGB':
            image = image.convert('RGB')
            mode = 'RGB'
        #create cache id
        id = ''.join([
            str(x) for x in [
                'shadow_', size, horizontal_offset, vertical_offset, border,
                shadow_blur, background_color, shadow_color
            ]
        ])

        #look up in cache
        if id in cache:
            #retrieve from cache
            back, back_size = cache[id]

    if back is None:
        #size of backdrop
        back_size = (size[0] + abs(horizontal_offset) + 2 * border,
                     size[1] + abs(vertical_offset) + 2 * border)

        #create shadow mask
        if mode == 'RGBA':
            image_mask = get_alpha(image)
            shadow = Image.new('L', back_size, 0)
        else:
            image_mask = Image.new(mode, size, shadow_color)
            shadow = Image.new(mode, back_size, background_color)

        shadow_left = border + max(horizontal_offset, 0)
        shadow_top = border + max(vertical_offset, 0)
        paste(shadow, image_mask,
              (shadow_left, shadow_top, shadow_left + size[0],
               shadow_top + size[1]))
        del image_mask  # free up memory

        #blur shadow mask

        #Apply the filter to blur the edges of the shadow.  Since a small
        #kernel is used, the filter must be applied repeatedly to get a decent
        #blur.
        n = 0
        while n < shadow_blur:
            shadow = shadow.filter(ImageFilter.BLUR)
            n += 1

        #create back
        if mode == 'RGBA':
            back = Image.new('RGBA', back_size, shadow_color)
            back.putalpha(shadow)
            del shadow  # free up memory
        else:
            back = shadow
            cache[id] = back, back_size

    #Paste the input image onto the shadow backdrop
    image_left = border - min(horizontal_offset, 0)
    image_top = border - min(vertical_offset, 0)
    if mode == 'RGBA':
        paste(back, image, (image_left, image_top), image)
        if force_background_color:
            mask = get_alpha(back)
            paste(back, Image.new('RGB', back.size, background_color), (0, 0),
                  ImageChops.invert(mask))
            back.putalpha(mask)
    else:
        paste(back, image, (image_left, image_top))

    return back
예제 #39
0
def loadimg(fn):
  im = Image.open(fn)
  im = im.convert("1").convert("RGB")

  im = ImageChops.invert(im)

  im = im.filter(ImageFilter.Kernel((3,3), [0,1,0,0,1,1,0,1,0]))
  #im = im.filter(ImageFilter.CONTOUR)
  #im = im.filter(ImageFilter.EDGE_ENHANCE)
  #im = im.filter(ImageFilter.EDGE_ENHANCE_MORE)
  
  im = im.crop(im.getbbox())
  #ts = [t/100.0 for t in range(101)]
  draw = ImageDraw.Draw(im)
  #draw.rectangle(getbounds(l), outline="green")
  #im = im.crop(im.getbbox())

  pts = []
  pbs = []
  
  step = im.size[0] / 10
  start = None
  for x in range(0, 10):
    crop = im.crop((x*step,0,(x+1)*step,100))
    box = crop.getbbox()
    if box != None:
      by = box[1]
      by2 = box[3]-1
      bx = -1
      bx2 = -1
      if start == None: start = (by,by2)

      for xx in range(0,step):
        if crop.getpixel((xx,by)) != Black and bx < 0:
          bx = xx
        if crop.getpixel((xx,by2)) != Black and bx2 < 0:
          bx2 = xx

      #if bx < 0: bx = 0
      #if bx2 < 0: bx2 = 0

      pts.append(((x*step)+bx,by))
      pbs.append(((x*step)+bx2,by2))

  #bz = make_bezier(pts)
  #draw.line(bz(ts), fill=128)
  pts.insert(0, (0,start[0]))
  pbs.insert(0, (0,start[1]))
  pts.append((im.size[0], by))
  pbs.append((im.size[0], by2))
  draw.line(pts, fill=255)
  draw.line(pbs, fill=255)
  del draw

  un = undeform(im)
  letters = full_check(un.copy())
  if letters == None:
    return []
    
  ret = []
  for lt in divide(paint_letters(letters)):
    ret.append(lt.resize((30,30)))
  return ret  
예제 #40
0
    def _process_edge(self):
        """Process the request as an edge piece"""
        # More sanity-checks:
        # B1, B2 are incompatible with B
        if ("B" in self.request_parts and
            ("B1" in self.request_parts or "B2" in self.request_parts)):
            Logger.log.info("B used with one of B1 and B2")
            raise apache.SERVER_RETURN, apache.HTTP_NOT_FOUND
        # D must be present and have a single F or R following
        if "D" not in self.request_parts:
            Logger.log.info("D parameter not present")
            raise apache.SERVER_RETURN, apache.HTTP_NOT_FOUND
        if len(self.request_parts["D"]) != 1:
            Logger.log.info(
                "D parameter does not have exactly one dotted part")
            raise apache.SERVER_RETURN, apache.HTTP_NOT_FOUND
        if self.request_parts["D"][0] not in ("F", "R"):
            Logger.log.info("D parameter is neither F nor R")
            raise apache.SERVER_RETURN, apache.HTTP_NOT_FOUND

        # Hang on to direction
        self.edge_forward = (self.request_parts["D"][0] == "F")

        # We must have T1 and T2 defined -- if not, create some empties
        if "T1" not in self.request_parts:
            self.request_parts["T1"] = []
        if "T2" not in self.request_parts:
            self.request_parts["T2"] = []

        upper_side = Part.HEX_LL
        lower_side = Part.HEX_UR
        direction = "B"
        if self.edge_forward:
            upper_side = Part.HEX_LR
            lower_side = Part.HEX_UL
            direction = "F"

        upper_body = HexComponent(self.meta, self.request_parts["T1"],
                                  upper_side)
        lower_body = HexComponent(self.meta, self.request_parts["T2"],
                                  lower_side)

        # Canonicalise the filename and check the cache
        file_name = "edge-T1-" + upper_body.base_name() \
           + "-T2-" + lower_body.base_name() \
           + "-B1-" \
           + "-B2-" \
           + "-D-" + direction \
           + ".png"
        file_name = os.path.join(self.set_path, "cache", file_name)
        if self._check_cache(file_name):
            return file_name

        # This mask is full transparency at the top, so we use it for
        # drawing the bottom half of the image
        hgt = self.meta["image-height"]
        hstr = self.meta["stride-height"]
        image_size = (self.meta["image-width"] / 2, hgt - hstr)
        bottom_mask = Image.new("1", image_size, 1)
        md = ImageDraw.Draw(bottom_mask)
        if self.edge_forward:
            md.polygon(((0, 0), (image_size[0], 0), (0, image_size[1])),
                       fill=0)
        else:
            md.polygon(
                ((0, 0), (image_size[0], 0), (image_size[0], image_size[1])),
                fill=0)
        # FIXME: Why does this next line not invert the mask properly?
        top_mask = ImageChops.invert(bottom_mask)

        name = os.tmpnam() + ".png"
        Logger.log.debug("Saving top mask as: " + name)
        top_mask.save(name)
        name = os.tmpnam() + ".png"
        Logger.log.debug("Saving bottom mask as: " + name)
        bottom_mask.save(name)

        # Construct our image and composite it together
        image = Image.new("RGBA", image_size, (255, 255, 255, 255))
        Logger.log.debug("Request: starting compositing")
        image = upper_body.composite(image, top_mask)
        image = lower_body.composite(image, bottom_mask)
        Logger.log.debug("Request: finished compositing")

        # Save the image and return it
        image.save(file_name)
        return file_name
예제 #41
0
def draw_text_with_halo(img, position, text, font, col, halo_col):
    halo = Image.new('RGBA', img.size, (0, 0, 0, 0))
    ImageDraw.Draw(halo).text(position, text, font=font, fill=halo_col)
    blurred_halo = halo.filter(ImageFilter.BLUR)
    ImageDraw.Draw(blurred_halo).text(position, text, font=font, fill=col)
    return Image.composite(img, blurred_halo, ImageChops.invert(blurred_halo))
예제 #42
0
pngFiles = glob.glob(folder + "/*.png")

totalFiles = len(pngFiles)

for (i, filename) in enumerate(pngFiles):

    print "Cleaned " + str(i) + " Of " + str(totalFiles) + " Images"

    image = Image.open(filename)

    w = image.size[0]
    h = image.size[1]

    scaledCoord = [(round(x * (w / maxW)), round(y * (h / maxH)))
                   for (x, y) in coord]

    im = Image.open(filename)

    overlay = Image.new('RGBA', im.size)

    draw = ImageDraw.Draw(overlay)

    draw.polygon(scaledCoord, fill=(255, 255, 255), outline=(0, 0, 0))

    inverted_overlay = ImageChops.invert(overlay)

    im.paste("black", (0, 0), mask=inverted_overlay)

    im.save(filename)