1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
|
use poise::serenity_prelude as serenity;
use crate::Data;
use crate::error::{Error, Result};
use crate::lang;
type Context<'a> = poise::Context<'a, Data, Error>;
/// QR group
#[poise::command(slash_command, subcommands("dekodowanie", "generowanie",))]
pub async fn qr(_ctx: Context<'_>) -> Result<()> {
Ok(())
}
/// Generate a QR code from text
#[poise::command(slash_command)]
pub async fn generowanie(
ctx: Context<'_>,
#[description = "Zawartość kodu QR"] text: String,
) -> Result<()> {
ctx.defer().await?;
let code = qrcode::QrCode::new(text.as_bytes())?;
let image = code.render::<image::Luma<u8>>().build();
let scaled = image::imageops::resize(
&image,
image.width() * 10,
image.height() * 10,
image::imageops::Nearest,
);
let mut buf = std::io::Cursor::new(Vec::new());
scaled.write_to(&mut buf, image::ImageFormat::Png)?;
ctx.send(
poise::CreateReply::default()
.content(lang::L_QR_GENERATED)
.attachment(serenity::CreateAttachment::bytes(
buf.into_inner(),
"qrcode.png",
)),
)
.await?;
Ok(())
}
/// Decode a QR code from an uploaded image
#[poise::command(slash_command)]
pub async fn dekodowanie(
ctx: Context<'_>,
#[description = "Obraz zawierający kod QR"] image: serenity::Attachment,
) -> Result<()> {
ctx.defer().await?;
let img_data = ctx
.data()
.http_client
.get(&image.url)
.send()
.await?
.bytes()
.await?;
let img = image::load_from_memory(&img_data)?;
let gray = img.to_luma8();
let decoded = decode_qr_simple(&gray);
match decoded {
Some(text) => {
ctx.say(lang::fmt_qr_decoded(&text)).await?;
}
None => {
ctx.say(lang::L_QR_DECODE_FAILED).await?;
}
}
Ok(())
}
fn decode_qr_simple(img: &image::ImageBuffer<image::Luma<u8>, Vec<u8>>) -> Option<String> {
rxing::helpers::detect_in_luma(img.as_raw().to_vec(), img.width(), img.height(), None)
.ok()
.map(|r| r.getText().to_owned())
}
pub fn commands() -> Vec<poise::Command<Data, Error>> {
vec![qr()]
}
|