qr: fix GIF creation

This commit is contained in:
ardocrat 2024-05-30 17:27:55 +03:00
parent 4c77faff60
commit 69b7fc2fac
4 changed files with 40 additions and 21 deletions

10
Cargo.lock generated
View file

@ -3775,6 +3775,7 @@ dependencies = [
"nokhwa",
"openssl-sys",
"parking_lot 0.12.3",
"qrcode",
"qrcodegen",
"rand 0.8.5",
"rfd",
@ -6985,6 +6986,15 @@ version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5520fbcd7da152a449261c5a533a1c7fad044e9e8aa9528cfec3f464786c7926"
[[package]]
name = "qrcode"
version = "0.14.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "23e719ca51966ff9f5a8436edb00d6115b3c606a0bb27c8f8ca74a38ff2b036d"
dependencies = [
"image 0.25.1",
]
[[package]]
name = "qrcodegen"
version = "1.8.0"

View file

@ -59,6 +59,7 @@ tokio = { version = "1.37.0", features = ["full"] }
image = "0.25.1"
rqrr = "0.7.1"
qrcodegen = "1.8.0"
qrcode = "0.14.0"
ur = "0.4.1"
gif = "0.13.1"

View file

@ -345,34 +345,42 @@ impl QrCodeContent {
let mut ur_enc = ur::Encoder::bytes(text.as_bytes(), 100).unwrap();
for _ in 0..ur_enc.fragment_count() {
let ur = ur_enc.next_part().unwrap();
if let Ok(qr) = QrCode::encode_text(ur.as_str(), qrcodegen::QrCodeEcc::Low) {
qrs.push(qr);
if let Ok(qr) = qrcode::QrCode::with_error_correction_level(
ur.as_bytes(),
qrcode::EcLevel::L
) {
// Create an image from QR data.
let image = qr.render()
.max_dimensions(size as u32, size as u32)
.dark_color(image::Rgb([0, 0, 0]))
.light_color(image::Rgb([255, 255, 255]))
.build();
qrs.push(image);
}
}
// Generate GIF data.
let color_map = &[0, 0, 0, 0xFF, 0xFF, 0xFF];
let mut gif_enc = gif::Encoder::new(&mut gif,
size as u16,
size as u16,
color_map).unwrap();
gif_enc.set_repeat(gif::Repeat::Infinite).unwrap();
for qr in qrs {
// Create an image from QR data and write it to encoder.
if let Some(image) = Self::qr_to_image_data(qr, size) {
let mut frame = gif::Frame::from_indexed_pixels(size as u16,
size as u16,
image.as_slice(),
None);
if !qrs.is_empty() {
// Generate GIF data.
let color_map = &[0, 0, 0, 0xFF, 0xFF, 0xFF];
let mut gif_enc = gif::Encoder::new(&mut gif,
qrs[0].width() as u16,
qrs[0].height() as u16,
color_map).unwrap();
gif_enc.set_repeat(gif::Repeat::Infinite).unwrap();
for qr in qrs {
let mut frame = gif::Frame::from_rgb(qr.width() as u16,
qr.height() as u16,
qr.as_raw().as_slice());
frame.delay = 10;
// Write an image to GIF encoder.
if let Ok(_) = gif_enc.write_frame(&frame) {
continue;
}
// Exit on error.
let mut w_state = qr_state.write();
w_state.gif_creating = false;
return;
}
// Exit on error.
let mut w_state = qr_state.write();
w_state.gif_creating = false;
return;
}
}
// Setup GIF image data.

View file

@ -518,7 +518,7 @@ impl View {
// Draw box content.
let content_resp = ui.allocate_ui_at_rect(rect, |ui| {
ui.vertical_centered_justified(|ui| {
ui.add_space(3.0);
ui.add_space(4.0);
ui.scope(|ui| {
// Correct vertical spacing between items.
ui.style_mut().spacing.item_spacing.y = -3.0;