imagemagick-0.0.1: examples/modulate.hs
{-# LANGUAGE OverloadedStrings #-}
{-
From: http://www.imagemagick.org/discourse-server/viewtopic.php?f=1&t=12640
Read the logo: image and use PixelIterators to produce two new images.
Convert the image to the HSB and HSL colourspaces, cut the Lightness/Brightness
by half and then write the images as logo_hsb.jpg and logo_hsl.jpg
Note the colour distortion in the HSL result whereas the HSB image is what
we'd expect to see when reducing an image's brightness by 50%.
As with my other examples, there is no error checking in this code.
If you adapt this to your own use, you should add error checking to ensure
that, for example, MagickReadImage succeeds and that the width and height
of the image in mw are reasonable values.
-}
import Control.Monad.IO.Class
import Control.Monad
import qualified Data.Vector.Storable as V
import Graphics.ImageMagick.MagickWand
main = withMagickWandGenesis $ do
(_,mw) <- magickWand
mw `readImage` "logo:"
width <- getImageWidth mw
height <- getImageHeight mw
(_,mwl) <- magickWand
(_,mwb) <- magickWand
p <- pixelWand
p `setColor` "none"
-- Set the hsl and hsb images to the same size as the input image
newImage mwl width height p
newImage mwb width height p
-- Even though we won't be reading these images they must be initialized
-- to something TODO: fails to work
-- readImage mwl "xs:none"
-- readImage mwb "xs:none"
-- Create iterators for each image
(_,imw) <- pixelIterator mw
(_,imwl) <- pixelIterator mwl
(_,imwb) <- pixelIterator mwb
it1 <- pixelIterateList imw
it2 <- pixelIterateList imwl
it3 <- pixelIterateList imwb
mapM_ (action imwl imwb) $ zip3 it1 it2 it3
-- write the results
mwb `writeImage` (Just "logo_hsb.jpg")
mwl `writeImage` (Just "logo_hsl.jpg")
where
action imwl imwb (pmw, pmwl, pmwb) = do
V.zipWithM_ inner1 pmw pmwb
V.zipWithM_ inner2 pmw pmwl
-- Sync writes the pixels back to the magick wands
pixelSyncIterator imwl
pixelSyncIterator imwb
inner1 xmw xmwb = localGenesis $ do
-- Get the RGB quanta from the source image
qr <- getRedQuantum xmw
qg <- getGreenQuantum xmw
qb <- getBlueQuantum xmw
-- Convert the source quanta to HSB
(bh,bs,bb) <- convertRGBToHSB qr qg qb
(qr1,qg1,qb1) <- convertHSBToRGB bh bs (0.5*bb)
-- Set the pixel in the HSB output image
xmwb `setRedQuantum` qr1
xmwb `setGreenQuantum` qg1
xmwb `setBlueQuantum` qb1
inner2 xmw xmwl = localGenesis $ do
qr <- getRedQuantum xmw
qg <- getGreenQuantum xmw
qb <- getBlueQuantum xmw
-- Convert the source quanta to HSL
(lh,ls,ll) <- convertRGBToHSL qr qg qb
(qr2,qg2,qb2) <- convertHSLToRGB lh ls (ll*0.5)
-- Set the pixel in the HSL output image
xmwl `setRedQuantum` qr2
xmwl `setGreenQuantum` qg2
xmwl `setBlueQuantum` qb2
zipWith3M_ f a b c = V.zipWithM_ f (V.zipWith g a b) c
where g a b = (a,b)
f' f (a,b) c = f a b c