Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What type to use for in-memory image data in Haskell?

Tags:

types

haskell

I'm trying to model a data Photo and wondering what type to use for the image data:

data Photo =
  Photo
  { photoUploaderId :: AccountId
  , photoWidth :: Int
  , photoHeight :: Int
  , photoData :: ByteString
  }

I'm using Data.ByteString here. Are there any better choice?

Background: I'm going to store the image data in a database, and retrieve and send it over a network connection. On inserting the photo into the database for the first time, I may need to manipulate it a bit, like scaling, etc.

like image 550
Xiao Jia Avatar asked Jan 07 '13 08:01

Xiao Jia


2 Answers

If you're going to access arbitrary pixels of photos use an unboxed array. It will give you O(1) indexing and a minimal space overhead. UArray (Int, Int) Word32 should be what you are looking for. Remeber that unboxed arrays are strict. If you're looking for non-strictness use an Array, but keep in mind that values of pixels will be boxed which degrades the performance.

Another types of similar capabilities and worth considering are vectors.

On the other hand, if you are not going to manipulate pixels and you'll treat the image just as a blob, ByteString is a good choice. That's what it was designed for: blobs of binary data.

In summary: manipulate using either Array or Vector, store and transfer as ByteString.

like image 111
Jan Avatar answered Sep 28 '22 10:09

Jan


Generally speaking, UArray is a good choice. It depends on the photo format, how you're going to read the image, and what kind of processing you do with it. I find the Codec.Image.DevIL library to be handy for photo processing. Here's an example converting a JPEG image to PNG.

import Codec.Image.DevIL

main = do
  ilInit
  img <- readImage "test.jpeg"
  writeImage "test.png" img 

The readImage function has this signature.

readImage :: FilePath -> IO (UArray (Int, Int, Int) Word8)

And it returns an RGBA array. Indices are (row,column,color-channel). So IO (UArray (Int, Int, Int) Word8) would be a good choice if you're going to use that library.

like image 23
mhwombat Avatar answered Sep 28 '22 11:09

mhwombat