Index of /archives/graphics/ImageMagick/python

Icon  Name                            Last modified      Size  Description
[PARENTDIR] Parent Directory - [   ] digest.rdf 2019-11-23 09:54 2.3K [   ] PythonMagick-0.9.19.zip.asc 2019-11-23 09:54 836 [   ] PythonMagick-0.9.19.tar.xz.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.gz.asc 2019-11-23 09:54 836 [   ] PythonMagick-0.9.19.tar.bz2.asc 2019-11-23 09:54 836 [   ] PythonMagick-0.9.19.zip 2019-11-23 09:54 509K [   ] PythonMagick-0.9.19.tar.xz 2019-11-23 09:54 266K [   ] PythonMagick-0.9.19.tar.lz 2019-11-23 09:54 265K [   ] PythonMagick-0.9.19.tar.gz 2019-11-23 09:53 422K [   ] PythonMagick-0.9.19.tar.bz2 2019-11-23 09:53 329K [DIR] releases/ 2019-10-14 07:25 - [TXT] README.txt 2014-08-13 20:14 12K
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