Index of /archives/graphics/ImageMagick/python
Name Last modified Size Description
Parent Directory -
README.txt 2014-08-13 20:14 12K
releases/ 2019-10-14 07:25 -
PythonMagick-0.9.19.tar.bz2 2019-11-23 09:53 329K
PythonMagick-0.9.19.tar.gz 2019-11-23 09:53 422K
PythonMagick-0.9.19.tar.lz 2019-11-23 09:54 265K
PythonMagick-0.9.19.tar.xz 2019-11-23 09:54 266K
PythonMagick-0.9.19.zip 2019-11-23 09:54 509K
PythonMagick-0.9.19.tar.bz2.asc 2019-11-23 09:54 836
PythonMagick-0.9.19.tar.gz.asc 2019-11-23 09:54 836
PythonMagick-0.9.19.tar.lz.asc 2019-11-23 09:54 836
PythonMagick-0.9.19.tar.xz.asc 2019-11-23 09:54 836
PythonMagick-0.9.19.zip.asc 2019-11-23 09:54 836
digest.rdf 2019-11-23 09:54 2.3K
catali@gentoo.org>ozaToth contributed an automake/autoconf build.
Included a license file to keep Debian/Redhat/etc. happy.
Fabbro <bicatali@gento...> contributed patch to correctly link with _LIBADD
and not _LDFLAGS in Makefile.am. It also uses the variable BOOST_PYTHON_LIB
instead of BOOST_PYTHON_LIBS for linking.
Find the documentation for PythonMagickWand at
http://public.procoders.net/PythonMagickWand/docs/html/index.html.
* * *
If you get
... matching function for call to 'registry_lookup(const volatile void (*)())
when compiling PythonMagick, upgrade your Boost Python to 1.34. See
http://www.boost.org/more/getting_started.html#CVS and checkout with
cvs -z3 -d:pserver:anonymous@boost.cvs.sourceforge.net:/cvsroot/boost
checkout -r RC_1_34_0 boost
Thanks to Nigel Rowe for this update.
* * *
Here is a short PythonMagick example to try:
from PythonMagick import *
img=Image('30x30','red')
img.write('test1.png')
data=file('test1.png','rb').read()
img=Image(Blob(data))
img.write('test2.png')
print "now you should have two png files"
Prerequisites:
* boost 1.32
* python 2.3 or newer
* ImageMagick 6.8.9-6+ (has to be build as shared library)
* Scons
Tutorial for doing basic operations
Load an image from disk
import PythonMagick
img = PythonMagick.Image("test.tif")
Display
Here is a wxPython solution for displaying an image. Convert an PythonMagick
image to wxImage, then you display using standard method. Here's how you
convert.
def convertMGtoWX(self, magickimage):
img = PythonMagick.Image(magickimage) # make copy
img.depth = 8 # change depth only for display
img.magick = "RGB"
data = img.data
wximg = wx.wxEmptyImage(img.columns(), img.rows())
wximg.SetData(data)
return wximg
A complete short program
This short program uses wxPython GUI, loads an image, displays the image, and
does a simple image processing operation (threshold).
from wxPython import wx
import PythonMagick
ID_FILE_OPEN = wx.wxNewId()
ID_FILE_EXIT = wx.wxNewId()
ID_THRESHOLD = wx.wxNewId()
class ImagePanel(wx.wxPanel):
def __init__(self, parent, id):
wx.wxPanel.__init__(self, parent, id)
self.image = None # wxPython image
wx.EVT_PAINT(self, self.OnPaint)
def display(self, magickimage):
self.image = self.convertMGtoWX(magickimage)
self.Refresh(True)
def OnPaint(self, evt):
dc = wx.wxPaintDC(self)
if self.image:
dc.DrawBitmap(self.image.ConvertToBitmap(), 0,0)
def convertMGtoWX(self, magickimage):
img = PythonMagick.Image(magickimage) # make copy
img.depth = 8 # change depth only for display
img.magick = "RGB"
data = img.data
wximg = wx.wxEmptyImage(img.columns(), img.rows())
wximg.SetData(data)
return wximg
class mtFrame(wx.wxFrame):
def __init__(self, parent, ID, title):
wx.wxFrame.__init__(self, parent, ID, title, wx.wxDefaultPosition,
wx.wxSize(500, 400))
self.iPanel = ImagePanel(self, -1)
self.im = None # Magick image
## Construct "File" menu
self.menuBar = wx.wxMenuBar()
self.menuFile = wx.wxMenu()
self.menuFile.Append(ID_FILE_OPEN, "&Open image","")
wx.EVT_MENU(self, ID_FILE_OPEN, self.OnOpen)
self.menuFile.AppendSeparator()
self.menuFile.Append(ID_FILE_EXIT, "E&xit", "")
wx.EVT_MENU(self, ID_FILE_EXIT, self.OnExit)
self.menuBar.Append(self.menuFile, "&File");
## Construct "Process" menu
self.menuProcess = wx.wxMenu()
self.menuProcess.Append(ID_THRESHOLD, "Threshold", "")
wx.EVT_MENU(self, ID_THRESHOLD, self.OnThreshold)
self.menuBar.Append(self.menuProcess, "&Process")
self.SetMenuBar(self.menuBar)
def OnOpen(self, event):
fd = wx.wxFileDialog(self, "Open Image", "", "", "*.*", wx.wxOPEN)
if fd.ShowModal() == wx.wxID_OK:
self.loadImage(fd.GetPath())
fd.Destroy()
def loadImage(self, path):
path = str(path)
try:
self.im = PythonMagick.Image(path)
self.iPanel.display(self.im)
except IOError:
print "can't open the file"
##-------------- Process ------------------------
def OnThreshold(self, event):
self.im = self.Threshold(self.im, 0.5)
self.iPanel.display(self.im)
#self.im.write('d:/threshold.tif')
def Threshold(self, image, threshold):
"""
Threshold image. Input threshold is normalized (0-1.0)
"""
img = PythonMagick.Image(image) # copy
img.threshold(threshold *65535.0)
return img
##-----------------------------------------------
def OnCloseWindow(self, event):
self.Destroy()
def OnExit(self, event):
self.Close(True)
#---------------------------------------------------------------------------
class mtApp(wx.wxApp):
def OnInit(self):
frame = mtFrame(wx.NULL, -1, "MagickSimple1")
frame.Show(True)
self.SetTopWindow(frame)
return True
app = mtApp(0)
app.MainLoop()
-Bob Klimek 9-23-03
HOW TO
CONVERT IMAGE
Load an image from disk
import PythonMagick
img = PythonMagick.Image("d:/test.tif")
Convert Magick image to wxPython image
def convertMGtoWX(self, magickimage):
img = PythonMagick.Image(magickimage) # make copy
img.depth = 8 # change depth only for display
img.magick = "RGB"
data = img.data
wximg = wx.wxEmptyImage(img.columns(), img.rows())
wximg.SetData(data)
return wximg
Convert Magick image to PIL (Python Imageing Library) image
def convertMGtoPIL(magickimage):
'works with grayscale and color'
img = PythonMagick.Image(magickimage) # make copy
img.depth = 8 # this takes 0.04 sec. for 640x480 image
img.magick = "RGB"
data = img.data
w, h = img.columns(), img.rows()
# convert string array to an RGB Pil image
pilimage = Image.fromstring('RGB', (w, h), data)
return pilimage
Convert PIL image to Magick image
def convertPILtoMG(pilimage):
'returns RGB image'
if pilimage == None:
return None
if pilimage.mode == 'L':
pilimage = pilimage.convert("RGB")
size = "%sx%s" % (pilimage.size[0], pilimage.size[1])
data = pilimage.tostring('raw','RGB')
mdata = PythonMagick.Blob(data)
img = PythonMagick.Image(mdata, size, 8, 'RGB')
return img
Convert Magick image to list
def convertMagickImageToList(image):
'converts a Magick image to a list of integers as RGBRGBRGB...'
img = PythonMagick.Image(image) # make copy
img.depth = 8
img.magick = "RGB"
data = img.data
aList = map(ord, data)
return aList
Convert a list to Magick image
def convertListToMagickImage(rgbList , w, h):
'converts a list of integers (RGBRGB...) to a Magick image'
data = ''.join(map(chr, rgbList)) # convert to string
size = "%sx%s" % (w, h)
mdata = PythonMagick.Blob(data)
img = PythonMagick.Image(mdata, size, 8, 'RGB')
return img
IMAGE PROCESSING
Note: A personal preference: In most of the below functions, I make a copy of
the input image before proceeding with the operation. This de-couples the
input and output image. Doing it this way takes slightly more time (the copy
takes 0.00002 sec. on a 1.2 GHz PC) but nothing you'll notice.
All of the following image processing operation assume that PythonMagick is
imported as such:
import PythonMagick
Threshold
def Threshold(image, t):
"""
Threshold image. Input threshold value (t) should by normalized (0-1.0)
"""
img = PythonMagick.Image(image) # copy
img.threshold(t *65535.0)
return img
Image Subtraction
def subImage(img1, img2):
'subtract (img1 - img2)'
size1 = "%sx%s" % (img1.columns(), img1.rows())
size2 = "%sx%s" % (img2.columns(), img2.rows())
if size1 != size2:
print 'image1 and image2 are different sizes'
return None
img2.composite(img1, 0, 0,
PythonMagick.CompositeOperator.MinusCompositeOp)
return img2
Resize Image
def Resize(image, w, h):
img = PythonMagick.Image(image) # copy
s = "!%sx%s" % (w, h)
img.sample(s)
return img
Extract a Color Plane (Channel) from a RGB image
def ExtractPlane(image, colorPlane):
if str(image.type) == 'TrueColorType':
if colorPlane == 0:
image.channel(PythonMagick.ChannelType.RedChannel)
elif colorPlane == 1:
image.channel(PythonMagick.ChannelType.GreenChannel)
elif colorPlane == 2:
image.channel(PythonMagick.ChannelType.BlueChannel)
elif colorPlane == 3:
image.type = PythonMagick.ImageType.GrayscaleType # converts to
grayscale
image.type = PythonMagick.ImageType.TrueColorType # convert to RGB
return image
else:
return image
Crop out (extract) a sub-image
def Crop(image, x1, y1, w, h):
img = PythonMagick.Image(image) # make a copy
rect = "%sx%s+%s+%s" % (w, h, x1, y1)
img.crop(rect)
return img
Paste a sub-image into a larger image
def Paste(destImage, sourceImage, x1, y1):
op = PythonMagick.CompositeOperator.OverCompositeOp
# a kluge to prevent changing to grayscale - doesn't always happen
type = destImage.type
destImage.composite(sourceImage, x1, y1, op)
destImage.type = type
return destImage
Get pixel value as 16-bit integer (for Q:16 version)
def getPixel(image, x, y):
'returns 16-bit integers (0-65535)'
color = image.pixelColor(x, y)
return (color.redQuantum, color.greenQuantum, color.blueQuantum)
Get pixel value as a normalized float (0.0 - 1.0)
def getPixelNorm(image, x, y):
'returns normalized floats (0.0 - 1.0)'
color = image.pixelColor(x, y)
rgb = PythonMagick.ColorRGB(color)
return (rgb.red, rgb.green, rgb.blue)
Set pixel
def setPixel(image, x, y, rgb):
color = PythonMagick.ColorRGB(rgb[0], rgb[1], rgb[2])
#~ red = PythonMagick.ColorGray(0.6)
image.pixelColor(x, y, color)
Filters - some but by no means all of them.
def Filter(image, filterType):
img = PythonMagick.Image(image) # copy
if filterType == 'smooth':
img.blur(1.0, 0.5)
return img
elif filterType == 'smoothmore':
return Blur(img, 2.0, 0.9)
elif filterType == 'median':
return MedianFilter(img, 1.0)
elif filterType == 'minimizenoise':
return Enhance(img)
elif filterType == 'sharpen':
return Sharpen(img, 2.0, 1.0)
elif filterType == 'unsharpmask':
return UnsharpMask(img, 2.0, 1.0, 0.85, 0.0)
elif filterType == 'edgedetect':
return Edge(img, 1.0)
elif filterType == 'edgedetectmore':
return Edge(img, 2.0)
elif filterType == 'despeckle':
return Despeckle(img)
elif filterType == 'invert':
return Invert(img)
else:
return img
def Sharpen(image, radius=1.0, sigma=0.5):
img = PythonMagick.Image(image) # copy
img.sharpen(radius, sigma)
return img
def Blur(image, radius=1.0, sigma=0.5):
"""Blur image. The radius parameter specifies the radius of
the Gaussian, in pixels, not counting the center pixel.
The sigma parameter specifies the standard deviation of
the Laplacian, in pixels.
"""
img = PythonMagick.Image(image) # copy
img.blur(radius, sigma)
return img
def MedianFilter(image, radius=1.0):
"""Filter image by replacing each pixel component with the median color
in a circular neighborhood.
"""
img = PythonMagick.Image(image) # copy
img.medianFilter(radius)
return img
def Enhance(image):
"""Enhance image (minimize noise). Very slight effect. Its sort of like
smoothing without degrading the edges. Takes out some texture.
"""
img = PythonMagick.Image(image) # copy
img.enhance()
return img
def Edge(image, radius=1.0):
"""Edge image (hilight edges in image). The radius is the radius of
the pixel neighborhood. Specify a radius of zero for automatic
radius selection.
"""
img = PythonMagick.Image(image) # copy
img.edge(radius)
return img
def Despeckle(image):
"""
Reduce speckle noise. This filter works quite nice with minimal smoothing
of edges.
"""
img = PythonMagick.Image(image) # copy
img.despeckle()
return img
def Invert(img, grayscale=0):
'inverse video'
img.negate(grayscale)
return img
-Bob Klimek 9-23-03