Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/PIL/ImageOps.py
diff options
context:
space:
mode:
Diffstat (limited to 'PIL/ImageOps.py')
-rw-r--r--PIL/ImageOps.py408
1 files changed, 0 insertions, 408 deletions
diff --git a/PIL/ImageOps.py b/PIL/ImageOps.py
deleted file mode 100644
index 89b5e72..0000000
--- a/PIL/ImageOps.py
+++ /dev/null
@@ -1,408 +0,0 @@
-#
-# The Python Imaging Library.
-# $Id: ImageOps.py 2760 2006-06-19 13:31:40Z fredrik $
-#
-# standard image operations
-#
-# History:
-# 2001-10-20 fl Created
-# 2001-10-23 fl Added autocontrast operator
-# 2001-12-18 fl Added Kevin's fit operator
-# 2004-03-14 fl Fixed potential division by zero in equalize
-# 2005-05-05 fl Fixed equalize for low number of values
-#
-# Copyright (c) 2001-2004 by Secret Labs AB
-# Copyright (c) 2001-2004 by Fredrik Lundh
-#
-# See the README file for information on usage and redistribution.
-#
-
-import Image
-import operator
-
-##
-# (New in 1.1.3) The <b>ImageOps</b> module contains a number of
-# 'ready-made' image processing operations. This module is somewhat
-# experimental, and most operators only work on L and RGB images.
-#
-# @since 1.1.3
-##
-
-#
-# helpers
-
-def _border(border):
- if type(border) is type(()):
- if len(border) == 2:
- left, top = right, bottom = border
- elif len(border) == 4:
- left, top, right, bottom = border
- else:
- left = top = right = bottom = border
- return left, top, right, bottom
-
-def _color(color, mode):
- if Image.isStringType(color):
- import ImageColor
- color = ImageColor.getcolor(color, mode)
- return color
-
-def _lut(image, lut):
- if image.mode == "P":
- # FIXME: apply to lookup table, not image data
- raise NotImplementedError("mode P support coming soon")
- elif image.mode in ("L", "RGB"):
- if image.mode == "RGB" and len(lut) == 256:
- lut = lut + lut + lut
- return image.point(lut)
- else:
- raise IOError, "not supported for this image mode"
-
-#
-# actions
-
-##
-# Maximize (normalize) image contrast. This function calculates a
-# histogram of the input image, removes <i>cutoff</i> percent of the
-# lightest and darkest pixels from the histogram, and remaps the image
-# so that the darkest pixel becomes black (0), and the lightest
-# becomes white (255).
-#
-# @param image The image to process.
-# @param cutoff How many percent to cut off from the histogram.
-# @param ignore The background pixel value (use None for no background).
-# @return An image.
-
-def autocontrast(image, cutoff=0, ignore=None):
- "Maximize image contrast, based on histogram"
- histogram = image.histogram()
- lut = []
- for layer in range(0, len(histogram), 256):
- h = histogram[layer:layer+256]
- if ignore is not None:
- # get rid of outliers
- try:
- h[ignore] = 0
- except TypeError:
- # assume sequence
- for ix in ignore:
- h[ix] = 0
- if cutoff:
- # cut off pixels from both ends of the histogram
- # get number of pixels
- n = 0
- for ix in range(256):
- n = n + h[ix]
- # remove cutoff% pixels from the low end
- cut = n * cutoff / 100
- for lo in range(256):
- if cut > h[lo]:
- cut = cut - h[lo]
- h[lo] = 0
- else:
- h[lo] = h[lo] - cut
- cut = 0
- if cut <= 0:
- break
- # remove cutoff% samples from the hi end
- cut = n * cutoff / 100
- for hi in range(255, -1, -1):
- if cut > h[hi]:
- cut = cut - h[hi]
- h[hi] = 0
- else:
- h[hi] = h[hi] - cut
- cut = 0
- if cut <= 0:
- break
- # find lowest/highest samples after preprocessing
- for lo in range(256):
- if h[lo]:
- break
- for hi in range(255, -1, -1):
- if h[hi]:
- break
- if hi <= lo:
- # don't bother
- lut.extend(range(256))
- else:
- scale = 255.0 / (hi - lo)
- offset = -lo * scale
- for ix in range(256):
- ix = int(ix * scale + offset)
- if ix < 0:
- ix = 0
- elif ix > 255:
- ix = 255
- lut.append(ix)
- return _lut(image, lut)
-
-##
-# Colorize grayscale image. The <i>black</i> and <i>white</i>
-# arguments should be RGB tuples; this function calculates a colour
-# wedge mapping all black pixels in the source image to the first
-# colour, and all white pixels to the second colour.
-#
-# @param image The image to colourize.
-# @param black The colour to use for black input pixels.
-# @param white The colour to use for white input pixels.
-# @return An image.
-
-def colorize(image, black, white):
- "Colorize a grayscale image"
- assert image.mode == "L"
- black = _color(black, "RGB")
- white = _color(white, "RGB")
- red = []; green = []; blue = []
- for i in range(256):
- red.append(black[0]+i*(white[0]-black[0])/255)
- green.append(black[1]+i*(white[1]-black[1])/255)
- blue.append(black[2]+i*(white[2]-black[2])/255)
- image = image.convert("RGB")
- return _lut(image, red + green + blue)
-
-##
-# Remove border from image. The same amount of pixels are removed
-# from all four sides. This function works on all image modes.
-#
-# @param image The image to crop.
-# @param border The number of pixels to remove.
-# @return An image.
-# @see Image#Image.crop
-
-def crop(image, border=0):
- "Crop border off image"
- left, top, right, bottom = _border(border)
- return image.crop(
- (left, top, image.size[0]-right, image.size[1]-bottom)
- )
-
-##
-# Deform the image.
-#
-# @param image The image to deform.
-# @param deformer A deformer object. Any object that implements a
-# <b>getmesh</b> method can be used.
-# @param resample What resampling filter to use.
-# @return An image.
-
-def deform(image, deformer, resample=Image.BILINEAR):
- "Deform image using the given deformer"
- return image.transform(
- image.size, Image.MESH, deformer.getmesh(image), resample
- )
-
-##
-# Equalize the image histogram. This function applies a non-linear
-# mapping to the input image, in order to create a uniform
-# distribution of grayscale values in the output image.
-#
-# @param image The image to equalize.
-# @param mask An optional mask. If given, only the pixels selected by
-# the mask are included in the analysis.
-# @return An image.
-
-def equalize(image, mask=None):
- "Equalize image histogram"
- if image.mode == "P":
- image = image.convert("RGB")
- h = image.histogram(mask)
- lut = []
- for b in range(0, len(h), 256):
- histo = filter(None, h[b:b+256])
- if len(histo) <= 1:
- lut.extend(range(256))
- else:
- step = (reduce(operator.add, histo) - histo[-1]) / 255
- if not step:
- lut.extend(range(256))
- else:
- n = step / 2
- for i in range(256):
- lut.append(n / step)
- n = n + h[i+b]
- return _lut(image, lut)
-
-##
-# Add border to the image
-#
-# @param image The image to expand.
-# @param border Border width, in pixels.
-# @param fill Pixel fill value (a colour value). Default is 0 (black).
-# @return An image.
-
-def expand(image, border=0, fill=0):
- "Add border to image"
- left, top, right, bottom = _border(border)
- width = left + image.size[0] + right
- height = top + image.size[1] + bottom
- out = Image.new(image.mode, (width, height), _color(fill, image.mode))
- out.paste(image, (left, top))
- return out
-
-##
-# Returns a sized and cropped version of the image, cropped to the
-# requested aspect ratio and size.
-# <p>
-# The <b>fit</b> function was contributed by Kevin Cazabon.
-#
-# @param size The requested output size in pixels, given as a
-# (width, height) tuple.
-# @param method What resampling method to use. Default is Image.NEAREST.
-# @param bleed Remove a border around the outside of the image (from all
-# four edges. The value is a decimal percentage (use 0.01 for one
-# percent). The default value is 0 (no border).
-# @param centering Control the cropping position. Use (0.5, 0.5) for
-# center cropping (e.g. if cropping the width, take 50% off of the
-# left side, and therefore 50% off the right side). (0.0, 0.0)
-# will crop from the top left corner (i.e. if cropping the width,
-# take all of the crop off of the right side, and if cropping the
-# height, take all of it off the bottom). (1.0, 0.0) will crop
-# from the bottom left corner, etc. (i.e. if cropping the width,
-# take all of the crop off the left side, and if cropping the height
-# take none from the top, and therefore all off the bottom).
-# @return An image.
-
-def fit(image, size, method=Image.NEAREST, bleed=0.0, centering=(0.5, 0.5)):
- """
- This method returns a sized and cropped version of the image,
- cropped to the aspect ratio and size that you request.
- """
-
- # by Kevin Cazabon, Feb 17/2000
- # kevin@cazabon.com
- # http://www.cazabon.com
-
- # ensure inputs are valid
- if type(centering) != type([]):
- centering = [centering[0], centering[1]]
-
- if centering[0] > 1.0 or centering[0] < 0.0:
- centering [0] = 0.50
- if centering[1] > 1.0 or centering[1] < 0.0:
- centering[1] = 0.50
-
- if bleed > 0.49999 or bleed < 0.0:
- bleed = 0.0
-
- # calculate the area to use for resizing and cropping, subtracting
- # the 'bleed' around the edges
-
- # number of pixels to trim off on Top and Bottom, Left and Right
- bleedPixels = (
- int((float(bleed) * float(image.size[0])) + 0.5),
- int((float(bleed) * float(image.size[1])) + 0.5)
- )
-
- liveArea = (
- bleedPixels[0], bleedPixels[1], image.size[0] - bleedPixels[0] - 1,
- image.size[1] - bleedPixels[1] - 1
- )
-
- liveSize = (liveArea[2] - liveArea[0], liveArea[3] - liveArea[1])
-
- # calculate the aspect ratio of the liveArea
- liveAreaAspectRatio = float(liveSize[0])/float(liveSize[1])
-
- # calculate the aspect ratio of the output image
- aspectRatio = float(size[0]) / float(size[1])
-
- # figure out if the sides or top/bottom will be cropped off
- if liveAreaAspectRatio >= aspectRatio:
- # liveArea is wider than what's needed, crop the sides
- cropWidth = int((aspectRatio * float(liveSize[1])) + 0.5)
- cropHeight = liveSize[1]
- else:
- # liveArea is taller than what's needed, crop the top and bottom
- cropWidth = liveSize[0]
- cropHeight = int((float(liveSize[0])/aspectRatio) + 0.5)
-
- # make the crop
- leftSide = int(liveArea[0] + (float(liveSize[0]-cropWidth) * centering[0]))
- if leftSide < 0:
- leftSide = 0
- topSide = int(liveArea[1] + (float(liveSize[1]-cropHeight) * centering[1]))
- if topSide < 0:
- topSide = 0
-
- out = image.crop(
- (leftSide, topSide, leftSide + cropWidth, topSide + cropHeight)
- )
-
- # resize the image and return it
- return out.resize(size, method)
-
-##
-# Flip the image vertically (top to bottom).
-#
-# @param image The image to flip.
-# @return An image.
-
-def flip(image):
- "Flip image vertically"
- return image.transpose(Image.FLIP_TOP_BOTTOM)
-
-##
-# Convert the image to grayscale.
-#
-# @param image The image to convert.
-# @return An image.
-
-def grayscale(image):
- "Convert to grayscale"
- return image.convert("L")
-
-##
-# Invert (negate) the image.
-#
-# @param image The image to invert.
-# @return An image.
-
-def invert(image):
- "Invert image (negate)"
- lut = []
- for i in range(256):
- lut.append(255-i)
- return _lut(image, lut)
-
-##
-# Flip image horizontally (left to right).
-#
-# @param image The image to mirror.
-# @return An image.
-
-def mirror(image):
- "Flip image horizontally"
- return image.transpose(Image.FLIP_LEFT_RIGHT)
-
-##
-# Reduce the number of bits for each colour channel.
-#
-# @param image The image to posterize.
-# @param bits The number of bits to keep for each channel (1-8).
-# @return An image.
-
-def posterize(image, bits):
- "Reduce the number of bits per color channel"
- lut = []
- mask = ~(2**(8-bits)-1)
- for i in range(256):
- lut.append(i & mask)
- return _lut(image, lut)
-
-##
-# Invert all pixel values above a threshold.
-#
-# @param image The image to posterize.
-# @param threshold All pixels above this greyscale level are inverted.
-# @return An image.
-
-def solarize(image, threshold=128):
- "Invert all values above threshold"
- lut = []
- for i in range(256):
- if i < threshold:
- lut.append(i)
- else:
- lut.append(255-i)
- return _lut(image, lut)