Hi, I would like to write an (Array (Int,Int) Int) to a file in some kind of image format. I implemented (quick and very dirty) XBM output, but it would be nice to have some colors, and anyway, I can't seem to show the XBMs as grayscale. I've searched around a bit, but the only stuff I could find was defunct references to GIF writer, Jeroen Fokker's JPEG stuff (which may still work, but I don't want JPEG compression), and the PPM support in Andrew Cooke's Pancito. Ripping out the latter currently seems to be the best bet, not sure how closely tied it is to the rest of the code. So, before I start, does anybody know any other libraries or programs that could be used? -kzm -- If I haven't seen further, it is by standing in the footprints of giants
Ketil Malde wrote:
I would like to write an (Array (Int,Int) Int) to a file in some kind of image format. I implemented (quick and very dirty) XBM output, [snip] So, before I start, does anybody know any other libraries or programs that could be used?
Hi Ketil, You could use wxHaskell to write (and read) files in many different formats (like png, bmp, tif, jpg, ico, xbm, etc). If you build from CVS, you will find the function "imageGetPixelArray" and "imageCreateFromPixelArray" in the "Graphics.UI.WXCore.Image" module. If you use the latest packaged 0.8 release, you will have to do with the lower level "pixelBufferSet/GetPixel" functions. Note that if you do not call "start", there is no GUI stuff involved and you can just use the image conversion functions of wxHaskell in a console application. Not a minimal solution, but maybe good enough for your purposes. All the best, Daan. ps. In a recent mail to shelarcy in the wxHaskell users mail archive you can find a program that shows how to use the lower level pixelBuffer functions in wxHaskell 0.8: <http://sourceforge.net/mailarchive/message.php?msg_id=9127088>
On Thu, Aug 05, 2004 at 02:07:02PM +0200, Ketil Malde wrote:
Hi,
I would like to write an (Array (Int,Int) Int) to a file in some kind of image format. I implemented (quick and very dirty) XBM output, but it would be nice to have some colors, and anyway, I can't seem to show the XBMs as grayscale.
I've searched around a bit, but the only stuff I could find was defunct references to GIF writer, Jeroen Fokker's JPEG stuff (which may still work, but I don't want JPEG compression), and the PPM support in Andrew Cooke's Pancito.
Ripping out the latter currently seems to be the best bet, not sure how closely tied it is to the rest of the code. So, before I start, does anybody know any other libraries or programs that could be used?
I once wrote a mini PPM read/write library for a markov-like-chains-in-images fun project. with the following basic API: type Image = Matrix Color withColor :: ((Int, Int, Int) -> (Int, Int, Int)) -> Color -> Color -- The Int-argument gives the maximum number for a color value: usually 255 readPPM :: String -> (Int, Image) showPPM :: Int -> Image -> String Though it's quite horribly slow it does work: Prelude PPM Matrix> (maxColor, img) <- readPPM `fmap` readFile "/tmp/foo.ppm" Prelude PPM Matrix> let img' = amap (withColor $ \(r,g,b) -> (r,g,b)) img Prelude PPM Matrix> writeFile "/tmp/bar.ppm" $ showPPM maxColor img' bar.ppm == foo.ppm afterwards. The Matrix module merely reexports some IArray instance. (DiffUArray, in my program) Happy hacking, Remi -- Nobody can be exactly like me. Even I have trouble doing it.
I think wxWindows is something I'll eventually have to look into, but it seems a bit heavy for my purposes at the moment. I discovered that although XPM accepts values in the range 0x00..0xff, it is still monochrome. XGM (plain, that is, not raw) is approximately the same format, but displays the way I wanted. So I ended up using: mkpgm :: Array (Int,Int) Int -> String mkpgm cm = header ++ "\n" ++ image where header = unwords ["P2",show width,show heigth,show maxval] image = unlines $ map show $ elems cm (width,heigth) = snd $ bounds cm maxval = maximum (elems cm) Not *very* beautiful, but seems to do the job for my stuff. I'll try the PPM library if I need something a tad more fancy - like colors :-) Thanks for the suggestions! -ketil -- If I haven't seen further, it is by standing in the footprints of giants
another option is to use something like fly: http://martin.gleeson.com/fly/ either through the text interface, or to link in. i currently do the formet to create small graphs, pictures, etc. not exceedingly efficient, but i don't know exactly your needs. On Thu, 5 Aug 2004, Ketil Malde wrote:
I think wxWindows is something I'll eventually have to look into, but it seems a bit heavy for my purposes at the moment.
I discovered that although XPM accepts values in the range 0x00..0xff, it is still monochrome. XGM (plain, that is, not raw) is approximately the same format, but displays the way I wanted. So I ended up using:
mkpgm :: Array (Int,Int) Int -> String mkpgm cm = header ++ "\n" ++ image where header = unwords ["P2",show width,show heigth,show maxval] image = unlines $ map show $ elems cm (width,heigth) = snd $ bounds cm maxval = maximum (elems cm)
Not *very* beautiful, but seems to do the job for my stuff. I'll try the PPM library if I need something a tad more fancy - like colors :-)
Thanks for the suggestions!
-ketil
-- Hal Daume III | hdaume@isi.edu "Arrest this man, he talks in maths." | www.isi.edu/~hdaume
Oops. Lest anybody should copy it blindly: mkpgm :: Array (Int,Int) Int -> String mkpgm cm = header ++ "\n" ++ image where header = unwords ["P2",show width,show heigth,show maxval] image = unlines $ map show $ elems cm - (width,heigth) = snd $ bounds cm + (heigth,width) = snd $ bounds cm maxval = maximum (elems cm) -kzm -- If I haven't seen further, it is by standing in the footprints of giants
Ketil Malde wrote:
I discovered that although XPM accepts values in the range 0x00..0xff, it is still monochrome. XGM (plain, that is, not raw) is approximately the same format, but displays the way I wanted. So I ended up using:
mkpgm :: Array (Int,Int) Int -> String mkpgm cm = header ++ "\n" ++ image where header = unwords ["P2",show width,show heigth,show maxval]
This may not work for many programs which read PGM files. The header is usually split into multiple lines, e.g. P2 256 256 255 Some programs may accept arbitrary whitespace between tokens, but others may insist upon newlines, e.g.: mkpgm cm = header ++ image where header = unlines $ map unwords [["P2"],[show width, show height],[show maxval]] Also:
(width,heigth) = snd $ bounds cm
This assumes that "fst $ bounds cm == (1,1)".
Not *very* beautiful, but seems to do the job for my stuff. I'll try the PPM library if I need something a tad more fancy - like colors :-)
Writing PPM is only marginally more complex, e.g.: mkppm :: Array (Int,Int) (Int, Int, Int) -> String mkppm cm = header ++ image where header = unlines $ map unwords [["P3"],[show width, show height],[show maxval]] image = unlines $ map showRGB $ elems cm width = x1 - x0 + 1 height = y1 - y0 + 1 ((x0,y0),(x1,y1)) = bounds cm maxval = maximum $ concatMap unRGB (elems cm) showRGB (r,g,b) = unwords [show r, show g, show b] unRGB (r,g,b) = [r,g,b] -- Glynn Clements <glynn.clements@virgin.net>
Hi,
I would like to write an (Array (Int,Int) Int) to a file in some kind of image format. I implemented (quick and very dirty) XBM output, but it would be nice to have some colors, and anyway, I can't seem to show the XBMs as grayscale.
Just write a "plain format" PPM by hand - if you want it in a different format, just use the pnm tools to convert. Format is: P3 width height maxval r g b r g b r g b r g b r g b r g b r g b r g b ... where all numbers are decimal, "P3" must be the first two chars, each token must be separated by some whitespace (newline or space, doesn't matter which or how many), and maxval is the maximum value of a component (usually 15 or 255). e.g. P3 4 4 15 0 0 0 0 0 0 0 0 0 15 0 15 0 0 0 0 15 7 0 0 0 0 0 0 0 0 0 0 0 0 0 15 7 0 0 0 15 0 15 0 0 0 0 0 0 0 0 0 Type "man 5 pnm" for more info. Once you have the ppm file, do cjpeg to get jpeg, or ppmtoxpm, ppmtobmp, or whatever else. --KW 8-) --KW 8-)
If you're on a machine where Imlib 2 is installable (unixish), then I have an almost complete binding to Imlib 2 which I threw together quite a while back while learning the FFI: http://optlab.mcmaster.ca/~cgibbard/Imlib2.hs and an example of using it for a very simple image converter at http://optlab.mcmaster.ca/~cgibbard/convert.hs The binding is pretty thin, but Imlib 2 is a fairly nicely structured library already. It's missing all the calls which have anything at all to do with X, and a neat one for scripting filters which I didn't quite know what to do with since it's variadic. If people want to play around with it, make improvements, etc, that would be great. I haven't tested that everything works, but it will quite likely work reasonably well for simple things. - Cale On Thu, 05 Aug 2004 14:07:02 +0200, Ketil Malde <ketil+haskell@ii.uib.no> wrote:
Hi,
I would like to write an (Array (Int,Int) Int) to a file in some kind of image format. I implemented (quick and very dirty) XBM output, but it would be nice to have some colors, and anyway, I can't seem to show the XBMs as grayscale.
I've searched around a bit, but the only stuff I could find was defunct references to GIF writer, Jeroen Fokker's JPEG stuff (which may still work, but I don't want JPEG compression), and the PPM support in Andrew Cooke's Pancito.
Ripping out the latter currently seems to be the best bet, not sure how closely tied it is to the rest of the code. So, before I start, does anybody know any other libraries or programs that could be used?
-kzm -- If I haven't seen further, it is by standing in the footprints of giants _______________________________________________ Haskell mailing list Haskell@haskell.org http://www.haskell.org/mailman/listinfo/haskell
participants (7)
-
Cale Gibbard -
Daan Leijen -
Glynn Clements -
Hal Daume III -
Keith Wansbrough -
Ketil Malde -
Remi Turk