首页
学习
活动
专区
圈层
工具
发布

截图
EN

Stack Overflow用户
提问于 2011-09-07 01:47:29
回答 2查看 495关注 0票数 0

我试图让我的程序截图,然后格式化数据的方式,它可以很容易地从我的程序。

到目前为止,我已经提出了以下解决方案:

代码语言:javascript
复制
    /**
    * Creates a screenshot of the entire screen
    * @param img - 2d array containing RGB values of screen pixels.
    */
    void get_screenshot(COLORREF** img, const Rectangle &bounds)
    {
        // get the screen DC
        HDC hdc_screen = GetDC(NULL);
        // memory DC so we don't have to constantly poll the screen DC
        HDC hdc_memory = CreateCompatibleDC(hdc_screen);
        // bitmap handle
        HBITMAP hbitmap = CreateCompatibleBitmap(hdc_screen, bounds.width, bounds.height);
        // select the bitmap handle
        SelectObject(hdc_memory, hbitmap);
        // paint onto the bitmap
        BitBlt(hdc_memory, bounds.x, bounds.y, bounds.width, bounds.height, hdc_screen, bounds.x, bounds.y, SRCPAINT);
        // release the screen DC
        ReleaseDC(NULL, hdc_screen);
        // get the pixel data from the bitmap handle and put it into a nice data structure
        for(size_t i = bounds.x; i < bounds.x + bounds.width; ++i)
        {
            for(size_t j = bounds.y; j < bounds.y + bounds.height; ++j)
            {
                img[j-bounds.y][i-bounds.x] = GetPixel(hdc_memory, i, j);
            }
        }
        // release our memory DC
        ReleaseDC(NULL, hdc_memory);
    }

*注意:矩形实际上是我为左上角x&y坐标和矩形的宽度和高度用4个size_t字段创建的结构。它不是WinAPI矩形。

关于这个代码,我有几个问题:

  1. 我是否适当地释放了所有资源?
  2. 有更好的方法吗?我正在寻找类似的复杂程度和灵活性的东西,一个2d的RGB值数组。最后的屏幕截图数据处理将用OpenCL完成,所以我希望没有任何复杂的结构。
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2011-09-07 06:29:52

  1. 你忘了DeleteObject(hbitmap)
  2. CreateDIBSection创建了一个HBITMAP,它可以通过内存指针直接访问数据位,所以使用它可以完全避免for循环。
  3. 添加CAPTUREBLT标志和SRCCOPY,否则将不包括分层(透明)窗口。
  4. 在循环后从内存DC中选择位图。
  5. 您应该在内存DC上调用DeleteDC而不是ReleaseDC。(如果你拿到了,就把它放了。如果您创建它,请删除它。)

如果您想要一种更有效的方法,可以使用DIBSECTION而不是兼容的位图。这将使您可以跳过缓慢的GetPixel循环,并以所需的格式将像素数据直接写入数据结构。

票数 1
EN

Stack Overflow用户

发布于 2011-09-07 03:29:49

我刚被介绍到CImage这个奇妙的世界。

代码语言:javascript
复制
    /**
    * Creates a screenshot of the specified region and copies it to the specified region in img.
    */
    void get_screenshot(CImage &img, const CRect & src_bounds, const CRect &dest_bounds)
    {
        // get the screen DC
        HDC hdc_screen = GetDC(nullptr);
        // copy to a CImage
        CImageDC memory_dc(img);
        //StretchDIBits(
        StretchBlt(memory_dc, dest_bounds.left, dest_bounds.top, dest_bounds.Width(), dest_bounds.Height(), hdc_screen, src_bounds.left, src_bounds.top, src_bounds.Width(), src_bounds.Height(), SRCCOPY);
        ReleaseDC(nullptr, memory_dc);
        ReleaseDC(nullptr, hdc_screen);
    }

然后使用,只需创建一个CImage对象,并调用GetBits()并将其转换为类似于char*和瞧的东西。立即访问图像数据。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/7328045

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档