camera: desktop support, switch camera, fix image crop

This commit is contained in:
ardocrat 2024-05-03 23:34:28 +03:00
parent 7267bf6441
commit 11ac0ea84b
5 changed files with 50 additions and 38 deletions

View file

@ -325,7 +325,7 @@ public class MainActivity extends GameActivity {
// Called from native code to switch camera.
public void switchCamera() {
mUseBackCamera = true;
mUseBackCamera = !mUseBackCamera;
stopCamera();
startCamera();
}

View file

@ -82,16 +82,6 @@ impl PlatformCallbacks for Android {
paste_data
}
fn cameras_amount(&self) -> u32 {
let result = self.call_java_method("camerasAmount", "()I", &[]).unwrap();
let amount = unsafe { result.i };
amount as u32
}
fn switch_camera(&self) {
self.call_java_method("switchCamera", "()V", &[]).unwrap();
}
fn start_camera(&self) {
// Clear image.
let mut w_image = LAST_CAMERA_IMAGE.write().unwrap();
@ -115,6 +105,16 @@ impl PlatformCallbacks for Android {
}
None
}
fn can_switch_camera(&self) -> bool {
let result = self.call_java_method("camerasAmount", "()I", &[]).unwrap();
let amount = unsafe { result.i };
amount > 1
}
fn switch_camera(&self) {
self.call_java_method("switchCamera", "()V", &[]).unwrap();
}
}
lazy_static! {

View file

@ -53,21 +53,6 @@ impl PlatformCallbacks for Desktop {
clipboard.get_text().unwrap_or("".to_string())
}
fn cameras_amount(&self) -> u32 {
let devices = PlatformContext::default().devices();
if devices.is_ok() {
return devices.unwrap().len() as u32;
}
0
}
fn switch_camera(&self) {
let amount = self.cameras_amount();
if amount < 2 {
return;
}
}
fn start_camera(&self) {
// Clear image.
{
@ -157,6 +142,14 @@ impl PlatformCallbacks for Desktop {
}
None
}
fn can_switch_camera(&self) -> bool {
false
}
fn switch_camera(&self) {
return;
}
}
/// Last captured image from started camera.

View file

@ -26,9 +26,9 @@ pub trait PlatformCallbacks {
fn hide_keyboard(&self);
fn copy_string_to_buffer(&self, data: String);
fn get_string_from_buffer(&self) -> String;
fn cameras_amount(&self) -> u32;
fn switch_camera(&self);
fn start_camera(&self);
fn stop_camera(&self);
fn camera_image(&self) -> Option<(Vec<u8>, u32)>;
fn can_switch_camera(&self) -> bool;
fn switch_camera(&self);
}

View file

@ -13,9 +13,12 @@
// limitations under the License.
use std::sync::{Arc, RwLock};
use eframe::emath::Align;
use egui::load::SizedTexture;
use egui::{Pos2, Rect, TextureOptions, Widget};
use egui::{Layout, Pos2, Rect, TextureOptions, Widget};
use image::{DynamicImage, EncodableLayout, ImageFormat};
use crate::gui::Colors;
use crate::gui::icons::CAMERA_ROTATE;
use crate::gui::platform::PlatformCallbacks;
use crate::gui::views::types::QrScanState;
@ -52,7 +55,7 @@ impl CameraContent {
_ => img
};
// Convert to ColorImage to add at content.
let color_image = match &img {
let color_img = match &img {
DynamicImage::ImageRgb8(image) => {
egui::ColorImage::from_rgb(
[image.width() as usize, image.height() as usize],
@ -69,21 +72,37 @@ impl CameraContent {
};
// Create image texture.
let texture = ui.ctx().load_texture("camera_image",
color_image.clone(),
color_img.clone(),
TextureOptions::default());
let image_size = egui::emath::vec2(color_image.width() as f32,
color_image.height() as f32);
let sized_image = SizedTexture::new(texture.id(), image_size);
let img_size = egui::emath::vec2(color_img.width() as f32,
color_img.height() as f32);
let sized_img = SizedTexture::new(texture.id(), img_size);
// Add image to content.
ui.vertical_centered(|ui| {
egui::Image::from_texture(sized_image)
// Setup to make image cropped at center of square.
.uv(Rect::from([Pos2::new(0.25, 0.0), Pos2::new(1.0, 1.0)]))
egui::Image::from_texture(sized_img)
// Setup to crop image at square.
.uv(Rect::from([
Pos2::new(1.0 - (img_size.y / img_size.x), 0.0),
Pos2::new(1.0, 1.0)
]))
.max_height(ui.available_width())
.maintain_aspect_ratio(false)
.shrink_to_fit()
.ui(ui);
});
// Show button to switch cameras.
if cb.can_switch_camera() {
ui.add_space(-52.0);
let mut size = ui.available_size();
size.y = 48.0;
ui.allocate_ui_with_layout(size, Layout::right_to_left(Align::Max), |ui| {
ui.add_space(4.0);
View::button(ui, CAMERA_ROTATE.to_string(), Colors::WHITE, || {
cb.switch_camera();
});
});
}
} else {
self.loading_content_ui(ui);
}
@ -137,7 +156,7 @@ impl CameraContent {
for g in grids {
if let Ok((meta, text)) = g.decode() {
println!("12345 ecc: {}, text: {}", meta.ecc_level, text.clone());
if !text.is_empty() {
if !text.trim().is_empty() {
let mut w_scan = self.qr_scan_state.write().unwrap();
w_scan.qr_scan_result = Some(text);
}