查看: 2578|回复: 5

[已经过期] 有没有办法截取整个屏幕或其中一部分?

[复制链接]
梦石
0
星屑
3053
在线时间
441 小时
注册时间
2014-11-21
回帖
103
发表于 2020-10-29 10:17:59 | 显示全部楼层 |阅读模式

加入我们,或者,欢迎回来。

您需要 登录 才可以下载或查看,没有账号?注册会员

×
本帖最后由 hy2000 于 2020-10-29 23:32 编辑

如题,现在找到的截图脚本似乎都只能截取游戏窗口内的图片,因为游戏内容需要,我想找一个能截取整个电脑屏幕内容或者其一部分的
找到一个古代截图脚本是从这方面入手的,但我试了一下有各种谜之bug,应该是配套的dll本身就有问题()
问一下有没有什么好的思路实现这一点

更新:找到了一个能用的古代截图脚本,修改之后可以用于截取全屏(其中Extra是我自己写的调api的一些方法,get_reso为获取分辨率)
全屏可以正常截取,但要截取其中较小一部分时就会出现问题,有时会截不出来,检测发现在起始0,0,设定范围2倍的区域外截到都是透明,不知道是哪里有问题……
虽然可以靠全屏截图后切割的办法,但效率比较低,会卡上2-3秒,希望还是能实现部分截图
或者有没有效率更高的办法()

二度更新:懂了,应该是原本其中width*2, height*2的设置有误,应当设置为全屏幕。
那么现在能用了,但是效率还是有点低,不知道有无效率更高的做法

[pre lang="ruby" line="1"]class << Graphics
  CreateDC = Win32API.new("gdi32", "CreateDC", "pppl", "l")
  CreateCompatibleBitmap = Win32API.new("gdi32", "CreateCompatibleBitmap", "lll", "l")
  CreateCompatibleDC = Win32API.new("gdi32", "CreateCompatibleDC", "l", "l")
  SelectObject = Win32API.new("gdi32", "SelectObject", "ll", "l")
  BitBlt = Win32API.new("gdi32", "BitBlt", "lllllllll", "l")
  GetBitmapBits = Win32API.new("gdi32", "GetBitmapBits", "llp", "l")
  ScreenToClient = Win32API.new("user32", "ScreenToClient", "ip", "i")
  DeleteDC = Win32API.new("gdi32", "DeleteDC", "l", "l")
  DeleteObject = Win32API.new("gdi32", "DeleteObject", "l", "l")
  SRCCOPY = 0xCC0020
  RtlMoveMemory = Win32API.new("kernel32", "RtlMoveMemory", "ipi", "i")
  RtlMoveMemory_pi = Win32API.new("kernel32", "RtlMoveMemory", "pii", "i")
  HWnd = Win32API.new("user32", "GetActiveWindow", nil, 'l').call
  DwCount = (1600 * 800 * 4)# * 2
  @@lpBits = "\000" * DwCount
  
  #---------------------------------------------------------------------------#
  # snap_to_bitmap                                                            #
  #---------------------------------------------------------------------------#
  def snap_to_bitmap2()
    xy = Extra.get_reso #获取分辨率
    width = xy[0]
    height = xy[1]
    hb = Bitmap.new(width, height)
    rgbs = self.bitmap_data(0,0,width,height)
    RtlMoveMemory.call(hb.address, rgbs, width * height * 4)
    hb.export("test")
    return hb
  end
  #---------------------------------------------------------------------------#
  # bitmap_data                                                          #
  #---------------------------------------------------------------------------#
  def bitmap_data(s_w,s_h,width,height)
    hScrDC = Win32API.new("User32.dll","GetDC",["L"],"L").call(Win32API.new("User32.dll","GetDesktopWindow",[],"L").call())
    hMemDC = CreateCompatibleDC.call(hScrDC)
    hBitmap = CreateCompatibleBitmap.call(hScrDC, width, height)
    hOldBitmap = SelectObject.call(hMemDC, hBitmap)
    win_pos = "\0\0\0\0\0\0\0\0"
    ScreenToClient.call(HWnd, win_pos)
    win_pos = win_pos.unpack("LL")

    xy = Extra.get_reso
    BitBlt.call(hMemDC, s_w, s_h, xy[0], xy[1], hScrDC, 0, 0, SRCCOPY)
    hBitmap2 = SelectObject.call(hMemDC, hOldBitmap)
    GetBitmapBits.call(hBitmap2, DwCount, @@lpBits)
    # 释放所有东西
    DeleteDC.call(hScrDC)
    DeleteDC.call(hMemDC)
    DeleteObject.call(hBitmap)
    DeleteObject.call(hOldBitmap)
    DeleteObject.call(hBitmap2)
    return @@lpBits
  end
  #---------------------------------------------------------------------------#
  # 用户窗口的位置                                                            #
  #---------------------------------------------------------------------------#
  def xsrc
    return self.point[0]
  end
  #---------------------------------------------------------------------------#
  # 用户窗口的位置                                                            #
  #---------------------------------------------------------------------------#
  def ysrc
    return self.point[1]
  end
  #---------------------------------------------------------------------------#
  # 那个点                                                                    #
  #---------------------------------------------------------------------------#
  def point
    point = [0,0].pack("LL")
    ScreenToClient.call(HWnd, point)
    return point.unpack("LL")
  end
end[/pre]
梦石
0
星屑
29896
在线时间
5733 小时
注册时间
2016-3-8
回帖
1653
发表于 2020-10-29 10:29:09 | 显示全部楼层
本帖最后由 alexncf125 于 2020-10-29 10:32 编辑

1.同时按下WIN键 + Print Screen键
2.打开C:\Users\user_name\Pictures\Screenshots
-截取完成-(被打...逃...

点评

23333  发表于 2020-10-29 22:51
啊这 和玩家说“由于技术原因这里没有实现,你自己截一张图假装实现了吧”wwww  发表于 2020-10-29 22:49
回复

使用道具 举报

梦石
0
星屑
10164
在线时间
2502 小时
注册时间
2016-10-2
回帖
31
发表于 2020-10-30 12:00:02 | 显示全部楼层
你的腳本已經有Graphics.snap_to_bitmap2的方法了,距離想要的效果不遠
如果是圖片檔的話可以用.blt方法配合Rect.new()切割出想要的區塊,但.snap_to_bitmap獲取的不能這麼做
所以這裡要反其道而行,利用fill_rect()與Color.new(0,0,0,0)填充bitmap區域,將不要的地方填成透明的



例如:
[pre lang="ruby"]@screenshot = Sprite.new
bitmap = Graphics.snap_to_bitmap2
rect = Rect.new(0, 200 ,bitmap.width, bitmap.height)
bitmap.fill_rect(rect, Color.new(0,0,0,0))
@screenshot.bitmap = bitmap[/pre]

之後控制@screenshot的x、y、z軸位置到想要的地方就行了

点评

这个反其道而行之的思路没想过,太强了,之后有时间试一下  发表于 2020-11-2 23:15

评分

参与人数 1星屑 +20 收起 理由
RyanBern + 20 塞糖

查看全部评分

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册会员

本版积分规则

Powered by Discuz! X5.0 © 2001-2026 Discuz! Team.

在本版发帖返回顶部