我正在开发一个应用程序,其中我(到目前为止)发现的处理图像的最佳方法是使用 Graphics.Netpbm 库。我将把许多操作(例如原始文件开发)委托给外部应用程序,我只想要一个非常干净且受支持的格式。
我真的让它工作了。我可以告诉 ufraw-batch “开发”一个原始文件并将结果以 pnm 格式输出到标准输出。Graphics.Netpbm.parsePPM 可以很好地解析图像。然后我需要将其转换为 pixbuf 以显示在 GtkImage 小部件中,虽然我有一个解决方案,但我认为这很恶心。我希望有更好的方法来做到这一点。
阅读这面代码墙时,您可以跳过整个let
声明并理解img_list :: Netpbm.PPM -> [CUChar]
.
display_image :: Graphics.UI.Gtk.Image -> Netpbm.PPM -> IO ()
display_image canvas image_bitmap =
let get_rgb_vector = Netpbm.pixelVectorToList . (\(Netpbm.PpmPixelDataRGB8 v) -> v) . Netpbm.ppmData
vector_to_cuchar_list = map CUChar . concat . map (\(Netpbm.PpmPixelRGB8 r g b) -> r:g:b:[])
img_list = vector_to_cuchar_list . get_rgb_vector
len = length . img_list
width = Netpbm.ppmWidth . Netpbm.ppmHeader
height = Netpbm.ppmHeight . Netpbm.ppmHeader
in do
img_ptr <- mallocBytes (len image_bitmap)
mapM_ (\(b, off) -> pokeByteOff img_ptr off (b :: CUChar)) (zip (img_list image_bitmap) [0,1..])
pb <- pixbufNewFromData img_ptr ColorspaceRgb False 8 (width image_bitmap) (height image_bitmap) ((width image_bitmap) * 3)
imageSetFromPixbuf canvas pb
顶部的函数从许多实用程序开始,以实际获取原始像素数据。它们也很乱,我真的不知道有更好的方法来组织它们。但总的部分在 do 块中。我分配了一个 C 字节数组来存储所有数据。然后我遍历表示图像的 [CUChar],将每个单独的字节插入 C 数组中的正确位置。然后我从该数据创建一个 GtkPixbuf。
呃。有什么更快、更清洁、更安全的方法来做到这一点?
pixbufNewFromData 接受 aPtr CUChar
作为第一个参数,其中带有所有展开的 Netpbm 最终可以为我提供[Word8]
. 所以在我看来,我需要一个干净的函数[Word8] -> Ptr CUChar
。它不必是纯粹的。
我也不介意进行重大更改,但我的数据流总体上是
operation that generates a ByteString of pnm data ---> GtkImage