2015-02-22 5 views
2

Есть ли способ прочитать цвет определенной точки холста?Haskell Threepenny Gui: Чтение цвета с холста в определенном месте?

Что-то вроде:

getColor :: Canvas -> Point -> Color 

Я проверил документацию на Graphics.UI.Threepenny.Canvas, но не смог найти какую-либо функцию для этого. Может быть, я просто этого не видел, потому что я не так долго использовал Haskell.

Если у вас есть какие-либо намеки на меня, пожалуйста, дайте мне знать.

спасибо заранее, Клем

EDIT: Благодаря ответ Генрих 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.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; на данный момент в качестве возвращаемых значений поддерживаются только несколько типов, таких как Int или String. Взгляните на исходный код для примеров.

+0

Большое спасибо за быстрый ответ! Мне удалось заставить его работать (см. EDIT в сообщении выше). Хотя это может быть и не идеально, сейчас это достаточно хорошо для меня :) 3penny-gui действительно потрясающе, спасибо за это. –

+1

Мое удовольствие. :-) Если вы чувствуете себя странно, вы также можете попробовать «Value» в качестве возвращаемого типа для маршала, это объект объекта JavaScript из библиотеки 'aeson'; Я думаю, что у модулей Graphics.UI.Threepenny.Event есть примеры для этого. Но поскольку ваш код работает, его не нужно менять. –

 Смежные вопросы

  • Нет связанных вопросов^_^