Project1

标题: 有没有办法截取整个屏幕或其中一部分? [打印本页]

作者: hy2000    时间: 2020-10-29 10:17
标题: 有没有办法截取整个屏幕或其中一部分?
本帖最后由 hy2000 于 2020-10-29 23:32 编辑

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

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

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

RUBY 代码复制
  1. class << Graphics
  2.   CreateDC = Win32API.new("gdi32", "CreateDC", "pppl", "l")
  3.   CreateCompatibleBitmap = Win32API.new("gdi32", "CreateCompatibleBitmap", "lll", "l")
  4.   CreateCompatibleDC = Win32API.new("gdi32", "CreateCompatibleDC", "l", "l")
  5.   SelectObject = Win32API.new("gdi32", "SelectObject", "ll", "l")
  6.   BitBlt = Win32API.new("gdi32", "BitBlt", "lllllllll", "l")
  7.   GetBitmapBits = Win32API.new("gdi32", "GetBitmapBits", "llp", "l")
  8.   ScreenToClient = Win32API.new("user32", "ScreenToClient", "ip", "i")
  9.   DeleteDC = Win32API.new("gdi32", "DeleteDC", "l", "l")
  10.   DeleteObject = Win32API.new("gdi32", "DeleteObject", "l", "l")
  11.   SRCCOPY = 0xCC0020
  12.   RtlMoveMemory = Win32API.new("kernel32", "RtlMoveMemory", "ipi", "i")
  13.   RtlMoveMemory_pi = Win32API.new("kernel32", "RtlMoveMemory", "pii", "i")
  14.   HWnd = Win32API.new("user32", "GetActiveWindow", nil, 'l').call
  15.   DwCount = (1600 * 800 * 4)# * 2
  16.   @@lpBits = "\000" * DwCount
  17.  
  18.   #---------------------------------------------------------------------------#
  19.   # snap_to_bitmap                                                            #
  20.   #---------------------------------------------------------------------------#
  21.   def snap_to_bitmap2()
  22.     xy = Extra.get_reso #获取分辨率
  23.     width = xy[0]
  24.     height = xy[1]
  25.     hb = Bitmap.new(width, height)
  26.     rgbs = self.bitmap_data(0,0,width,height)
  27.     RtlMoveMemory.call(hb.address, rgbs, width * height * 4)
  28.     hb.export("test")
  29.     return hb
  30.   end
  31.   #---------------------------------------------------------------------------#
  32.   # bitmap_data                                                          #
  33.   #---------------------------------------------------------------------------#
  34.   def bitmap_data(s_w,s_h,width,height)
  35.     hScrDC = Win32API.new("User32.dll","GetDC",["L"],"L").call(Win32API.new("User32.dll","GetDesktopWindow",[],"L").call())
  36.     hMemDC = CreateCompatibleDC.call(hScrDC)
  37.     hBitmap = CreateCompatibleBitmap.call(hScrDC, width, height)
  38.     hOldBitmap = SelectObject.call(hMemDC, hBitmap)
  39.     win_pos = "\0\0\0\0\0\0\0\0"
  40.     ScreenToClient.call(HWnd, win_pos)
  41.     win_pos = win_pos.unpack("LL")
  42.  
  43.     xy = Extra.get_reso
  44.     BitBlt.call(hMemDC, s_w, s_h, xy[0], xy[1], hScrDC, 0, 0, SRCCOPY)
  45.     hBitmap2 = SelectObject.call(hMemDC, hOldBitmap)
  46.     GetBitmapBits.call(hBitmap2, DwCount, @@lpBits)
  47.     # 释放所有东西
  48.     DeleteDC.call(hScrDC)
  49.     DeleteDC.call(hMemDC)
  50.     DeleteObject.call(hBitmap)
  51.     DeleteObject.call(hOldBitmap)
  52.     DeleteObject.call(hBitmap2)
  53.     return @@lpBits
  54.   end
  55.   #---------------------------------------------------------------------------#
  56.   # 用户窗口的位置                                                            #
  57.   #---------------------------------------------------------------------------#
  58.   def xsrc
  59.     return self.point[0]
  60.   end
  61.   #---------------------------------------------------------------------------#
  62.   # 用户窗口的位置                                                            #
  63.   #---------------------------------------------------------------------------#
  64.   def ysrc
  65.     return self.point[1]
  66.   end
  67.   #---------------------------------------------------------------------------#
  68.   # 那个点                                                                    #
  69.   #---------------------------------------------------------------------------#
  70.   def point
  71.     point = [0,0].pack("LL")
  72.     ScreenToClient.call(HWnd, point)
  73.     return point.unpack("LL")
  74.   end
  75. end

作者: alexncf125    时间: 2020-10-29 10:29
本帖最后由 alexncf125 于 2020-10-29 10:32 编辑

1.同时按下WIN键 + Print Screen键
2.打开C:\Users\user_name\Pictures\Screenshots
-截取完成-(被打...逃...
作者: st251355    时间: 2020-10-30 12:00
你的腳本已經有Graphics.snap_to_bitmap2的方法了,距離想要的效果不遠
如果是圖片檔的話可以用.blt方法配合Rect.new()切割出想要的區塊,但.snap_to_bitmap獲取的不能這麼做
所以這裡要反其道而行,利用fill_rect()與Color.new(0,0,0,0)填充bitmap區域,將不要的地方填成透明的



例如:
RUBY 代码复制
  1. @screenshot = Sprite.new
  2. bitmap = Graphics.snap_to_bitmap2
  3. rect = Rect.new(0, 200 ,bitmap.width, bitmap.height)
  4. bitmap.fill_rect(rect, Color.new(0,0,0,0))
  5. @screenshot.bitmap = bitmap


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




欢迎光临 Project1 (https://rpg.blue/) Powered by Discuz! X3.1