captcha
captcha copied to clipboard
Can you support generating a captcha by specific text instead of random text?
I didn't find way to generate a captcha by specific text,can you add the support?
Hi, guys, I support this question
@omega4github , I found only this example of captcha generation from predefined symbols:
extern crate captcha;
use captcha::filters::{Cow, Noise, Wave};
use captcha::{Captcha, Geometry};
use std::path::Path;
fn main() {
let mut c = Captcha::new();
println!("{:?}", c.supported_chars());
c.set_chars(&['0', '1', '2', '3', '4', '5', '6', '7', '8'])
.add_chars(4)
.apply_filter(Noise::new(0.2))
.apply_filter(Wave::new(2.0, 20.0))
.view(220, 120)
.apply_filter(
Cow::new()
.min_radius(40)
.max_radius(50)
.circles(1)
.area(Geometry::new(40, 150, 50, 70)),
)
.set_color([255, 128, 0]);
c.save(Path::new("captcha.png")).expect("save failed");
println!("{}", c.chars_as_string());
}
Try implementing something like this:
/// sets text of captcha
pub fn set_text(&mut self, vec: &[char]) -> &mut Self {
for char in vec {
if let Some((c, i)) = self.random_char_as_image(Some(char)) {
let x = self.text_area.right;
let y = (self.text_area.bottom + self.text_area.top) / 2 - i.height() / 2;
self.img.add_image(x, y, &i);
self.text_area.top = min(self.text_area.top, y);
self.text_area.right = x + i.width() - 1;
self.text_area.bottom = max(self.text_area.bottom, y + i.height() - 1);
self.chars.push(c);
}
}
self
}
// accept optional char
fn random_char_as_image(&mut self, c: Option<&char>) -> Option<(char, Image)> {
match c {
Some(val) => match self.font.png(*val) {
Some(p) => Image::from_png(p).map(|i| (*val, i)),
None => None,
},
None => match self.use_font_chars.choose(&mut self.rng) {
None => None,
Some(c) => match self.font.png(*c) {
None => None,
Some(p) => Image::from_png(p).map(|i| (*c, i)),
},
}
}
}