在Haskell屏幕捕获?(Screen capture in Haskell?)

2019-06-27 01:15发布

是否有可能捕捉到在Windows环境中使用哈斯克尔屏幕(或窗口)? (即,以每隔几分钟左右截图)。 如果是这样,怎么会去这样做(同样,在Haskell,用于Windows环境)?

更多信息:我是一个初学者哈斯克尔。 一个朋友想通过我一起鞭打他的会计师事务所某些程序削减开发成本,但他还是坚持我使用哈斯克尔。 他想要一个工具,这将让他监视不同的Windows XP工作站的桌面。 这也很可能是一个客户端/服务器类型的应用程序。 他只需要监控桌面活动,因此为什么他不希望任何昂贵的管理软件已经在市场上。 我已经通过大量的文件,进行筛分,只得到尽可能寻找wxHaskell,但我无法找到太多的捕捉画面,特别适合Windows环境。

Answer 1:

吉洪提到的方法是正确的。 只是添加一些代码到他上面给出了答案

import Graphics.Win32.Window
import Graphics.Win32.GDI.Bitmap
import Graphics.Win32.GDI.HDC
import Graphics.Win32.GDI.Graphics2D

main = do desktop   <- getDesktopWindow -- Grab the Hwnd of the desktop, GetDC 0, GetDC NULL etc all work too
          hdc       <- getWindowDC (Just desktop) -- Get the dc handle of the desktop
          (x,y,r,b) <- getWindowRect desktop -- Find the size of the desktop so we can know which size the destination bitmap should be
                                             -- (left, top, right, bottom)
          newDC     <- createCompatibleDC (Just hdc) -- Create a new DC to hold the copied image. It should be compatible with the source DC
          let width  = r - x -- Calculate the width
          let height = b - y -- Calculate the Height
          newBmp    <- createCompatibleBitmap hdc width height -- Create a new Bitmap which is compatible with the newly created DC
          selBmp    <- selectBitmap newDC newBmp -- Select the Bitmap into the DC, drawing on the DC now draws on the bitmap as well
          bitBlt newDC 0 0 width height hdc 0 0 sRCCOPY -- use SRCCOPY to copy the desktop DC into the newDC
          createBMPFile "Foo.bmp" newBmp newDC  -- Write out the new Bitmap file to Foo.bmp
          putStrLn "Bitmap image copied" -- Some debug message
          deleteBitmap selBmp -- Cleanup the selected bitmap
          deleteBitmap newBmp -- Cleanup the new bitmap
          deleteDC newDC      -- Cleanup the DC we created.

这只是快速地放在一起,但它节省了一个名为Foo.bmp文件的截图。 PS。 给谁就给谁写的Win32的图书馆,很好地完成:)



Answer 2:

你也可以做到这一点与跨平台的方式GTK 。

那会不会是从使用C做太大的不同: 以与C / GTK截图 。

{-# LANGUAGE OverloadedStrings #-}

import Graphics.UI.Gtk
import System.Environment
import Data.Text as T

main :: IO ()
main = do
    [fileName] <- getArgs
    _ <- initGUI
    Just screen <- screenGetDefault
    window <- screenGetRootWindow screen
    size <- drawableGetSize window
    origin <- drawWindowGetOrigin window
    Just pxbuf <-
        pixbufGetFromDrawable
            window
            ((uncurry . uncurry Rectangle) origin size)
    pixbufSave pxbuf fileName "png" ([] :: [(T.Text, T.Text)])


Answer 3:

您应该能够使用Win32 API来做到这一点。 基于什么是采取与C ++一个窗口的截图在Windows的最佳方式? ,你需要获得该窗口的环境,然后将图像从它使用复制GetWindowDCBitBlt分别。

展望Haskell的Win32 API的文档周围,有一个getWindowDC在功能Graphics.Win32.Window 。 这将返回一个IO HDC 。 有一个bitblt的功能Graphics.Win32.GDI.Graphics2D 。 此函数采用一个HDC一束沿INT S的大概对应于需要在参数C ++ 。

不幸的是,我没有在Windows机器方便,所以我不能写实际的代码。 你必须弄清楚如何自己使用Win32 API函数,这可能是一个有点麻烦。

当你这样做,它会如果它分解成库为大,把它挂在Hackage - 视窗通常不会得到太多的爱在Haskell土地(为我自己显示:P),所以我相信其他的Windows程序员将感激不尽一种简单的方法来采取截图。



文章来源: Screen capture in Haskell?