05b1714628
🔴 QR 扫描失败根因 (2项): - render/png: saturating_sub 导致 margin 区域映射到 finder 黑角, quiet zone 全黑,扫描器无法定位 QR - matrix/patterns: 缺少右上 finder 左侧 + 左下 finder 顶部 隔离带预留,数据模块破坏 finder 检测比率(1:1:3:1:1) 🔴 GUI 导出失败 (2项): - gui/Cargo.toml + gui/lib.rs: 注册 tauri-plugin-fs 后端插件 (前端 writeFile 调用缺少 Rust handler) - capabilities: fs:allow-write-file + $HOME/** 路径 scope (ACL 默认不给 fs 写权限,需显式声明) 🔧 其他: - ExportPanel: 导出失败显示红色错误信息(替代静默吞错) Co-Authored-By: Claude <noreply@anthropic.com>
53 lines
1.6 KiB
Rust
53 lines
1.6 KiB
Rust
use crate::qr::QrCode;
|
||
use image::{ImageBuffer, Luma};
|
||
|
||
/// 将单个模块填充到图像缓冲区(module_size × module_size 像素块)
|
||
fn fill_module(
|
||
img: &mut ImageBuffer<Luma<u8>, Vec<u8>>,
|
||
x: u32,
|
||
y: u32,
|
||
module_size: u32,
|
||
is_dark: bool,
|
||
) {
|
||
let px_val = if is_dark { 0u8 } else { 255u8 };
|
||
let x0 = x * module_size;
|
||
let y0 = y * module_size;
|
||
for dy in 0..module_size {
|
||
for dx in 0..module_size {
|
||
img.put_pixel(x0 + dx, y0 + dy, Luma([px_val]));
|
||
}
|
||
}
|
||
}
|
||
|
||
pub fn render_png(qr: &QrCode, module_size: u8) -> Result<Vec<u8>, image::ImageError> {
|
||
let matrix_size = qr.size() as u32;
|
||
let margin = qr.margin as u32;
|
||
let total_size = matrix_size + 2 * margin;
|
||
let img_size = total_size * module_size as u32;
|
||
|
||
let mut img = ImageBuffer::new(img_size, img_size);
|
||
|
||
for y in 0..total_size {
|
||
for x in 0..total_size {
|
||
// 直接比较坐标与 margin 边界,避免 saturating_sub 在边界处回绕到 0
|
||
let is_dark = if x >= margin
|
||
&& x < margin + matrix_size
|
||
&& y >= margin
|
||
&& y < margin + matrix_size
|
||
{
|
||
let mx = (x - margin) as usize;
|
||
let my = (y - margin) as usize;
|
||
qr.modules()[my][mx]
|
||
} else {
|
||
false // 白边 (quiet zone)
|
||
};
|
||
|
||
fill_module(&mut img, x, y, module_size as u32, is_dark);
|
||
}
|
||
}
|
||
|
||
let mut buf = Vec::new();
|
||
img.write_to(&mut std::io::Cursor::new(&mut buf), image::ImageFormat::Png)?;
|
||
Ok(buf)
|
||
}
|