qrcode_png/lib.rs
1//! Create a QR code
2//! ```
3//! use qrcode_png::{QrCode, QrCodeEcc, Color};
4//!
5//! let mut qrcode = QrCode::new(b"Hello Rust !", QrCodeEcc::Medium).unwrap();
6//!
7//! qrcode.zoom(10).margin(10);
8//!
9//! // -------- Bitmap
10//! let buf = qrcode.generate(Color::Bitmap(false, true)).unwrap();
11//! std::fs::write("./qrcode.bitmap.png", buf).unwrap();
12//!
13//! // -------- Grayscale
14//! let buf = qrcode.generate(Color::Grayscale(0, 255)).unwrap();
15//! std::fs::write("./qrcode.grayscale.png", buf).unwrap();
16//!
17//! // -------- RGB
18//! let buf = qrcode
19//! .generate(Color::Rgb([3, 169, 244], [113, 140, 0]))
20//! .unwrap();
21//! std::fs::write("./qrcode.rgb.png", buf).unwrap();
22//!
23//! // -------- RGBA
24//! let buf = qrcode
25//! .generate(Color::Rgba([137, 89, 168, 255], [255, 255, 255, 0]))
26//! .unwrap();
27//! std::fs::write("./qrcode.rgba.png", buf).unwrap();
28//! ```
29
30mod image;
31
32pub use image::Color;
33use image::Png;
34use png::EncodingError;
35pub use qrcodegen::QrCodeEcc;
36use qrcodegen::{DataTooLong, QrCode as QrCode_};
37
38/// Define QR code
39#[derive(Clone)]
40pub struct QrCode {
41 // QR Code
42 qr: QrCode_,
43 // Zoom factor
44 zoom: u32,
45 // Margin of the QR code from the picture
46 margin: u32,
47}
48
49impl QrCode {
50 /// Create a QR code
51 pub fn new<T: AsRef<[u8]>>(content: T, ecl: QrCodeEcc) -> Result<Self, DataTooLong> {
52 let qr = QrCode_::encode_binary(content.as_ref(), ecl)?;
53
54 Ok(Self {
55 qr,
56 zoom: 1,
57 margin: 0,
58 })
59 }
60
61 /// Enlarge the QR code according to the original scale,
62 /// Default value: 1
63 pub fn zoom(&mut self, zoom: u32) -> &mut Self {
64 assert_ne!(zoom, 0, "The minimum value is 1");
65 self.zoom = zoom;
66 self
67 }
68
69 /// Set the distance between the QR code and the edge of the picture
70 pub fn margin(&mut self, margin: u32) -> &mut Self {
71 self.margin = margin;
72 self
73 }
74
75 /// Get png data of QR code
76 pub fn generate(&self, color: Color) -> Result<Vec<u8>, EncodingError> {
77 let size = self.qr.size() as u32 * self.zoom + self.margin * 2;
78
79 let mut image = Png::new(size as usize, size as usize, color);
80
81 for x in 0..self.qr.size() {
82 for y in 0..self.qr.size() {
83 if self.qr.get_module(x, y) {
84 let x_start = (x as u32 * self.zoom) + self.margin;
85 let y_start = (y as u32 * self.zoom) + self.margin;
86
87 for x in x_start..x_start + self.zoom {
88 for y in y_start..y_start + self.zoom {
89 image.set_color(x as usize, y as usize);
90 }
91 }
92 }
93 }
94 }
95
96 image.encode()
97 }
98}