title: The right way to capture screenshot using Rust
body: <p>I have been looking for an answer to this question for several days and so on until the end, I have not completely figured it out. It is worth clarifying that I am looking for a way not just to save the screenshot as a file, but to get an array of bytes and array of bytes decoded to png/jpg or another lightweight image format.
  The first way i tried was <a href="https://crates.io/crates/screenshot-rs/0.1.5" rel="nofollow noreferrer">screenshot-rs</a> crate, code like this:</p>
  <pre><code>let s = match get_screenshot(0) {
          Ok(it) =&gt; it,
          _ =&gt; return,
      };
  
      let mut buf = Vec::&lt;u8&gt;::new();
  
      let encoder = PngEncoder::new(&amp;mut buf);
      unsafe {
          match encoder.encode(
              std::slice::from_raw_parts(s.raw_data(), s.raw_len()),
              s.width() as u32,
              s.height() as u32,
              image::ColorType::Rgba8,
          ) {
              Ok(it) =&gt; it,
              _ =&gt; return,
          };
      }
  </code></pre>
  <p>(I use png encoder too)</p>
  <p>Formally, this code works but works very slowly (around ~5 sec) and producec screenshot with switched blue and red color channels.</p>
  <p>After this i start trying to use winapi to capture screenshot, but my knowledge about winapi, hundreds of data types and what i have to do now (this doesnt work properly)</p>
  <pre><code>let x1 = GetSystemMetrics(78);
          let y1 = GetSystemMetrics(79);
          let x2 = GetSystemMetrics(76);
          let y2 = GetSystemMetrics(77);
          let w = x2 - x1;
          let h = y2 - y1;
  
          let hdc_screen = GetDC(ptr::null_mut());
          let hdc = CreateCompatibleDC(hdc_screen);
          let h_bitmap = CreateCompatibleBitmap(hdc_screen, w, h);
          let obj = SelectObject(hdc, h_bitmap as HGDIOBJ);
          let status = BitBlt(hdc, 0, 0, w, h, hdc_screen, x1, y1, SRCCOPY);
  </code></pre>