返回 AiToEarn
ImgChoose.tsx
1 /*
2 * @Author: nevin
3 * @Date: 2025-01-22 21:59:36
4 * @LastEditTime: 2025-02-11 21:45:34
5 * @LastEditors: nevin
6 * @Description: 选择图片
7 */
8 import { Button, message } from 'antd';
9 import { FC } from 'react';
10 import { generateUUID, getFilePathName } from '@/utils';
11 import { icpGetFileStream } from '@/icp/view';
12
13 interface ImgChooseProps {
14 // 单选就使用单选方法,多选就使用单选方法
15
16 // 单选返回
17 onChoose?: (_: IImgFile) => void;
18 // 多选返回方法
19 onMultipleChoose?: (_: IImgFile[]) => void;
20 children?: React.ReactNode;
21 }
22
23 export interface IImgFile {
24 id: string;
25 size: number;
26 file: Blob;
27 // 前端临时路径,注意不要存到数据库
28 imgUrl: string;
29 filename: string;
30 // 图片在硬盘上的路径
31 imgPath: string;
32 // 图片宽度
33 width: number;
34 // 图片高度
35 height: number;
36 }
37
38 // 根据图片在硬盘上的路径获取文件
39 export const getImgFile = async (path: string): Promise<IImgFile> => {
40 const file = await icpGetFileStream(path);
41 return await formatImg({ path, file });
42 };
43
44 /**
45 * 根据图片的Uint8Array和路径获取文件
46 * @param path
47 * @param file
48 * @param blob
49 */
50 export const formatImg = async ({
51 path,
52 file,
53 blob,
54 }: {
55 path: string;
56 file?: Uint8Array;
57 blob?: Blob;
58 }): Promise<IImgFile> => {
59 return new Promise((resolve) => {
60 const { filename, suffix } = getFilePathName(path);
61 if (!blob) {
62 blob = new Blob([file!], {
63 type: `image/${suffix}`,
64 });
65 }
66 const imgUrl = URL.createObjectURL(blob);
67
68 const img = new Image();
69 img.onload = () => {
70 resolve({
71 id: generateUUID(),
72 width: img.width,
73 height: img.height,
74 imgPath: path,
75 size: blob!.size,
76 filename,
77 file: blob!,
78 imgUrl,
79 });
80 };
81 img.src = imgUrl;
82 });
83 };
84
85 const ImgChoose: FC<ImgChooseProps> = ({
86 onChoose,
87 onMultipleChoose,
88 children,
89 }) => {
90 /**
91 * 发送上传的事件
92 */
93 const handleUploadImg = async () => {
94 try {
95 const result: {
96 path: string;
97 file: Uint8Array;
98 }[] = await window.ipcRenderer.invoke(
99 'ICP_VIEWS_CHOSE_IMG',
100 !!onMultipleChoose,
101 );
102 if (!result) return;
103 const tasks: Promise<IImgFile>[] = [];
104 for (const v of result) {
105 tasks.push(formatImg(v));
106 }
107 const imgFiles = await Promise.all(tasks);
108
109 if (onMultipleChoose) {
110 onMultipleChoose(imgFiles);
111 } else if (onChoose) {
112 onChoose(imgFiles[0]);
113 }
114 } catch (error) {
115 message.error('选择图片失败');
116 console.error(error);
117 }
118 };
119
120 return (
121 <>
122 {children ? (
123 <div
124 className="imgChoose"
125 onClick={handleUploadImg}
126 style={{ cursor: 'pointer' }}
127 >
128 {children}
129 </div>
130 ) : (
131 <Button type="primary" onClick={handleUploadImg}>
132 选择图片
133 </Button>
134 )}
135 </>
136 );
137 };
138
139 export default ImgChoose;
140
140 lines Plain Text