rust_wechat_weapp/api/
image_processing.rs

1use crate::Client;
2use reqwest::multipart;
3use rust_wechat_codegen::ServerResponse;
4use rust_wechat_core::client::ClientTrait;
5use serde::{Deserialize, Serialize};
6use serde_json::json;
7
8const CROP_IMAGE_URL: &str = "https://api.weixin.qq.com/cv/img/aicrop";
9const QRCODE_IMAGE_URL: &str = "https://api.weixin.qq.com/cv/img/qrcode";
10
11#[derive(Debug, Serialize, Deserialize, ServerResponse)]
12#[sr(flatten)]
13pub struct CropImage {
14    pub results: Vec<CropResult>,
15    pub img_size: ImageSize,
16}
17
18#[derive(Debug, Serialize, Deserialize)]
19pub struct CropResult {
20    pub crop_left: i32,
21    pub crop_top: i32,
22    pub crop_right: i32,
23    pub crop_bottom: i32,
24}
25#[derive(Debug, Serialize, Deserialize)]
26pub struct ImageSize {
27    pub w: u32,
28    pub h: u32,
29}
30
31#[derive(Debug, Serialize, Deserialize, ServerResponse)]
32#[sr(flatten)]
33pub struct ScanQrcode {
34    pub code_results: Vec<CropResult>,
35    pub img_size: ImageSize,
36}
37#[derive(Debug, Serialize, Deserialize)]
38pub struct QrcodeResult {
39    pub type_name: String,
40    pub data: String,
41    pub pos: Pos,
42}
43
44#[derive(Debug, Serialize, Deserialize)]
45pub struct Pos {
46    pub left_top: Point,
47    pub right_top: Point,
48    pub right_bottom: Point,
49    pub left_bottom: Point,
50}
51
52#[derive(Debug, Serialize, Deserialize)]
53pub struct Point {
54    pub x: u32,
55    pub y: u32,
56}
57
58impl Client {
59    pub async fn crop_image(&self, path: &str) -> crate::Result<CropImage> {
60        let url = self.authorized_url(CROP_IMAGE_URL).await?;
61
62        if path.starts_with("http") {
63            let response: CropImageResponse = self.json(url, &[("img_url", path)]).await?;
64            Ok(response.data()?)
65        } else {
66            let file_byte = std::fs::read(path)?;
67            let part = multipart::Part::bytes(file_byte);
68            let multipart = multipart::Form::new().part("img", part);
69            let response: CropImageResponse = self.upload(url, multipart).await?;
70            Ok(response.data()?)
71        }
72    }
73    pub async fn scan_qrcode(&self, path: &str) -> crate::Result<ScanQrcode> {
74        let url = self.authorized_url(QRCODE_IMAGE_URL).await?;
75        if path.starts_with("http") {
76            let response: ScanQrcodeResponse = self.json(url, &[("img_url", path)]).await?;
77            Ok(response.data()?)
78        } else {
79            let file_byte = std::fs::read(path)?;
80            let part = multipart::Part::bytes(file_byte);
81            let multipart = multipart::Form::new().part("img", part);
82            let response: ScanQrcodeResponse = self.upload(url, multipart).await?;
83            Ok(response.data()?)
84        }
85    }
86}