forked from michael/leanshot
works with imlib!
This commit is contained in:
parent
6cb1dd1b6e
commit
24d019fdcb
7 changed files with 51 additions and 93 deletions
|
@ -12,11 +12,6 @@ pub struct Image {
|
|||
}
|
||||
|
||||
impl Image {
|
||||
/// Set the display for the imlib context.
|
||||
pub fn context_set_display(display: *mut x11::xlib::Display) {
|
||||
unsafe { im::imlib_context_set_display(display as *mut im::_XDisplay) };
|
||||
}
|
||||
|
||||
/// Creates an Image from a pixmap.
|
||||
pub fn create_from_drawable(
|
||||
drawable: impl AsRef<im::Drawable>,
|
||||
|
@ -29,7 +24,14 @@ impl Image {
|
|||
) -> Result<Self, Error> {
|
||||
unsafe { im::imlib_context_set_drawable(*drawable.as_ref()) };
|
||||
let image = unsafe {
|
||||
im::imlib_create_image_from_drawable(pixmap, x, y, width, height, if grab_x{ 1 } else { 0 }) as im::Imlib_Image
|
||||
im::imlib_create_image_from_drawable(
|
||||
pixmap,
|
||||
x,
|
||||
y,
|
||||
width,
|
||||
height,
|
||||
if grab_x { 1 } else { 0 },
|
||||
) as im::Imlib_Image
|
||||
};
|
||||
Ok(Image { inner: image })
|
||||
}
|
||||
|
|
|
@ -9,7 +9,20 @@ extern crate x11;
|
|||
|
||||
mod errors;
|
||||
mod image;
|
||||
mod visual;
|
||||
|
||||
pub use errors::Error;
|
||||
pub use image::Image;
|
||||
pub use imlib2_sys::{Drawable, Pixmap};
|
||||
pub use visual::Visual;
|
||||
|
||||
/// Set the display for the imlib context.
|
||||
pub fn context_set_display(display: *mut x11::xlib::Display) {
|
||||
unsafe { imlib2_sys::imlib_context_set_display(display as *mut imlib2_sys::_XDisplay) };
|
||||
}
|
||||
|
||||
/// Set the visual for the imlib context.
|
||||
pub fn context_set_visual(visual: Visual) {
|
||||
unsafe { imlib2_sys::imlib_context_set_visual(visual.inner) };
|
||||
}
|
||||
|
||||
|
|
15
imlib2/visual.rs
Normal file
15
imlib2/visual.rs
Normal file
|
@ -0,0 +1,15 @@
|
|||
use imlib2_sys as im;
|
||||
use x11;
|
||||
|
||||
/// Visual
|
||||
pub struct Visual {
|
||||
pub(crate) inner: *mut im::Visual,
|
||||
}
|
||||
|
||||
impl Visual {
|
||||
/// get the default visual for a display
|
||||
pub fn default(display: *mut x11::xlib::_XDisplay, screen: i32) -> Self {
|
||||
let inner = unsafe { im::XDefaultVisual(display as *mut im::_XDisplay, screen) };
|
||||
Visual { inner }
|
||||
}
|
||||
}
|
|
@ -23,12 +23,7 @@ pub fn capture(opt: &Options) -> Result<(), ScreenshotError> {
|
|||
let height = attr.get_height();
|
||||
let root = gui.display.get_default_root_window()?;
|
||||
let (x, y, _) = gui.display.translate_coordinates(win, 0, 0, root)?;
|
||||
Some(Rectangle {
|
||||
x: x as u32,
|
||||
y: y as u32,
|
||||
width,
|
||||
height,
|
||||
})
|
||||
Some(Rectangle::new(x as u32, y as u32, width, height))
|
||||
}
|
||||
_ => None,
|
||||
};
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use imlib2::{self, Image as Image2, Visual};
|
||||
use xlib::{Display, Image, Window};
|
||||
use imlib2::{Image as Image2,};
|
||||
|
||||
use errors::ScreenshotError;
|
||||
use Rectangle;
|
||||
|
@ -21,7 +21,8 @@ impl GUI {
|
|||
let height = attr.get_height() as i32;
|
||||
let root = self.display.get_default_root_window()?;
|
||||
let (x, y, _) = self.display.translate_coordinates(window, 0, 0, root)?;
|
||||
Image2::context_set_display(self.display.as_raw());
|
||||
imlib2::context_set_display(self.display.as_raw());
|
||||
imlib2::context_set_visual(Visual::default(self.display.as_raw(), 0));
|
||||
Image2::create_from_drawable(window, 0, x, y, width, height, true).map_err(|err| err.into())
|
||||
}
|
||||
|
||||
|
|
77
src/image.rs
77
src/image.rs
|
@ -1,77 +0,0 @@
|
|||
use std::fs::File;
|
||||
use std::io::BufWriter;
|
||||
use std::path::Path;
|
||||
|
||||
use png::{self, Encoder, HasParameters};
|
||||
use xlib::{Image, ImageByteOrder};
|
||||
|
||||
use errors::ScreenshotError;
|
||||
use Rectangle;
|
||||
|
||||
pub trait ImageExt {
|
||||
fn to_data_buf(&self, rect: Rectangle) -> Result<Vec<u8>, ScreenshotError>;
|
||||
fn write_png(
|
||||
&self,
|
||||
out: impl AsRef<Path>,
|
||||
rect: Option<Rectangle>,
|
||||
) -> Result<(), ScreenshotError>;
|
||||
}
|
||||
|
||||
impl ImageExt for Image {
|
||||
/// Converts the image buffer into RGB(A).
|
||||
fn to_data_buf(&self, rect: Rectangle) -> Result<Vec<u8>, ScreenshotError> {
|
||||
let (full_width, _) = (self.get_width() as usize, self.get_height() as usize);
|
||||
let bytes_per_row = 4 * rect.width as usize;
|
||||
let size = bytes_per_row * rect.height as usize;
|
||||
let mut buf = vec![1; size];
|
||||
let sbuf = self.buffer(); // source buffer
|
||||
let mut rx = rect.y as usize;
|
||||
if let ImageByteOrder::LSBFirst = self.get_byte_order()? {
|
||||
// LSBFirst
|
||||
while rx < rect.height as usize {
|
||||
let mut sx = (rx * full_width + rect.x as usize) * 4; // source idx
|
||||
let mut dx = rx * bytes_per_row; // dest idx
|
||||
let edx = (rx + 1) * bytes_per_row;
|
||||
// println!("sx={} dx={} edx={}", sx,dx,edx);
|
||||
while dx < edx {
|
||||
buf[dx] = sbuf.get_byte(sx + 2).unwrap() as u8;
|
||||
buf[dx + 1] = sbuf.get_byte(sx + 1).unwrap() as u8;
|
||||
buf[dx + 2] = sbuf.get_byte(sx).unwrap() as u8;
|
||||
buf[dx + 3] = if self.get_depth() == 32 {
|
||||
sbuf.get_byte(sx + 3).unwrap() as u8
|
||||
} else {
|
||||
255u8
|
||||
};
|
||||
sx += 4;
|
||||
dx += 4;
|
||||
}
|
||||
rx += 1;
|
||||
}
|
||||
}
|
||||
Ok(buf)
|
||||
}
|
||||
|
||||
fn write_png(
|
||||
&self,
|
||||
out: impl AsRef<Path>,
|
||||
rect: Option<Rectangle>,
|
||||
) -> Result<(), ScreenshotError> {
|
||||
let rect = rect.unwrap_or_else(|| Rectangle {
|
||||
x: 0,
|
||||
y: 0,
|
||||
width: self.get_width(),
|
||||
height: self.get_height(),
|
||||
});
|
||||
|
||||
let file = File::create(out.as_ref())?;
|
||||
let ref mut out = BufWriter::new(file);
|
||||
|
||||
let mut encoder = Encoder::new(out, rect.width, rect.height);
|
||||
encoder.set(png::ColorType::RGBA).set(png::BitDepth::Eight);
|
||||
let mut writer = encoder.write_header()?;
|
||||
|
||||
let data = self.to_data_buf(rect)?;
|
||||
writer.write_image_data(data.as_slice())?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
13
src/lib.rs
13
src/lib.rs
|
@ -10,13 +10,11 @@ extern crate xlib;
|
|||
mod capture;
|
||||
mod errors;
|
||||
mod gui;
|
||||
mod image;
|
||||
mod options;
|
||||
|
||||
use structopt::StructOpt;
|
||||
|
||||
pub use capture::capture;
|
||||
pub use image::ImageExt;
|
||||
pub use options::Options;
|
||||
|
||||
#[derive(Debug)]
|
||||
|
@ -26,3 +24,14 @@ pub struct Rectangle {
|
|||
pub width: u32,
|
||||
pub height: u32,
|
||||
}
|
||||
|
||||
impl Rectangle {
|
||||
pub fn new(x: u32, y: u32, width: u32, height: u32) -> Self {
|
||||
Rectangle {
|
||||
x,
|
||||
y,
|
||||
width,
|
||||
height,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue