Desktop screenshot with Ruby

Viewed 111

I'm currently working with a Ruby script that would capture the desktop screen, which needs to be saved. However, the size of the image (base64 string) is very huge. This needs to be compressed. Requesting help to compress this image and get the compressed base64 string.

Reference: https://github.com/jarmo/win32screenshot/blob/master/lib/win32/screenshot/bitmap_maker.rb

My current Ruby script is pasted below.

def self.get_screen_image
  handle = Windows::Win.desktop_window
  hScreenDC = Windows::Win.window_dc(handle)
  screen_size = `wmic path Win32_VideoController get CurrentHorizontalResolution,CurrentVerticalResolution`
  width = screen_size.scan(/\d+/)[0].to_i
  height = screen_size.scan(/\d+/)[1].to_i
  hmemDC = Windows::Win.create_compatible_dc(hScreenDC)
  hmemBM = Windows::Win.create_compatible_bitmap(hScreenDC, width, height)
  Windows::Win.select_object(hmemDC, hmemBM)
  Windows::Win.bit_blt(hmemDC, 0, 0, width, height, hScreenDC, 0, 0, Windows::Win::SRCCOPY)
  begin
    bitmap_size = width * height * 3 + width % 4 * height
    bitmap_data = FFI::MemoryPointer.new(bitmap_size)
    bitmap_info = [40, width, height, 1, 24, 0, 0, 0, 0, 0, 0].pack('L3S2L6')
    Windows::Win.di_bits(hmemDC, hmemBM, 0, height, bitmap_data, bitmap_info, Windows::Win::DIB_RGB_COLORS)
    bitmap_file_header = [
      19778,
      bitmap_size + 40 + 14,
      0,
      0,
      54
    ].pack('SLSSL')
    Base64.encode64(bitmap_file_header + bitmap_info + bitmap_data.read_string(bitmap_size))
  rescue StandardError => e
    ''
  ensure
    bitmap_data.free
    Windows::Win.delete_object(hmemBM)
    Windows::Win.delete_dc(hmemDC)
    Windows::Win.release_dc(0, hScreenDC)
  end
end

I am looking to have an equivalent of the below .Net code in Ruby (ideally without having external gem dependency)

Rectangle rectangle = Screen.PrimaryScreen.Bounds;
using (Bitmap bitmap = new Bitmap(rectangle.Width, rectangle.Height))
using (Graphics g = Graphics.FromImage(bitmap))
using (MemoryStream stream = new MemoryStream())
{
    g.CopyFromScreen(System.Drawing.Point.Empty, System.Drawing.Point.Empty, rectangle.Size);
    bitmap.Save(stream, ImageFormat.Jpeg);
    return Convert.ToBase64String(stream.ToArray());
}
0 Answers
Related