views:

896

answers:

3

How do I rotate a JPEG image by 45° and save it back to disk?

+7  A: 

As far as I know, there is no good image manipulation library for Haskell yet.

Better way

You can use hsmagick (bindings to libmagick) to manipulate images.

See TomMD's answer for an example.

Easy way

But if you want to do it from Haskell, this can do the trick (assuming that ImageMagick is available):

import System.Cmd (system)
import System.Environment (getArgs)

main = do
  (original:rotated:_) <- getArgs
  system $ "convert -rotate \"-45\" \"" ++ original ++ "\" \"" ++ rotated ++ "\""

Usage:

runghc rotate.hs original.jpg rotated45.jpg

Hard way

Or you can choose the hard way, and implement rotation algorithm yourself. To read and write almost all image formats in Haskell, you can use Codec.Image.DevIL library. If you do it, it would be kind of you to put this code on Hackage.

jetxee
While there might be no good manipulation library, this is an easy task and he should be able to find a sufficient library on Hackage.
TomMD
Oh, I missed hsmagick. Thanks.
jetxee
+6  A: 

The GD library lets you do this, but the Haskell bindings ( http://hackage.haskell.org/package/gd ) don't include the appropriate function at the moment. One also could either make a feature request to the maintainer, or simply patch it and send it upstream. The Graphics.GD.Internal module (not exported) in fact already has a commented out binding to the appropriate function ( http://hackage.haskell.org/packages/archive/gd/3000.5.0/doc/html/src/Graphics-GD-Internal.html ), so it should be very simple, I imagine, to finish the job (and I'm sure, the work will be appreciated).

sclv
+5  A: 

Look around on Hackage. I know Tim started working on bindings to libmagick, which wasn't enough to stop me from dropping down to generating script-fu for GIMP when I needed image manipulation, but it's enough for you if you're just doing simple things like rotation:

liftM (rotateImage 45) (readImage file) >>= writeImage file2

I see Cale also has an ImLib that appears more feature complete:

loadImageImmediately file >>= contextSetImage >>
createRotatedImage 45 >>= contextSetImage >> saveImage file2

As I said, look around and let us know!

TomMD
Weird. The ImLib binding for saveImage appears to be wrong/not filled in. :-(
sclv
sclv: That's what I thought at first but see the edit - ImLib is stateful (damn IO)
TomMD
aha. contextsetimage! oy vey.
sclv