auto search shiny done.
This commit is contained in:
parent
ea08b62096
commit
87ca8c6ec8
|
@ -241,6 +241,27 @@ dependencies = [
|
|||
"windows",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "errno"
|
||||
version = "0.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6b30f669a7961ef1631673d2766cc92f52d64f7ef354d4fe0ddfd30ed52f0f4f"
|
||||
dependencies = [
|
||||
"errno-dragonfly",
|
||||
"libc",
|
||||
"windows-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "errno-dragonfly"
|
||||
version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "exr"
|
||||
version = "1.7.0"
|
||||
|
@ -257,6 +278,12 @@ dependencies = [
|
|||
"zune-inflate",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fastrand"
|
||||
version = "2.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6999dc1837253364c2ebb0704ba97994bd874e8f195d665c50b7548f6ea92764"
|
||||
|
||||
[[package]]
|
||||
name = "fdeflate"
|
||||
version = "0.3.0"
|
||||
|
@ -400,6 +427,12 @@ dependencies = [
|
|||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "lazy_static"
|
||||
version = "1.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
||||
|
||||
[[package]]
|
||||
name = "lebe"
|
||||
version = "0.5.2"
|
||||
|
@ -422,6 +455,12 @@ dependencies = [
|
|||
"pkg-config",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "linux-raw-sys"
|
||||
version = "0.4.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "57bcfdad1b858c2db7c38303a6d2ad4dfaf5eb53dfeb0910128b2c26d6158503"
|
||||
|
||||
[[package]]
|
||||
name = "lock_api"
|
||||
version = "0.4.10"
|
||||
|
@ -434,9 +473,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "log"
|
||||
version = "0.4.19"
|
||||
version = "0.4.20"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b06a4cde4c0f271a446782e3eff8de789548ce57dbc8eca9292c27f4a42004b4"
|
||||
checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f"
|
||||
|
||||
[[package]]
|
||||
name = "malloc_buf"
|
||||
|
@ -500,7 +539,11 @@ dependencies = [
|
|||
"crossterm",
|
||||
"enigo",
|
||||
"image",
|
||||
"log",
|
||||
"rand",
|
||||
"rusty-tesseract",
|
||||
"screenshots",
|
||||
"simple-logging",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -576,7 +619,7 @@ checksum = "93f00c865fe7cabf650081affecd3871070f26767e7b2070a3ffae14c654b447"
|
|||
dependencies = [
|
||||
"cfg-if",
|
||||
"libc",
|
||||
"redox_syscall",
|
||||
"redox_syscall 0.3.5",
|
||||
"smallvec",
|
||||
"windows-targets",
|
||||
]
|
||||
|
@ -626,6 +669,12 @@ dependencies = [
|
|||
"miniz_oxide",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ppv-lite86"
|
||||
version = "0.2.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de"
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.66"
|
||||
|
@ -662,6 +711,36 @@ dependencies = [
|
|||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand"
|
||||
version = "0.8.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"rand_chacha",
|
||||
"rand_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_chacha"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
|
||||
dependencies = [
|
||||
"ppv-lite86",
|
||||
"rand_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_core"
|
||||
version = "0.6.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
|
||||
dependencies = [
|
||||
"getrandom",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rayon"
|
||||
version = "1.7.0"
|
||||
|
@ -684,6 +763,12 @@ dependencies = [
|
|||
"num_cpus",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "redox_syscall"
|
||||
version = "0.1.57"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "41cc0f7e4d5d4544e8861606a285bb08d3e70712ccc7d2b84d7c0ccfaf4b05ce"
|
||||
|
||||
[[package]]
|
||||
name = "redox_syscall"
|
||||
version = "0.3.5"
|
||||
|
@ -693,6 +778,32 @@ dependencies = [
|
|||
"bitflags 1.3.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustix"
|
||||
version = "0.38.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "19ed4fa021d81c8392ce04db050a3da9a60299050b7ae1cf482d862b54a7218f"
|
||||
dependencies = [
|
||||
"bitflags 2.4.0",
|
||||
"errno",
|
||||
"libc",
|
||||
"linux-raw-sys",
|
||||
"windows-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rusty-tesseract"
|
||||
version = "1.1.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "af2176026d24dbb67968571c7d464d287934820490ece864e17b88d2e5e3eee8"
|
||||
dependencies = [
|
||||
"image",
|
||||
"subprocess",
|
||||
"substring",
|
||||
"tempfile",
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "scopeguard"
|
||||
version = "1.2.0"
|
||||
|
@ -753,6 +864,17 @@ version = "0.3.7"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d66dc143e6b11c1eddc06d5c423cfc97062865baf299914ab64caa38182078fe"
|
||||
|
||||
[[package]]
|
||||
name = "simple-logging"
|
||||
version = "2.0.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b00d48e85675326bb182a2286ea7c1a0b264333ae10f27a937a72be08628b542"
|
||||
dependencies = [
|
||||
"lazy_static",
|
||||
"log",
|
||||
"thread-id",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "smallvec"
|
||||
version = "1.11.0"
|
||||
|
@ -768,6 +890,25 @@ dependencies = [
|
|||
"lock_api",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "subprocess"
|
||||
version = "0.2.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0c2e86926081dda636c546d8c5e641661049d7562a68f5488be4a1f7f66f6086"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "substring"
|
||||
version = "1.4.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "42ee6433ecef213b2e72f587ef64a2f5943e7cd16fbd82dbe8bc07486c534c86"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "2.0.28"
|
||||
|
@ -779,6 +920,50 @@ dependencies = [
|
|||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tempfile"
|
||||
version = "3.7.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dc02fddf48964c42031a0b3fe0428320ecf3a73c401040fc0096f97794310651"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"fastrand",
|
||||
"redox_syscall 0.3.5",
|
||||
"rustix",
|
||||
"windows-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror"
|
||||
version = "1.0.44"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "611040a08a0439f8248d1990b111c95baa9c704c805fa1f62104b39655fd7f90"
|
||||
dependencies = [
|
||||
"thiserror-impl",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror-impl"
|
||||
version = "1.0.44"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "090198534930841fab3a5d1bb637cde49e339654e606195f8d9c76eeb081dc96"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thread-id"
|
||||
version = "3.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c7fbf4c9d56b320106cd64fd024dadfa0be7cb4706725fc44a7d7ce952d820c1"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"redox_syscall 0.1.57",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tiff"
|
||||
version = "0.8.1"
|
||||
|
|
13
Cargo.toml
13
Cargo.toml
|
@ -10,10 +10,10 @@ edition = "2021"
|
|||
|
||||
default = ["pokemmo"]
|
||||
|
||||
pokemmo = ["screen","ocr","joystick","dep:image","pokemon","detector"]
|
||||
pokemmo = ["screen", "ocr", "joystick", "dep:image", "pokemon", "detector"]
|
||||
screen = ["dep:screenshots"]
|
||||
ocr = []
|
||||
joystick = ["dep:enigo"]
|
||||
ocr = ["dep:rusty-tesseract", "dep:image"]
|
||||
joystick = ["dep:enigo","dep:rand"]
|
||||
pokemon = []
|
||||
detector = ["dep:crossterm"]
|
||||
|
||||
|
@ -26,5 +26,8 @@ path = "src/lib.rs"
|
|||
log = "0.4.20"
|
||||
enigo = { version = "0.1.2", optional = true }
|
||||
screenshots = { version = "0.7.0", optional = true }
|
||||
image = {version = "0.24.6", optional = true}
|
||||
crossterm = {version = "0.27.0", optional = true}
|
||||
image = { version = "0.24.6", optional = true }
|
||||
crossterm = { version = "0.27.0", optional = true }
|
||||
rusty-tesseract = { version = "1.1.7", optional = true }
|
||||
rand = { version = "0.8.5", optional = true }
|
||||
simple-logging = {version = "2.0.2"}
|
|
@ -0,0 +1,58 @@
|
|||
#[cfg(feature = "joystick")]
|
||||
pub(crate) mod joystick{
|
||||
use std::thread;
|
||||
use std::time::Duration;
|
||||
use enigo::{Enigo, Key, KeyboardControllable};
|
||||
use rand::Rng;
|
||||
|
||||
pub enum MoveMode{
|
||||
// 横向
|
||||
HORIZONTAL,
|
||||
// 纵向
|
||||
PORTRAIT,
|
||||
// 随机
|
||||
RANDOM,
|
||||
}
|
||||
|
||||
impl MoveMode {
|
||||
pub fn to_key_list(&self) -> Vec<Key>{
|
||||
return match self {
|
||||
MoveMode::HORIZONTAL => vec![Key::Layout('j'),Key::Layout('l')],
|
||||
MoveMode::PORTRAIT => vec![Key::UpArrow,Key::DownArrow],
|
||||
MoveMode:: RANDOM => vec![Key::LeftArrow,Key::RightArrow,Key::UpArrow,Key::DownArrow],
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
pub(crate) fn move_once_by_mode(road : &MoveMode, index : usize){
|
||||
let mut enigo = Enigo::new();
|
||||
let moves = road.to_key_list();
|
||||
let move_index = index % moves.len();
|
||||
let move_key = moves[move_index];
|
||||
long_press(enigo,move_key,1000,500);
|
||||
}
|
||||
|
||||
pub(crate) fn once_press(mut enigo:Enigo, key: Key){
|
||||
enigo.key_click(key);
|
||||
}
|
||||
|
||||
pub(crate) fn quick_press(key: Key){
|
||||
let mut enigo = Enigo::new();
|
||||
let mut rng = rand::thread_rng();
|
||||
enigo.key_down(key);
|
||||
thread::sleep(Duration::from_millis(rng.gen_range(0 .. 20)));
|
||||
enigo.key_up(key);
|
||||
}
|
||||
|
||||
pub(crate) fn long_press(mut enigo:Enigo, key: Key, est_time: isize, random_time: isize){
|
||||
let mut rng = rand::thread_rng();
|
||||
enigo.key_down(key);
|
||||
let act = est_time + rng.gen_range((-random_time .. random_time));
|
||||
thread::sleep(Duration::from_millis(act as u64));
|
||||
enigo.key_up(key);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::joystick::joystick::joystick::{move_once_by_mode, MoveMode};
|
||||
|
||||
#[test]
|
||||
fn try_move() {
|
||||
let mut count = 0;
|
||||
let mode = MoveMode::HORIZONTAL;
|
||||
while count < 100 {
|
||||
move_once_by_mode(&mode, 0);
|
||||
count = count + 1;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,2 @@
|
|||
pub mod joystick;
|
||||
pub mod joystick_test;
|
|
@ -2,4 +2,5 @@ pub(crate) mod screen;
|
|||
pub(crate) mod joystick;
|
||||
pub(crate) mod pokemmo;
|
||||
pub(crate) mod pokemon;
|
||||
pub(crate) mod detector;
|
||||
pub(crate) mod detector;
|
||||
pub(crate) mod ocr;
|
|
@ -0,0 +1,2 @@
|
|||
pub(crate) mod ocr;
|
||||
mod ocr_test;
|
|
@ -0,0 +1,65 @@
|
|||
#[cfg(feature = "ocr")]
|
||||
pub(crate) mod ocr {
|
||||
use std::error::Error;
|
||||
use image::DynamicImage;
|
||||
use rusty_tesseract::{Args, Image};
|
||||
|
||||
/**
|
||||
|
||||
OEM 解释
|
||||
0 仅旧版引擎
|
||||
1 仅神经网络 LSTM 引擎
|
||||
2 个旧版 + LSTM 引擎
|
||||
3 默认,基于可用的内容
|
||||
|
||||
|
||||
PSM 解释 :
|
||||
0 仅方向和脚本检测 (OSD)。
|
||||
1 使用 OSD 自动页面分割。
|
||||
2 自动页面分割,但没有 OSD 或 OCR。 (未实现)
|
||||
3 全自动页面分割,但无OSD。 (默认)
|
||||
4 假设有一列大小可变的文本。
|
||||
5 假设有一个统一的垂直对齐文本块。
|
||||
6 假设有一个统一的文本块。
|
||||
7 将图像视为单个文本行。
|
||||
8 将图像视为单个单词。
|
||||
9 将图像视为圆圈中的单个单词。
|
||||
10 将图像视为单个字符。
|
||||
11 稀疏文本。 查找尽可能多的文本(不按特定顺序排列)。
|
||||
12 带 OSD 的稀疏文本。
|
||||
13 原始线。 将图像视为单个文本行,
|
||||
|
||||
*/
|
||||
|
||||
pub(crate) fn find_string_in_image(image: &DynamicImage, psm:i32) -> String {
|
||||
let img = Image::from_dynamic_image(image).expect("from image failed");
|
||||
let mut args = Args {
|
||||
lang: "chi_sim".to_string(),
|
||||
config_variables: Default::default(),
|
||||
dpi: Some(300),
|
||||
psm: Some(psm),
|
||||
oem: Some(3),
|
||||
};
|
||||
let output = rusty_tesseract::image_to_string(&img, &args).expect("image to string failed");
|
||||
return output;
|
||||
}
|
||||
|
||||
|
||||
pub(crate) fn find_text_in_image(key_words: &Vec<String>, image: &DynamicImage) -> bool {
|
||||
let img = Image::from_dynamic_image(image).expect("from image failed");
|
||||
let mut args = Args {
|
||||
lang: "chi_sim".to_string(),
|
||||
config_variables: Default::default(),
|
||||
dpi: Some(600),
|
||||
psm: Some(6),
|
||||
oem: Some(3),
|
||||
};
|
||||
let output = rusty_tesseract::image_to_string(&img, &args).expect("image to string failed");
|
||||
for word in key_words{
|
||||
if output.contains(word){
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
#[cfg(test)]
|
||||
mod tests {
|
||||
use std::collections::HashMap;
|
||||
use image::io::Reader;
|
||||
use rusty_tesseract::{Args, Image};
|
||||
use crate::ocr::ocr::ocr::find_text_in_image;
|
||||
|
||||
|
||||
#[test]
|
||||
fn test_ocr_image() {
|
||||
println!("ocr !");
|
||||
|
||||
// let img = Image::from_path("test/image/group_5.png").expect("image not found");
|
||||
let img = Image::from_path("test/image/sb.png").expect("image not found");
|
||||
let mut args = Args {
|
||||
lang: "chi_sim".to_string(),
|
||||
config_variables: Default::default(),
|
||||
dpi: Some(300),
|
||||
psm: Some(1),
|
||||
oem: Some(3),
|
||||
};
|
||||
|
||||
// string output
|
||||
let output = rusty_tesseract::image_to_string(&img, &args).expect("ocr error!");
|
||||
println!("The String output is: {:?}", output);
|
||||
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_ocr_dynamic_image() {
|
||||
let dynamic_image = Reader::open("test/image/1.png")
|
||||
.unwrap()
|
||||
.decode()
|
||||
.unwrap();
|
||||
let key_words = vec!["头目".to_string(),"白银山".to_string()];
|
||||
let has_word = find_text_in_image(&key_words,&dynamic_image);
|
||||
|
||||
println!("含有关键词:{}",has_word);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
|
@ -7,25 +7,142 @@ pub mod pokemmo_const_value{
|
|||
right: 80,
|
||||
top: 0,
|
||||
bottom: 20,
|
||||
psm : 3,
|
||||
};
|
||||
pub(crate) const MAP_CITY: Area = Area{
|
||||
left: 0,
|
||||
right: 250,
|
||||
top: 24,
|
||||
bottom: 55,
|
||||
psm : 7,
|
||||
};
|
||||
pub(crate) const SHORTCUT_KEY_1: Area = Area{
|
||||
left: 255,
|
||||
right: 298,
|
||||
top: 28,
|
||||
bottom: 70,
|
||||
psm : 8,
|
||||
};
|
||||
pub(crate) const SHORTCUT_KEY_5: Area = Area{
|
||||
left: 445,
|
||||
right: 485,
|
||||
top: 28,
|
||||
bottom: 70,
|
||||
psm : 8,
|
||||
};
|
||||
pub(crate) const TEXT_AREA: Area = Area{
|
||||
left: 0,
|
||||
right: 800,
|
||||
top: 1020,
|
||||
bottom: 1340,
|
||||
psm : 6,
|
||||
};
|
||||
// 战斗对话狂
|
||||
pub(crate) const TEMP_BATTLE_TEXT_AREA: Area = Area{
|
||||
left: 400,
|
||||
right: 1100,
|
||||
top: 850,
|
||||
bottom: 1020,
|
||||
psm : 6,
|
||||
};
|
||||
pub(crate) const LAST_TEXT_AREA: Area = Area{
|
||||
left: 0,
|
||||
right: 800,
|
||||
top: 1295,
|
||||
bottom: 1340,
|
||||
psm : 7,
|
||||
};
|
||||
pub(crate) const SINGLE_BATTLE: Area = Area{
|
||||
left: 400,
|
||||
right: 800,
|
||||
top: 180,
|
||||
bottom: 260,
|
||||
psm : 3,
|
||||
};
|
||||
pub(crate) const GROUP_5_1: Area = Area{
|
||||
left: 700,
|
||||
right: 1050,
|
||||
top: 90,
|
||||
bottom: 148,
|
||||
psm : 3,
|
||||
};
|
||||
pub(crate) const GROUP_5_2: Area = Area{
|
||||
left: 1100,
|
||||
right: 1400,
|
||||
top: 90,
|
||||
bottom: 148,
|
||||
psm : 3,
|
||||
};
|
||||
pub(crate) const GROUP_5_3: Area = Area{
|
||||
left: 1500,
|
||||
right: 1800,
|
||||
top: 90,
|
||||
bottom: 148,
|
||||
psm : 3,
|
||||
};
|
||||
pub(crate) const GROUP_5_4: Area = Area{
|
||||
left: 740,
|
||||
right: 1050,
|
||||
top: 170,
|
||||
bottom: 210,
|
||||
psm : 3,
|
||||
};
|
||||
pub(crate) const GROUP_5_5: Area = Area{
|
||||
left: 1500,
|
||||
right: 1800,
|
||||
top: 170,
|
||||
bottom: 210,
|
||||
psm : 3,
|
||||
};
|
||||
|
||||
pub(crate) const BUTTON_HL_1: Area = Area{
|
||||
left: 392,
|
||||
right: 406,
|
||||
top: 863,
|
||||
bottom: 878,
|
||||
psm : 3,
|
||||
};
|
||||
pub(crate) const BUTTON_HL_2: Area = Area{
|
||||
left: 708,
|
||||
right: 722,
|
||||
top: 863,
|
||||
bottom: 878,
|
||||
psm : 3,
|
||||
};
|
||||
pub(crate) const BUTTON_HL_3: Area = Area{
|
||||
left: 392,
|
||||
right: 406,
|
||||
top: 942,
|
||||
bottom: 957,
|
||||
psm : 3,
|
||||
};
|
||||
pub(crate) const BUTTON_HL_4: Area = Area{
|
||||
left: 708,
|
||||
right: 722,
|
||||
top: 942,
|
||||
bottom: 957,
|
||||
psm : 3,
|
||||
};
|
||||
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum PokemmoStatus {
|
||||
// 遇见闪光
|
||||
MeetShiny,
|
||||
// 无状态
|
||||
Free,
|
||||
// 加载遇怪动画
|
||||
LoadBattle,
|
||||
// 遇怪状态
|
||||
InBattle,
|
||||
// 逃跑中
|
||||
Running,
|
||||
// 检查逃跑成功
|
||||
CheckRun,
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -1,34 +1,233 @@
|
|||
#[cfg(feature = "pokemmo")]
|
||||
pub mod pokemmo{
|
||||
use screenshots::Compression;
|
||||
use crate::pokemmo::const_value::pokemmo_const_value::LOGO;
|
||||
use crate::screen::screen::screen::{screen_shot};
|
||||
pub mod pokemmo {
|
||||
use std::thread;
|
||||
use std::time::Duration;
|
||||
|
||||
use enigo::Key;
|
||||
use enigo::Key::{N, V};
|
||||
use image::{DynamicImage, RgbaImage};
|
||||
use image::io::Reader as ImageReader;
|
||||
use log::{error, info, trace};
|
||||
use rand::thread_rng;
|
||||
use rusty_tesseract::Image;
|
||||
use screenshots::Compression;
|
||||
|
||||
use crate::joystick::joystick::joystick::{move_once_by_mode, MoveMode, quick_press};
|
||||
use crate::ocr::ocr::ocr::find_string_in_image;
|
||||
use crate::pokemmo::const_value::pokemmo_const_value::{BUTTON_HL_1, BUTTON_HL_2, BUTTON_HL_3, BUTTON_HL_4, GROUP_5_1, GROUP_5_2, GROUP_5_3, GROUP_5_4, GROUP_5_5, LAST_TEXT_AREA, LOGO, PokemmoStatus, SINGLE_BATTLE, TEMP_BATTLE_TEXT_AREA, TEXT_AREA};
|
||||
use crate::pokemmo::const_value::pokemmo_const_value::PokemmoStatus::{Free, InBattle, LoadBattle, MeetShiny, Running};
|
||||
use crate::screen::screen::screen::{Area, screen_shot};
|
||||
|
||||
// 单遇闪光
|
||||
pub fn single_meet_shiny(key_words: &Vec<String>) {
|
||||
let mut status = PokemmoStatus::Free;
|
||||
let move_mode = MoveMode::HORIZONTAL;
|
||||
|
||||
let mut move_index = 0_usize;
|
||||
let mut meet_pokemmo: String = String::new();
|
||||
loop {
|
||||
trace!("当前状态:{:?}",status);
|
||||
match status {
|
||||
PokemmoStatus::MeetShiny => {
|
||||
return;
|
||||
}
|
||||
PokemmoStatus::Free => {
|
||||
trace!("自由状态,移动一步");
|
||||
move_once_by_mode(&move_mode, move_index);
|
||||
move_index = move_index + 1;
|
||||
let text = get_last_string();
|
||||
trace!("查询战斗文字 : {}",text);
|
||||
if text.contains("野生") || text.contains("派出") {
|
||||
info!("遇怪:{}.",text);
|
||||
meet_pokemmo = text.clone();
|
||||
status = LoadBattle;
|
||||
}else {
|
||||
let temp_battle = read_area(TEMP_BATTLE_TEXT_AREA);
|
||||
if temp_battle.contains("战斗") || temp_battle.contains("逃跑"){
|
||||
status = LoadBattle;
|
||||
}
|
||||
}
|
||||
}
|
||||
PokemmoStatus::LoadBattle => {
|
||||
info!("进入加载动画");
|
||||
let mut btn_index = None;
|
||||
while btn_index == None {
|
||||
trace!("等待按钮加载");
|
||||
let est_index = get_choose_btn();
|
||||
if est_index.is_some() {
|
||||
btn_index = est_index;
|
||||
status = InBattle;
|
||||
}
|
||||
thread::sleep(Duration::from_millis(100));
|
||||
}
|
||||
}
|
||||
PokemmoStatus::InBattle => {
|
||||
trace!("检查遇怪种类..");
|
||||
let text = get_text_list();
|
||||
let filter_text: Vec<String> = text.into_iter().filter(|x| x.contains("野生")).collect();
|
||||
if filter_text.is_empty() {
|
||||
error!("遇怪错误!");
|
||||
return;
|
||||
}
|
||||
let filter_size = filter_text.len();
|
||||
let pokemon_text = filter_text[filter_size - 1].clone();
|
||||
if pokemon_text.contains("怪群") {
|
||||
info!("遇见怪群");
|
||||
let five_names = read_group_5();
|
||||
for name in five_names {
|
||||
for key_word in key_words {
|
||||
if name.contains(key_word) {
|
||||
status = MeetShiny;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
let name = read_area(SINGLE_BATTLE);
|
||||
info!("单遇:{}",name);
|
||||
for key_word in key_words {
|
||||
if name.contains(key_word) || meet_pokemmo.contains(key_word) {
|
||||
info!("遇见{}",key_word);
|
||||
status = MeetShiny;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
// 进入招式界面
|
||||
status = PokemmoStatus::Running
|
||||
}
|
||||
PokemmoStatus::Running => {
|
||||
thread::sleep(Duration::from_micros(100));
|
||||
quick_press(Key::Layout('l'));
|
||||
thread::sleep(Duration::from_micros(100));
|
||||
quick_press(Key::Layout('k'));
|
||||
thread::sleep(Duration::from_micros(100));
|
||||
let mut est_index = get_choose_btn();
|
||||
while est_index.is_none() || est_index.unwrap() != 3 {
|
||||
quick_press(Key::Layout('l'));
|
||||
quick_press(Key::Layout('k'));
|
||||
trace!("尝试获取激活按钮");
|
||||
est_index = get_choose_btn();
|
||||
}
|
||||
quick_press(Key::Layout('z'));
|
||||
thread::sleep(Duration::from_micros(100));
|
||||
status = PokemmoStatus::CheckRun;
|
||||
}
|
||||
PokemmoStatus::CheckRun => {
|
||||
let mut last_word = get_last_string();
|
||||
// 读取十次后默认成功
|
||||
let mut times = 0_usize;
|
||||
while !last_word.contains("成功")
|
||||
&& !last_word.contains("中逃跑")
|
||||
&& !last_word.contains("不能跑")
|
||||
&& times < 10{
|
||||
trace!("读取逃跑文档 : {}",last_word);
|
||||
last_word = get_last_string();
|
||||
thread::sleep(Duration::from_millis(200));
|
||||
times = times + 1;
|
||||
}
|
||||
if last_word.contains("成功") || last_word.contains("逃跑") {
|
||||
trace!("逃跑成功.");
|
||||
status = Free;
|
||||
} else {
|
||||
trace!("逃跑失败");
|
||||
status = Free;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_text_list() -> Vec<String> {
|
||||
let text_image = read_area(TEXT_AREA);
|
||||
let text_list: Vec<String> = text_image.split("\r\n").filter(|x| !x.is_empty()).map(|x| String::from(x)).collect();
|
||||
return text_list;
|
||||
}
|
||||
|
||||
|
||||
pub fn get_last_string() -> String {
|
||||
let text_image = read_area(LAST_TEXT_AREA);
|
||||
return text_image;
|
||||
}
|
||||
|
||||
|
||||
pub(crate) fn check_screen_active() -> bool{
|
||||
|
||||
pub(crate) fn check_screen_active() -> bool {
|
||||
let logo_image = screen_shot(Some(LOGO));
|
||||
let data= logo_image.to_png(Some(Compression::Default)).expect("image to png failed");
|
||||
|
||||
let data = logo_image.to_png(Some(Compression::Default)).expect("image to png failed");
|
||||
let active_logo = ImageReader::open("./resources/pokemmo/image/logo_active.png").expect("read active logo image failed").decode().expect("decode image failed");
|
||||
let active_logo_data = active_logo.as_bytes().to_vec();
|
||||
|
||||
let size = data.len();
|
||||
let mut dis = 0_isize;
|
||||
for i in 0 .. size{
|
||||
dis += active_logo_data[i].clone() as isize - data[i].clone() as isize;
|
||||
for i in 0..size {
|
||||
dis += active_logo_data[i.clone()].clone() as isize - data[i].clone() as isize;
|
||||
}
|
||||
println!("dis : {}",dis);
|
||||
println!("dis : {}", dis);
|
||||
|
||||
return dis <= 5000;
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
pub fn read_area(area: Area) -> String {
|
||||
let psm = area.psm.clone();
|
||||
let image = screen_shot(Some(area));
|
||||
let image_data = image.rgba().clone();
|
||||
let image_width = image.width();
|
||||
let image_height = image.height();
|
||||
let dy_image = DynamicImage::from(RgbaImage::from_vec(image_width, image_height, image_data).unwrap());
|
||||
let text = find_string_in_image(&dy_image, psm);
|
||||
return text;
|
||||
}
|
||||
|
||||
|
||||
pub fn read_group_5() -> Vec<String> {
|
||||
let mut result = Vec::new();
|
||||
result.push(read_area(GROUP_5_1));
|
||||
result.push(read_area(GROUP_5_2));
|
||||
result.push(read_area(GROUP_5_3));
|
||||
result.push(read_area(GROUP_5_4));
|
||||
result.push(read_area(GROUP_5_5));
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
pub fn get_choose_btn() -> Option<usize> {
|
||||
let mut btn_list = Vec::new();
|
||||
btn_list.push(screen_shot(Some(BUTTON_HL_1)));
|
||||
btn_list.push(screen_shot(Some(BUTTON_HL_2)));
|
||||
btn_list.push(screen_shot(Some(BUTTON_HL_3)));
|
||||
btn_list.push(screen_shot(Some(BUTTON_HL_4)));
|
||||
let mut y_max = 0_f32;
|
||||
let mut max_index = None;
|
||||
for index in 0..4 {
|
||||
let image = &mut btn_list[index];
|
||||
let data = image.rgba();
|
||||
let size = data.len();
|
||||
let pixel_size = size / 4;
|
||||
let mut r_total = 0_usize;
|
||||
let mut g_total = 0_usize;
|
||||
let mut b_total = 0_usize;
|
||||
for i in 0..pixel_size {
|
||||
r_total += (data[i.clone() * 4].clone() as usize);
|
||||
g_total += (data[i.clone() * 4 + 1].clone() as usize);
|
||||
b_total += (data[i.clone() * 4 + 2].clone() as usize);
|
||||
}
|
||||
let r_avg = r_total / pixel_size;
|
||||
let g_avg = g_total / pixel_size;
|
||||
let b_avg = b_total / pixel_size;
|
||||
|
||||
let r1 = r_avg as f32 / 255_f32;
|
||||
let g1 = g_avg as f32 / 255_f32;
|
||||
let b1 = b_avg as f32 / 255_f32;
|
||||
|
||||
let max = r1.max(g1).max(b1);
|
||||
let k = 1_f32 - max;
|
||||
let y = (1_f32 - b1 - k) / (1_f32 - k);
|
||||
if y > y_max && y > 0.4_f32 {
|
||||
y_max = y;
|
||||
max_index = Some(index);
|
||||
}
|
||||
}
|
||||
return max_index;
|
||||
}
|
||||
}
|
|
@ -3,52 +3,81 @@ mod tests {
|
|||
use std::thread::sleep;
|
||||
use std::time::Duration;
|
||||
use image::io::Reader as ImageReader;
|
||||
use crate::pokemmo::const_value::pokemmo_const_value::{LOGO, MAP_CITY, SHORTCUT_KEY_1, SHORTCUT_KEY_5};
|
||||
use crate::pokemmo::pokemmo::pokemmo::check_screen_active;
|
||||
use log::LevelFilter;
|
||||
use crate::pokemmo::const_value::pokemmo_const_value::{BUTTON_HL_1, BUTTON_HL_2, BUTTON_HL_3, BUTTON_HL_4, GROUP_5_1, GROUP_5_2, GROUP_5_3, GROUP_5_4, GROUP_5_5, LAST_TEXT_AREA, LOGO, MAP_CITY, SHORTCUT_KEY_1, SHORTCUT_KEY_5, SINGLE_BATTLE, TEMP_BATTLE_TEXT_AREA, TEXT_AREA};
|
||||
use crate::pokemmo::pokemmo::pokemmo::{check_screen_active, get_choose_btn, get_last_string, read_area, read_group_5, single_meet_shiny};
|
||||
use crate::screen::screen::screen::{print_image, screen_shot};
|
||||
|
||||
|
||||
#[test]
|
||||
fn print_logo() {
|
||||
sleep(Duration::from_secs(1));
|
||||
fn try_meet_shiny(){
|
||||
simple_logging::log_to_file("./test/log/meet_shiny.log",LevelFilter::Info).expect("set log failed");
|
||||
|
||||
let logo_image = screen_shot(Some(LOGO));
|
||||
print_image(logo_image, "logo".to_string());
|
||||
let key_words = vec![
|
||||
"闪".to_string(),
|
||||
"光".to_string(),
|
||||
];
|
||||
single_meet_shiny(&key_words);
|
||||
|
||||
}
|
||||
|
||||
|
||||
let active = check_screen_active();
|
||||
println!("main screen active : {}", active);
|
||||
#[test]
|
||||
fn print_shortcut() {
|
||||
let text = screen_shot(Some(TEMP_BATTLE_TEXT_AREA));
|
||||
print_image(text, "temp_battle_text".to_string());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn print_city() {
|
||||
sleep(Duration::from_secs(1));
|
||||
fn print_group_5() {
|
||||
let group_5_1 = screen_shot(Some(GROUP_5_1));
|
||||
print_image(group_5_1, "group_5_1".to_string());
|
||||
let group_5_2 = screen_shot(Some(GROUP_5_2));
|
||||
print_image(group_5_2, "group_5_2".to_string());
|
||||
let group_5_3 = screen_shot(Some(GROUP_5_3));
|
||||
print_image(group_5_3, "group_5_3".to_string());
|
||||
let group_5_4 = screen_shot(Some(GROUP_5_4));
|
||||
print_image(group_5_4, "group_5_4".to_string());
|
||||
let group_5_5 = screen_shot(Some(GROUP_5_5));
|
||||
print_image(group_5_5, "group_5_5".to_string());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn print_button() {
|
||||
let btn_hl_1 = screen_shot(Some(BUTTON_HL_1));
|
||||
print_image(btn_hl_1, "btn_hl_1".to_string());
|
||||
let btn_hl_2 = screen_shot(Some(BUTTON_HL_2));
|
||||
print_image(btn_hl_2, "btn_hl_2".to_string());
|
||||
let btn_hl_3 = screen_shot(Some(BUTTON_HL_3));
|
||||
print_image(btn_hl_3, "btn_hl_3".to_string());
|
||||
let btn_hl_4 = screen_shot(Some(BUTTON_HL_4));
|
||||
print_image(btn_hl_4, "btn_hl_4".to_string());
|
||||
|
||||
let logo_image = screen_shot(Some(MAP_CITY));
|
||||
print_image(logo_image, "city".to_string());
|
||||
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn print_shortcut_key_1() {
|
||||
sleep(Duration::from_secs(1));
|
||||
|
||||
let logo_image = screen_shot(Some(SHORTCUT_KEY_1));
|
||||
print_image(logo_image, "key_1".to_string());
|
||||
|
||||
fn find_text() {
|
||||
let text = read_area(TEMP_BATTLE_TEXT_AREA);
|
||||
println!("text in image: {}",text);
|
||||
}
|
||||
|
||||
|
||||
#[test]
|
||||
fn print_shortcut_key_5() {
|
||||
sleep(Duration::from_secs(1));
|
||||
|
||||
let logo_image = screen_shot(Some(SHORTCUT_KEY_5));
|
||||
print_image(logo_image, "key_5".to_string());
|
||||
|
||||
fn get_active_btn() {
|
||||
let index_op = get_choose_btn();
|
||||
if index_op.is_some(){
|
||||
println!("激活索引:{}",index_op.unwrap());
|
||||
}else {
|
||||
println!("无激活索引");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
#[test]
|
||||
fn compare_logo() {
|
||||
|
||||
let active_logo = ImageReader::open("./resources/pokemmo/image/logo_active.png").expect("read active logo image failed").decode().expect("decode image failed");
|
||||
let active_logo_data = active_logo.as_bytes().to_vec();
|
||||
|
||||
|
@ -59,11 +88,8 @@ mod tests {
|
|||
|
||||
let mut dis = 0_isize;
|
||||
for i in 0 .. size{
|
||||
dis += na_logo_data[i].clone() as isize - active_logo_data[i].clone() as isize;
|
||||
dis += na_logo_data[i.clone()].clone() as isize - active_logo_data[i.clone()].clone() as isize;
|
||||
}
|
||||
|
||||
println!("dis = {}",dis);
|
||||
|
||||
|
||||
}
|
||||
}
|
|
@ -1,4 +1,147 @@
|
|||
#[cfg(feature = "pokemon")]
|
||||
pub(crate) mod pokemon{
|
||||
pub(crate) mod pokemon {
|
||||
pub enum PokeType {
|
||||
Normal,
|
||||
Fighting,
|
||||
Flying,
|
||||
Poison,
|
||||
Ground,
|
||||
Rock,
|
||||
Bug,
|
||||
Ghost,
|
||||
Steel,
|
||||
File,
|
||||
Water,
|
||||
Grass,
|
||||
Electric,
|
||||
Psychic,
|
||||
Ice,
|
||||
Dragon,
|
||||
Dark,
|
||||
Fairy,
|
||||
}
|
||||
|
||||
pub struct Pokemon {
|
||||
pub(crate) dex: PokeDex,
|
||||
pub(crate) moves: Vec<MoveCategory>,
|
||||
pub(crate) lv: u32,
|
||||
pub(crate) stat: Stat,
|
||||
pub(crate) status: StatusChange,
|
||||
pub(crate) nature: Nature
|
||||
}
|
||||
|
||||
pub struct PokeDex {
|
||||
pub(crate) no: u32,
|
||||
pub(crate) fir_type: PokeType,
|
||||
pub(crate) sec_type: Option<PokeType>,
|
||||
pub(crate) iv: Iv,
|
||||
}
|
||||
|
||||
pub struct Iv {
|
||||
pub(crate) hp: u32,
|
||||
pub(crate) attack: u32,
|
||||
pub(crate) defense: u32,
|
||||
pub(crate) sp_atk: u32,
|
||||
pub(crate) sp_def: u32,
|
||||
pub(crate) speed: u32,
|
||||
}
|
||||
|
||||
pub struct Ev {
|
||||
pub(crate) hp: u32,
|
||||
pub(crate) attack: u32,
|
||||
pub(crate) defense: u32,
|
||||
pub(crate) sp_atk: u32,
|
||||
pub(crate) sp_def: u32,
|
||||
pub(crate) speed: u32,
|
||||
}
|
||||
|
||||
pub struct Stat {
|
||||
pub(crate) hp: u32,
|
||||
pub(crate) attack: u32,
|
||||
pub(crate) defense: u32,
|
||||
pub(crate) sp_atk: u32,
|
||||
pub(crate) sp_def: u32,
|
||||
pub(crate) speed: u32,
|
||||
}
|
||||
|
||||
pub struct StatusChange {
|
||||
pub(crate) attack: i32,
|
||||
pub(crate) defense: i32,
|
||||
pub(crate) sp_atk: i32,
|
||||
pub(crate) sp_def: i32,
|
||||
pub(crate) speed: i32,
|
||||
pub(crate) accuracy: i32,
|
||||
pub(crate) evasion: i32,
|
||||
}
|
||||
|
||||
pub enum MoveCategory {
|
||||
Physical,
|
||||
Special,
|
||||
Status,
|
||||
}
|
||||
|
||||
pub struct Move {
|
||||
pub(crate) cat: MoveCategory,
|
||||
pub(crate) value: u32,
|
||||
}
|
||||
|
||||
pub enum Nature {
|
||||
Hardy,
|
||||
Lonely,
|
||||
Brave,
|
||||
Adamant,
|
||||
Naughty,
|
||||
Bold,
|
||||
Docile,
|
||||
Relaxed,
|
||||
Impish,
|
||||
Lax,
|
||||
Timid,
|
||||
Hasty,
|
||||
Serious,
|
||||
Jolly,
|
||||
Naive,
|
||||
Modest,
|
||||
Mild,
|
||||
Quiet,
|
||||
Bashful,
|
||||
Rash,
|
||||
Calm,
|
||||
Gentle,
|
||||
Sassy,
|
||||
Careful,
|
||||
Quirky,
|
||||
}
|
||||
|
||||
impl Nature {
|
||||
pub fn influence(&self) -> (f32, f32, f32, f32, f32) {
|
||||
return match self {
|
||||
Hardy => (0_f32, 0_f32, 0_f32, 0_f32, 0_f32),
|
||||
Lonely => (1.1_f32, 0.9_f32, 0_f32, 0_f32, 0_f32),
|
||||
Brave => (1.1_f32, 0_f32, 0_f32, 0_f32, 0.9_f32),
|
||||
Adamant => (1.1_f32, 0_f32, 0.9_f32, 0_f32, 0_f32),
|
||||
Naughty => (1.1_f32, 0_f32, 0_f32, 0.9_f32, 0_f32),
|
||||
Bold => (0.9_f32, 1.1_f32, 0_f32, 0_f32, 0_f32),
|
||||
Docile => (0_f32, 0_f32, 0_f32, 0_f32, 0_f32),
|
||||
Relaxed => (0_f32, 1.1_f32, 0_f32, 0_f32, 0.9_f32),
|
||||
Impish => (0_f32, 1.1_f32, 0.9_f32, 0_f32, 0_f32),
|
||||
Lax => (0_f32, 1.1_f32, 0_f32, 0.9_f32, 0_f32),
|
||||
Timid => (0.9_f32, 0_f32, 0_f32, 0_f32, 1.1_f32),
|
||||
Hasty => (0_f32, 0.9_f32, 0_f32, 0_f32, 1.1_f32),
|
||||
Serious => (0_f32, 0_f32, 0_f32, 0_f32, 0_f32),
|
||||
Jolly => (0_f32, 0_f32, 0.9_f32, 0_f32, 1.1_f32),
|
||||
Naive => (0_f32, 0_f32, 0_f32, 0.9_f32, 1.1_f32),
|
||||
Modest => (0.9_f32, 0_f32, 1.1_f32, 0_f32, 0_f32),
|
||||
Mild => (0_f32, 0.9_f32, 1.1_f32, 0_f32, 0_f32),
|
||||
Quiet => (0_f32, 0_f32, 1.1_f32, 0_f32, 0.9_f32),
|
||||
Bashful => (0_f32, 0_f32, 0_f32, 0_f32, 0_f32),
|
||||
Rash => (0_f32, 0_f32, 1.1_f32, 0.9_f32, 0_f32),
|
||||
Calm => (0.9_f32, 0_f32, 0_f32, 1.1_f32, 0_f32),
|
||||
Gentle => (0_f32, 0.9_f32, 0_f32, 1.1_f32, 0_f32),
|
||||
Sassy => (0_f32, 0_f32, 0_f32, 1.1_f32, 0.9_f32),
|
||||
Careful => (0_f32, 0_f32, 0.9_f32, 1.1_f32, 0_f32),
|
||||
Quirky => (0_f32, 0_f32, 0_f32, 0_f32, 0_f32),
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
|
@ -9,8 +9,10 @@ pub mod screen {
|
|||
pub right: i32,
|
||||
pub top: i32,
|
||||
pub bottom: i32,
|
||||
pub psm : i32,
|
||||
}
|
||||
|
||||
|
||||
pub fn screen_shot(area: Option<Area>) -> Image {
|
||||
let main_screen_list: Vec<Screen> = Screen::all().expect("get all screen failed").into_iter().filter(|x| x.display_info.is_primary).collect();
|
||||
let main_screen = main_screen_list.first().expect("get main screen failed");
|
||||
|
@ -25,12 +27,9 @@ pub mod screen {
|
|||
return image
|
||||
}
|
||||
|
||||
|
||||
pub fn print_image(image: Image,file_name : String){
|
||||
fs::write(format!("test/image/{}.png", file_name), image.to_png(Some(Compression::Default)).expect("image to png failed")).unwrap();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
|
@ -10,12 +10,10 @@ mod tests {
|
|||
right: 300,
|
||||
top: 0,
|
||||
bottom: 300,
|
||||
psm: 3,
|
||||
};
|
||||
let image = screen_shot(Some(area));
|
||||
|
||||
print_image(image,"abc".to_string());
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue