use std::{borrow::Cow, sync::Arc, thread};
use image::{
EncodableLayout, GenericImageView, ImageBuffer, Rgba,
imageops::{flip_horizontal_in_place, flip_vertical_in_place},
};
use winit::event_loop::EventLoopProxy;
use super::{
image_view::ImageView,
op_queue::{Output, UserEventLoopProxyExt},
};
use crate::util::{Image, ImageData, UserEvent};
pub fn copy(view: &ImageView, proxy: EventLoopProxy<UserEvent>) {
let image_data = view.image_data.clone();
let rotation = view.rotation();
let horizontal_flip = view.horizontal_flip;
let vertical_flip = view.vertical_flip;
thread::spawn(move || {
let guard = image_data.read().unwrap();
let frame = guard.frames.first().unwrap();
let buffer = match rotation {
0 => Cow::Borrowed(frame.buffer()),
1 => Cow::Owned(frame.buffer().rotate270()),
2 => Cow::Owned(frame.buffer().rotate180()),
3 => Cow::Owned(frame.buffer().rotate90()),
_ => unreachable!("image is rotated more then 360 degrees"),
};
let buffer = match buffer {
Cow::Owned(mut buffer) => {
if horizontal_flip {
flip_horizontal_in_place(&mut buffer);
}
if vertical_flip {
flip_vertical_in_place(&mut buffer);
}
Cow::Owned(buffer)
}
Cow::Borrowed(buffer) => {
if !horizontal_flip && !vertical_flip {
Cow::Borrowed(buffer)
} else {
let mut buffer = buffer.clone();
if horizontal_flip {
flip_horizontal_in_place(&mut buffer);
}
if vertical_flip {
flip_vertical_in_place(&mut buffer);
}
Cow::Owned(buffer)
}
}
};
let (width, height) = buffer.dimensions();
let buffer = buffer.to_rgba8();
let image_data = arboard::ImageData {
width: width as usize,
height: height as usize,
bytes: Cow::Borrowed(buffer.as_bytes()),
};
if let Ok(mut clipboard) = arboard::Clipboard::new() {
let _ = clipboard.set_image(image_data);
}
proxy.send_output(Output::Done);
});
}
pub fn paste(proxy: EventLoopProxy<UserEvent>) {
thread::spawn(move || {
if let Ok(mut clipboard) = arboard::Clipboard::new()
&& let Ok(image_data) = clipboard.get_image()
{
let width = image_data.width;
let height = image_data.height;
let mut data = Vec::with_capacity(image_data.bytes.len());
data.extend_from_slice(&image_data.bytes);
let image =
ImageBuffer::<Rgba<u8>, _>::from_raw(width as u32, height as u32, data).unwrap();
proxy.send_output(Output::ImageLoaded(
Arc::new(ImageData::from(vec![Image::from(image)])),
None,
));
return;
}
proxy.send_output(Output::Done);
});
}