用DirectDraw实现屏幕截图

利用D3D抓取显存数据 如何抓取显存的数据呢?在linux下直接通过FB就好,但是在windows下面不是那么好搞的? 这里看到了一些方法,还没有经过验证。 microsoft 提供的D3D SDK是用来进行3D建模和利用GPU运算的一组接口的集合, D3D SDK至少有两个优点: 1、提供了一种3D建模的构架,程序员可以很容易的用这种构架来建模自己的3D模型 2、提供了一种GPU和CPU并行运算的 阅读详情
  在DirectDraw的非独占模式中,主表面即为当前屏幕。你可以直接Lock住主表面,从而取得主表面图象数据。但如果你要对大量的数据进行直接的操作,最好还是先在系统内存中建一个和主表面一样大小的后台表面。用BltFast把主表面复制一份到后台表面,然后锁住后台表面,再进行操作,这是因为CPU对显存的操作是什分慢的。

1、初始化DirectDraw
  你可以响应WM_CREATE消息,并在OnCreate中初始化DirectDraw

  void CMainFrame::InitDirectX()
  {
    //创建DirectDraw
    if (FAILED( DirectDrawCreate(NULL,&ddraw1,NULL)))
    {
      TRACE(/"Couldn/'t create DirectDraw object.//n/");
    }
    if (FAILED( ddraw1->QueryInterface(IID_IDirectDraw2,(LPVOID *)&ddraw2)))
    {
      TRACE(/"Couldn/'t query the interface.//n/");
    }
    if (ddraw2)
    {
      ddraw2->SetCooperativeLevel(GetSafeHwnd(),DDSCL_NORMAL);
    }
    if (ddraw1)
    {
      ddraw1->Release();
      ddraw1=NULL;
    }

    //创建主表面
    HRESULT r;

    DDSURFACEDESC desc;
    desc.dwSize = sizeof(desc);
    desc.dwFlags = DDSD_CAPS;
    desc.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
    r=ddraw2->CreateSurface(&desc, &primsurf, 0);
    if(r!=DD_OK)
    {
      AfxMessageBox(/"Create DirectX Surface failed//n /");
      PostMessage(WM_CLOSE);
    }
    r=ddraw2->CreateClipper(0, &clipper, 0);
    if(r!=DD_OK)
    {
      AfxMessageBox(/"CreateClipper() fialed//n /");
      PostMessage(WM_CLOSE);
    }
    r=clipper->SetHWnd(0,GetSafeHwnd());
    if(r!=DD_OK)
    {
      AfxMessageBox(/"SetHWnd() failed//n /");
      PostMessage(WM_CLOSE);
    }
    r=primsurf->SetClipper(clipper);
    if(r!=DD_OK)
    {
      AfxMessageBox(/"SetClipper() fialed//n /");
      PostMessage(WM_CLOSE);
    }

    //创建后台表面
    ZeroMemory(&desc,sizeof(desc));
    desc.dwSize=sizeof(desc);
    desc.dwFlags=DDSD_WIDTH|DDSD_HEIGHT|DDSD_CAPS;
    desc.dwWidth=::GetSystemMetrics(SM_CXSCREEN);
    desc.dwHeight=::GetSystemMetrics(SM_CYSCREEN);
    desc.ddsCaps.dwCaps = DDSCAPS_SYSTEMMEMORY | DDSCAPS_OFFSCREENPLAIN;

    r=ddraw2->CreateSurface(&desc,&backsurf,0);
    //收集图象参数
    DDSURFACEDESC ddsd;

    ZeroMemory(&ddsd, sizeof(ddsd));
    ddsd.dwSize=sizeof(ddsd);
    backsurf->GetSurfaceDesc(&ddsd);
    BitCount = ddsd.ddpfPixelFormat.dwRGBBitCount;
    lPitch = ddsd.lPitch;
    dwWidth = ddsd.dwWidth;
    dwHeight = ddsd.dwHeight;
    dwRBitMask = ddsd.ddpfPixelFormat.dwRBitMask;
    dwGBitMask = ddsd.ddpfPixelFormat.dwGBitMask;
    dwBBitMask = ddsd.ddpfPixelFormat.dwBBitMask;
    //确定16Bit色时的修正(16Bit色时有两种显示格式565和555)
    RMove = 8;//这里先假定为565格式
     GMove = 3;
    BMove = 3;
    if(BitCount==16)
    {
      if(dwGBitMask==992)
      {
        //555格式
        RMove = 7;
        GMove = 2;
      }
      if(dwGBitMask==1984)
        //555格式
        BMove = 2;
    }
  }

2、得到图象数据的起始位置指针

  DDSURFACEDESC ddsd;

  ZeroMemory(&ddsd,sizeof(ddsd));
  ddsd.dwSize=sizeof(ddsd);
  if FAILED(backsurf->Lock(NULL, &ddsd, DDLOCK_WAIT , NULL))
    TRACE(/"backsurf->lock failed//n/");
// ddsd.lpSurface即为图象数据的指针

3、图象数据的转换
  DirectX是不支持图象格式转换的,如果你想得到的是24Bit的图象,而现在的显示模式为16Bit色,你就要自己动手了(看过下面的代码后你可能会发现,经转换后图象是倒置的,这是我为了方便对数进行压缩而进行的,你可以改变其for循环语句把图象换过来)。

  void CMainFrame:: Conversion()
  {
    int x,y;
    DDSURFACEDESC ddsd;

    ZeroMemory(&ddsd,sizeof(ddsd));
    ddsd.dwSize=sizeof(ddsd);

    if FAILED(backsurf->Lock(NULL, &ddsd, DDLOCK_WAIT , NULL))
      TRACE(/"backsurf->lock failed//n/");

    BYTE *scr=new BYTE[3*ddsd.dwHeight*ddsd.dwWidth];
    BYTE *scrt=scr;

    //Surface to RGB switch(BitCount)
    {
      case 8:
      {
        //TRACE(/"8 Bit//n/");
        BYTE *tem=(BYTE *)ddsd.lpSurface;
        PALETTEENTRY entry[256];

        HDC hScrDC=CreateDC(/"DISPLAY/", NULL, NULL, NULL);
        ::GetSystemPaletteEntries(hScrDC,0,256, entry);

        for(y=(int)dwHeight-1;y>=0;y--)
        {
          for(x=0;x<(int)dwWidth;x++)
          {
            *scrt++=entry[tem[x+lPitch*y]].peRed;
            *scrt++=entry[tem[x+lPitch*y]].peGreen;
            *scrt++=entry[tem[x+lPitch*y]].peBlue;
          }
        }
        break;
      }
      case 16:
      {
        //TRACE(/"16 Bit//n/");
        WORD *tem=(WORD *)ddsd.lpSurface;
         WORD color;
        for(y=(int)dwHeight-1;y>=0;y--)
        {
          for(x=0;x<(int)lPitch/2;x++)
          {
            color=tem[x+lPitch/2*y];
            *scrt++=(BYTE)((color&dwRBitMask)>>RMove);
            *scrt++=(BYTE)((color&dwGBitMask)>>GMove);
            *scrt++=(BYTE)(((color&dwBBitMask))<< BMove);
          }
        }
        break;
      }
      case 24:
      {
        //TRACE(/"24 Bit//n/");
        BYTE *tem=(BYTE *)ddsd.lpSurface;
        for(y=(int)dwHeight-1;y>=0;y--)
        {
          for(x=0;x<(int)dwWidth*3;x+=3)
          {
            *scrt++=tem[x+2+y*lPitch];
            *scrt++=tem[x+1+y*lPitch];
            *scrt++=tem[x+y*lPitch];
          }
        }
        break;
      }
      case 32:
      {
        AfxMessageBox(/"目前还不支持32Bit色//n请调整为24Bit色或16Bit色/");
        backsurf->Unlock(NULL);
        delete scr; PostMessage(WM_CLOSE);
        break;
      }
    }
    backsurf->Unlock(NULL);
    //在里进行你的数据处理 delete scr;
    //数据处理完毕释放内存
  }
使用DDK和Mirror Driver实现屏幕截图技术 htmltable {th, td {th {pre {简介:本文详细说明了如何利用Microsoft DirectDraw Kernel (DDK) 和 Mirror Driver技术进行屏幕截图。这包括Windows驱动程序开发的各个方面,特别是对视频源代码的修改以捕获屏幕内容。DDK是一个开发工具包,用于创建能与硬件交互的驱动程序。Mirror Driver是一个特殊类型的驱动程序,可以复制屏幕内容到其他显示设备。 阅读详情

相关推荐

halcon3D 点云拟合球体

halon3D 点云拟合球面

weixin_43213429的博客 1639

DirectDraw像素操作

今天我们将分别使用调色板和RGB模式来熟悉DirectDraw的基本图形。它们有什么不同呢?如果你曾经在DOS下编程,你可能使用过调色板映射模式。调色板是个颜色查询表,为了绘制象素,你将一个单独的字节写入视频内存,通过这个字节你可以索引到一个拥有各种颜色的链表,这个颜色的链表,或查询表就叫作调色板。而RGB模式是不同的,因为它不需要颜色查询表。在RGB模式下绘制一个象素,你可以直接把红色、绿色和蓝

老家的橙子好吃 2436

以太网硬件核心:MAC、PHY、MII与交换机原理与实战排查

计算机网络通信的基础依赖于一套完整的硬件协议栈。在OSI模型中,数据链路层和物理层是实现设备间可靠、高效数据传输的基石。其核心原理在于将上层数据包封装成帧,并通过特定的介质访问控制与物理信号转换机制进行传输。这一过程的技术价值在于为上层应用提供了透明、稳定的通信信道,是互联网和所有局域网通信的物理承载。在嵌入式系统、网络设备开发及运维等应用场景中,深入理解底层硬件交互至关重要。本文将聚焦于以太网硬件的两大核心组件:负责逻辑成帧与流量控制的MAC控制器,以及负责数模转换与链路协商的PHY芯片。它们通过MII、

dgqvhtlwq472235338的博客 424

[DirectDraw]显示模式

    (转自:http://web.mblogger.cn/www/club/topic_12_11852.htm)     ● 关于显示模式    显示模式指的是显示器的当前设置,描述了显示器的分辨率和位深度,这个信息通常是由显示硬件从主页面传递给显示器的。显示模式是由三个特征定义的:宽、高、位深度。例如,大多数的显示器可以显示宽为640像素、高为480像素的图象,每一个像素的位深度是

scofieldzhu的专栏 2836

XDS110 USB Debug Probe连接错误-260:CCS Theia环境下的诊断与修复指南

本文详细解析了CCS Theia环境下XDS110 USB Debug Probe连接错误-260的诊断与修复方法。从硬件连接到驱动状态、固件更新到软件配置,提供了全面的排查指南,帮助开发者快速解决这一常见的调试器通信障碍问题,确保嵌入式开发工作流畅进行。

hope8的博客 285

深入解析组合逻辑环(combinational loop)的成因与解决方案

本文深入解析了数字电路设计中组合逻辑环(combinational loop)的成因与危害。通过边沿检测和中断轮询(round_robin)仲裁器等实例,揭示了代码如何意外形成环路,并对比了插入触发器、重构逻辑以及状态机思维三种核心解决方案,帮助硬件工程师从根本上避免这一常见设计陷阱,确保电路稳定可靠。

weixin_28278377的博客 314

DirectDraw Tutorial 2

DirectDraw Tutorial 2 Alpha混合 一、              基本alpha混合 Alhpa混合有多种算法,基本的计算公式如下:result = ALPHA * srcPixel + ( 1 - ALPHA ) * destPixel其中ALHPA的范围从0.0到1.0,result为混合后的颜色,srcPixel为前景色,destPixe

NETTE DE BLOG 1611

别再瞎调了!STM32 Systick延时函数避坑指南(正点原子、野火、慧净代码对比)

本文深入解析STM32 Systick延时函数的实现差异与优化策略,对比正点原子、野火、慧净等主流方案的优缺点。针对us和ms级延时精度问题,提供避坑指南和高级优化技巧,帮助开发者根据项目需求选择最佳方案,提升嵌入式系统的定时控制精度。

weixin_28717807的博客 340

16-Bit Pixels (翻译)

/************************************************************************/本文纯粹是译者学习,不作任何它用.译者尊重原作者拥有的一切权力!转载请告知,E-mail: linuxsunshen@163.com/*****************************************************

adamsun(令狐冲)的专栏 1705

汽车行业OTD业务模式入门学习

本文是在学习彭俊松老师的《汽车行业整车订单交付系统》后,对于OTD理解的一些摘录,供诸位参考学习。

qq_40664711的博客 1万+

Intellij IDEA 使用教程(一)Jdk安装和配置

一.JDK下载 这里下载的是Java SE 8u181 64位版本。可以根据自己电脑配置来选择不同版本。 官网下载JDK 二.安装JDK 双击运行jdk-8u181-windows-x64.exe安装程序 选择安装目录,然后点击下一步 等待安装 安装JRE,就是java的运行环境,可以安装在java目录下 等待安装 安装完成。点击关闭。 三.java环境变量配置 关于环境变量的配置,...

岁月不饶人,我亦未曾饶过岁月 4059

DirectDraw实现屏幕截图的原代码

DirectDraw实现屏幕截图的原代码 HBITMAP CDialogcapDlg::CopyScreenToBitmapDX(LPRECT lpRect) { HBITMAP hBitmap; HDC hDC=NULL; int height,width,bitsize,palettebit; HRESULT hres; heigh...

zgy19851028的专栏 654

基于PyQt5和OpenCV的传统图像分割应用UI程序

主要功能包括:加载和显示图像应用多种图像分割算法调整算法参数保存处理结果。

Henry的博客 473

(转)用DirectDraw实现屏幕截图 [ 2004-05-03 ] 陈伟凡 出处:GameDev 目 录

在DirectDraw的非独占模式中,主表面即为当前屏幕。你可以直接Lock住主表面,从而取得主表面图象数据。但如果你要对大量的数据进行直接的操作,最好还是先在系统内存中建一个和主表面一样大小的后台表面。用BltFast把主表面复制一份到后台表面,然后锁住后台表面,再进行操作,这是因为CPU对显存的操作是什分慢的。1、初始化DirectDraw  你可以响应WM_CREATE消息,并在OnCrea

我的编程之旅 2808

IMSL CNL 7.0.0 (x86-64)Crack

IMSL CNL 7.0.0 (x86-64)Crack intel的算法库破解文件,这是C++版本的破解文件

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

DirectDraw方式截取系统屏幕

//注意:需要下载Microsoft DirectX SDK开发包#include #include #include #include #include #include #include #include using namespace std; void CaptureScreenByDirectDraw() { // 初始化阶段 BITM

baggiowangyu的专栏 1953

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

如何提高截取屏幕的速度?

2000年12月30日 11:59:00 作者: Seaky 发表日期: 1999-10-14 23:29:18 返回《VC论坛》 快速返回 我用如下的方法截取屏幕,但我发现截取整个800x600x24屏幕需约200ms,有没有更快的方法? 越快越好! HDC hScrDC,hMemDC; HBITMAP hBitmap,hOldBitmap; hScrDC=CreateDC("DISPL

秦梦瑶的专栏 489

lwip-2.0.3

lwip是瑞典计算机科学院(SICS)的Adam Dunkels 开发的一个小型开源的TCP/IP协议栈。实现的重点是在保持TCP协议主要功能的基础上减少对RAM 的占用。

wince下全屏截图并保存为bmp格式

在WinCE中, 由于WinCE的精简,有很多win32下的标准API不支持,所以有很多在vc上能够轻易实现的功能, 在evc中有点难度,必须变通一下,就拿截取屏幕来说,一个常用的函数GetDIBits在wince就Unsupported.当时为了实现这个功能,颇费了了一番心血,当然其主要还是因为对api不是很熟悉。 最初使用的截屏方法说来还真有些丢人,一个一个点的取得颜色值,再保存到bmp

yizhou2010的专栏 928

多媒体编程——屏幕截图

多媒体编程——屏幕截图   为什么要先讲屏幕截图而不是硬件加速渲染图像呢,因为视频播放需要连续渲染图像,而最好的图像来源就是视频文件。但是视频文件解析是一个巨大的课题,哪怕是做一个测试例子,也至少要引入某些开源的解析库,非常麻烦。所以先讲屏幕截图,不停的抓图,得到一张张屏幕画面,进而后面章节可以讲解怎么渲染图像实现视频播放。   屏幕截图,依然会用到Direct,具体的说是DirectDr

「花岗岩是甜的」的专栏 1286

directdraw direct3d 保存位图

直接上代码 // 功能:将一个DirectDraw表面,存为一张24位BMP位图 (传入主表面即截屏) // 输入:表面指针,输出的文件名 // 输出:是否成功 bool SaveToBitmapFile(LPDIRECTDRAWSURFACE lpSurface, char* filename) { WORD* lpBuffer; // 表面指针 int nPitch;

qianbo_0423的专栏 qq:418511899 18710866728 1163

用delphi实现完美屏幕截图

可以截取layered窗口(包括透明窗口)的代码: procedure CaptureScreen(AFileName: string);const  CAPTUREBLT = $40000000;var  hdcScreen: HDC;  hdcCompatible: HDC;  bmp: TBitmap;  hbmScreen: HBITMAP;begin  hdcScreen := Cre...

weixin_33853827的博客 801

DirectDraw下的的游戏截屏

  现在很多游戏都提供一种截屏的功能,用来截取游戏中的画面,那么这是如何实现的呢?其实就是把游戏当前屏幕的数据存成一个图片文件;在这里我给出一段源程序,它实现了DirectDraw(16位模式)下的的游戏截屏。生成的文件格式为BMP,程序有比较详细的注释,请各位自己看吧。bool Is555; // 是否是565模式,这个变量需要用者填写// 功能:将一个16位的DirectDraw表面,存为一张...

weixin_30386713的博客 142

TCPMP中使用GDI、Direct及DirectDraw效果对比

       早先跟ZL讨论过WinCE6.0下使用TCPMP播放视频的问题。他认为直接写显存应该可以让视频播放更流畅。今天我在我们的平台上实际测试了一下,分别使用GDI、Direct和DirectDraw三种方式做了Benchmark,其中Direct就是他所说的直接写显存的方式。       为了让TCPMP支持Direct的方式,需要修改overlay_direct.c中的相关代码,使其能...

weixin_34301132的博客 190

windows下使用ffmpeg + DDRAW 截屏,并保存为图片

不清楚原理的看上篇文章《用DirectDraw实现屏幕截图》。 下面直接贴代码 #include #include #include "ddraw.h" extern "C"{ #include "libavcodec/avcodec.h" #include "libswscale/swscale.h" } void save_bmp(unsigned char *

Sloan 3732

屏幕录制,远程桌面传输,基于Windows图形驱动的屏幕截图技术

计算机屏幕图像的截取在屏幕的录制、计算机远程控制以及多媒体教学软件中都是关键术,基于Windows操作系统有多种截屏方法,研究的重点集中在如何快速有效的截取DBI(Device-Independent Bitmap)格式的屏幕图形数据。现在商业软件流行的截屏技术主要采取的Api Hook技术,但这种技术一次截屏仍有较大的时间消耗,这样就对运行软件的硬件仍有较多的限制,而且是一种非标准的技术,不为微

oldmtn的专栏 4303

计算机屏幕截图给播放器黑屏,跟大家学习电脑截图黑屏的解决方法

很多时候,我们总需对电脑进行截屏,那大家有没有遇上过电脑截图黑屏的呢?接下来,IT之窗的小编就给大家讲解一下电脑截图黑屏的处理方法。1、在Xp时代,很多用户都曾被视频截图后的“全黑图片”困扰。对此,在解决本地播放时出现的截图变黑问题,一般有两个方法可以用来解决,一个方法是用两个不同的播放器,同时打开同一个文件,另一个方法是禁用DirectDraw。2、熟悉Windows XP和Windows 7的...

weixin_39580124的博客 1350
上一篇: 16-Bit Pixels
下一篇: 象素格式
Garfield
博客等级 码龄26年 24粉丝 29原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值