use anyhow::bail;
use image::imageops::FilterType;
use opencv::core::{Mat, MatTraitConst, MatTraitConstManual, Size_};
use opencv::imgproc::{cvt_color_def, COLOR_BGR2RGB};
use opencv::videoio::{VideoCapture, VideoCaptureTrait, VideoCaptureTraitConst, CAP_ANY};
pub struct Webcam(VideoCapture);
impl Webcam {
pub fn new(camera_idx: i32, api_preference: i32) -> anyhow::Result<Self> {
let video_capture_handle = VideoCapture::new(camera_idx, api_preference)?;
if !video_capture_handle.is_opened()? {
bail!("Failed to open capture device.")
}
Ok(Self(video_capture_handle))
}
pub fn new_def_auto_detect() -> anyhow::Result<Self> {
let video_capture_handle = VideoCapture::new_def(CAP_ANY)?;
if !video_capture_handle.is_opened()? {
bail!("Failed to open capture device.")
}
Ok(Self(video_capture_handle))
}
pub fn new_def(camera_idx: i32) -> anyhow::Result<Self> {
let video_capture_handle = VideoCapture::new_def(camera_idx)?;
if !video_capture_handle.is_opened()? {
bail!("Failed to open capture device.")
}
Ok(Self(video_capture_handle))
}
pub fn get_frame(&mut self) -> anyhow::Result<(Vec<u8>, Size_<i32>)> {
let mut frame = Mat::default();
self.0.read(&mut frame)?;
let mut corrected_frame = Mat::default();
cvt_color_def(&frame, &mut corrected_frame, COLOR_BGR2RGB)?;
Ok((frame.data_bytes()?.to_vec(), corrected_frame.size()?))
}
pub fn get_backend_name(&self) -> anyhow::Result<String> {
Ok(self.0.get_backend_name()?)
}
pub fn release(&mut self) -> anyhow::Result<()> {
Ok(self.0.release()?)
}
}
pub fn resize_image_from_bytes(formatted_image_bytes: &[u8], width: u32, lenght: u32, filter: FilterType) -> anyhow::Result<Vec<u8>> {
let frame = image::load_from_memory(formatted_image_bytes)?;
Ok(frame.resize_exact(width, lenght, filter).as_bytes().to_vec())
}