camera: desktop support, switch camera, fix image crop
This commit is contained in:
parent
7267bf6441
commit
11ac0ea84b
5 changed files with 50 additions and 38 deletions
|
@ -325,7 +325,7 @@ public class MainActivity extends GameActivity {
|
||||||
|
|
||||||
// Called from native code to switch camera.
|
// Called from native code to switch camera.
|
||||||
public void switchCamera() {
|
public void switchCamera() {
|
||||||
mUseBackCamera = true;
|
mUseBackCamera = !mUseBackCamera;
|
||||||
stopCamera();
|
stopCamera();
|
||||||
startCamera();
|
startCamera();
|
||||||
}
|
}
|
||||||
|
|
|
@ -82,16 +82,6 @@ impl PlatformCallbacks for Android {
|
||||||
paste_data
|
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) {
|
fn start_camera(&self) {
|
||||||
// Clear image.
|
// Clear image.
|
||||||
let mut w_image = LAST_CAMERA_IMAGE.write().unwrap();
|
let mut w_image = LAST_CAMERA_IMAGE.write().unwrap();
|
||||||
|
@ -115,6 +105,16 @@ impl PlatformCallbacks for Android {
|
||||||
}
|
}
|
||||||
None
|
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! {
|
lazy_static! {
|
||||||
|
|
|
@ -53,21 +53,6 @@ impl PlatformCallbacks for Desktop {
|
||||||
clipboard.get_text().unwrap_or("".to_string())
|
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) {
|
fn start_camera(&self) {
|
||||||
// Clear image.
|
// Clear image.
|
||||||
{
|
{
|
||||||
|
@ -157,6 +142,14 @@ impl PlatformCallbacks for Desktop {
|
||||||
}
|
}
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn can_switch_camera(&self) -> bool {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
|
||||||
|
fn switch_camera(&self) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Last captured image from started camera.
|
/// Last captured image from started camera.
|
||||||
|
|
|
@ -26,9 +26,9 @@ pub trait PlatformCallbacks {
|
||||||
fn hide_keyboard(&self);
|
fn hide_keyboard(&self);
|
||||||
fn copy_string_to_buffer(&self, data: String);
|
fn copy_string_to_buffer(&self, data: String);
|
||||||
fn get_string_from_buffer(&self) -> String;
|
fn get_string_from_buffer(&self) -> String;
|
||||||
fn cameras_amount(&self) -> u32;
|
|
||||||
fn switch_camera(&self);
|
|
||||||
fn start_camera(&self);
|
fn start_camera(&self);
|
||||||
fn stop_camera(&self);
|
fn stop_camera(&self);
|
||||||
fn camera_image(&self) -> Option<(Vec<u8>, u32)>;
|
fn camera_image(&self) -> Option<(Vec<u8>, u32)>;
|
||||||
|
fn can_switch_camera(&self) -> bool;
|
||||||
|
fn switch_camera(&self);
|
||||||
}
|
}
|
|
@ -13,9 +13,12 @@
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
use std::sync::{Arc, RwLock};
|
use std::sync::{Arc, RwLock};
|
||||||
|
use eframe::emath::Align;
|
||||||
use egui::load::SizedTexture;
|
use egui::load::SizedTexture;
|
||||||
use egui::{Pos2, Rect, TextureOptions, Widget};
|
use egui::{Layout, Pos2, Rect, TextureOptions, Widget};
|
||||||
use image::{DynamicImage, EncodableLayout, ImageFormat};
|
use image::{DynamicImage, EncodableLayout, ImageFormat};
|
||||||
|
use crate::gui::Colors;
|
||||||
|
use crate::gui::icons::CAMERA_ROTATE;
|
||||||
|
|
||||||
use crate::gui::platform::PlatformCallbacks;
|
use crate::gui::platform::PlatformCallbacks;
|
||||||
use crate::gui::views::types::QrScanState;
|
use crate::gui::views::types::QrScanState;
|
||||||
|
@ -52,7 +55,7 @@ impl CameraContent {
|
||||||
_ => img
|
_ => img
|
||||||
};
|
};
|
||||||
// Convert to ColorImage to add at content.
|
// Convert to ColorImage to add at content.
|
||||||
let color_image = match &img {
|
let color_img = match &img {
|
||||||
DynamicImage::ImageRgb8(image) => {
|
DynamicImage::ImageRgb8(image) => {
|
||||||
egui::ColorImage::from_rgb(
|
egui::ColorImage::from_rgb(
|
||||||
[image.width() as usize, image.height() as usize],
|
[image.width() as usize, image.height() as usize],
|
||||||
|
@ -69,21 +72,37 @@ impl CameraContent {
|
||||||
};
|
};
|
||||||
// Create image texture.
|
// Create image texture.
|
||||||
let texture = ui.ctx().load_texture("camera_image",
|
let texture = ui.ctx().load_texture("camera_image",
|
||||||
color_image.clone(),
|
color_img.clone(),
|
||||||
TextureOptions::default());
|
TextureOptions::default());
|
||||||
let image_size = egui::emath::vec2(color_image.width() as f32,
|
let img_size = egui::emath::vec2(color_img.width() as f32,
|
||||||
color_image.height() as f32);
|
color_img.height() as f32);
|
||||||
let sized_image = SizedTexture::new(texture.id(), image_size);
|
let sized_img = SizedTexture::new(texture.id(), img_size);
|
||||||
// Add image to content.
|
// Add image to content.
|
||||||
ui.vertical_centered(|ui| {
|
ui.vertical_centered(|ui| {
|
||||||
egui::Image::from_texture(sized_image)
|
egui::Image::from_texture(sized_img)
|
||||||
// Setup to make image cropped at center of square.
|
// Setup to crop image at square.
|
||||||
.uv(Rect::from([Pos2::new(0.25, 0.0), Pos2::new(1.0, 1.0)]))
|
.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())
|
.max_height(ui.available_width())
|
||||||
.maintain_aspect_ratio(false)
|
.maintain_aspect_ratio(false)
|
||||||
.shrink_to_fit()
|
.shrink_to_fit()
|
||||||
.ui(ui);
|
.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 {
|
} else {
|
||||||
self.loading_content_ui(ui);
|
self.loading_content_ui(ui);
|
||||||
}
|
}
|
||||||
|
@ -137,7 +156,7 @@ impl CameraContent {
|
||||||
for g in grids {
|
for g in grids {
|
||||||
if let Ok((meta, text)) = g.decode() {
|
if let Ok((meta, text)) = g.decode() {
|
||||||
println!("12345 ecc: {}, text: {}", meta.ecc_level, text.clone());
|
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();
|
let mut w_scan = self.qr_scan_state.write().unwrap();
|
||||||
w_scan.qr_scan_result = Some(text);
|
w_scan.qr_scan_result = Some(text);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue