Haskell Threepenny Gui:在特定点从Canvas读取颜色?

时间:2015-02-22 13:43:24

标签: haskell canvas threepenny-gui

有没有办法读取画布特定点的颜色?

类似的东西:

getColor :: Canvas -> Point -> Color

我在Graphics.UI.Threepenny.Canvas检查了文档,但找不到任何功能。也许我只是没有看到它,因为我使用Haskell的时间并不长。

如果您有任何提示,请告诉我。

提前多多感谢, 克莱姆

编辑:感谢Heinrich Apfelmus的回答,我能够编写一个有效的解决方案,并希望在有人需要相同功能的情况下分享它。当然,如果您使用它并进行调整,请随意分享:)

import qualified Graphics.UI.Threepenny as UI
import Graphics.UI.Threepenny.Core
import Codec.Picture.Types

-- to UI (PixelRGB8) is also possible just change from fst to snd after the return
getCanvCol :: UI.Canvas -> UI.Point -> UI (UI.Color) 
getCanvCol canvas (x,y) = do  
-- str returns a string with comma separated values i.e. "255,0,255"  
str <- callFunction $ ffi ("(%1.getContext('2d').getImageData(%2,%3,1,1).data[0])+\
                            \\",\"+(%1.getContext('2d').getImageData(%2,%3,1,1).data[1])+\
                            \\",\"+(%1.getContext('2d').getImageData(%2,%3,1,1).data[2])") 
                            canvas x y
  return $ fst $ tripleToCol $ lsToRGB $ wordsWhen (==',') str
   where
   -- could also use splitOn
   wordsWhen     :: (Char -> Bool) -> String -> [String]
   wordsWhen p s =  case dropWhile p s of
                         "" -> []
                         s' -> w : wordsWhen p s''
                               where (w, s'') = break p s'
   -- take a list of strings and make a triple of ints 
   lsToRGB :: [String] -> (Int,Int,Int)
   lsToRGB (a:b:c:xs) = (read a, read b, read c)
   lsToRGB _          = (0,0,0) 
   -- make a triple of Int to Color needed
   tripleToCol :: (Int,Int,Int) -> (UI.Color, PixelRGB8)
   tripleToCol (r,g,b) = ((UI.RGB r g b),(PixelRGB8 r' g' b'))
     where (r',g',b') = (fromIntegral r,fromIntegral g,fromIntegral b)

1 个答案:

答案 0 :(得分:1)

(作者在这里)

从threepenny-gui-0.5.0.0开始,目前还没有可以执行此操作的预定义函数。但是,您可以使用附带的JavaScript FFI来调用返回所需值的JavaScript函数。例如,以下是drawImage函数的源代码:

drawImage :: Element -> Vector -> Canvas -> UI ()
drawImage image (x,y) canvas =
    runFunction $ ffi "%1.getContext('2d').drawImage(%2,%3,%4)" canvas image x y

ffi函数允许您调用任意JavaScript函数。唯一的麻烦是您必须将结果封送到类型Color;目前,只支持IntString等几种类型作为返回值。看一下示例的源代码。