luoyutianyang commited on
Commit
4a260f7
·
verified ·
1 Parent(s): 88e86a8

Update egg-api.js

Browse files
Files changed (1) hide show
  1. egg-api.js +87 -79
egg-api.js CHANGED
@@ -44,92 +44,100 @@ async function downloadAndConvertImage(url) {
44
 
45
  // 图像处理函数
46
  async function processImage(imageBuffer, classifiersFolder, replacementImageBuffer) {
47
- try {
48
- const classifiers = await loadClassifiersFromFolder(classifiersFolder);
49
-
50
- // 使用 Jimp 验证图片文件是否有效
51
- const jimpImage = await Jimp.read(imageBuffer);
52
- if (!jimpImage) {
53
- throw new Error('Failed to read the image with Jimp. The image file might be corrupted or not supported.');
54
- }
55
-
56
- const img = cv.imdecode(imageBuffer);
57
- if (img.empty) {
58
- throw new Error('Failed to read the image with OpenCV. The image file might be corrupted or not supported.');
59
- }
60
-
61
- const grayImg = img.bgrToGray();
62
- const allFaces = [];
63
- classifiers.forEach(classifier => {
64
- const faces = classifier.detectMultiScale(grayImg).objects;
65
- allFaces.push(...faces);
66
- });
67
-
68
- const replacementFace = await Jimp.read(replacementImageBuffer);
69
- allFaces.forEach((faceRect, i) => {
70
- const resizedReplacementFace = replacementFace.resize(faceRect.width, faceRect.height)
71
- const faceRegion = img.getRegion(faceRect)
72
 
73
- const replacementBuffer = resizedReplacementFace.bitmap.data
74
- const centerX = faceRect.width / 2
75
- const centerY = faceRect.height / 2
76
- const maxRadius = Math.min(centerX, centerY)
77
- for (let y = 0; y < faceRect.height; y++) {
78
- for (let x = 0; x < faceRect.width; x++) {
79
- const distance = Math.sqrt((x - centerX) ** 2 + (y - centerY) ** 2)
80
- if (distance <= maxRadius) {
81
- const idx = (y * faceRect.width + x) << 2
82
- const [r, g, b, a] = replacementBuffer.slice(idx, idx + 4)
83
 
84
- if (a > 0) {
85
- faceRegion.set(y, x, new cv.Vec3(b, g, r))
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
86
  }
87
  }
88
  }
89
- }
90
- })
91
- const outputBuffer = cv.imencode('.jpg', img);
92
- return outputBuffer;
93
- } catch (error) {
94
- console.error('Error during image processing:', error);
95
- throw error;
96
  }
97
- }
98
 
99
  // Express接口
100
  app.get('/process-image', async (req, res) => {
101
- const { imageUrl, replacementImageUrl } = req.query;
102
-
103
- if (!imageUrl || !replacementImageUrl) {
104
- return res.status(400).send('Both image URL and replacement image URL are required');
105
- }
106
-
107
- const classifiersFolder = './classifiers';
108
- let replacementImageBuffer;
109
- try {
110
- // 下载并转换输入图片和替换图片到内存中
111
- const imageBuffer = await downloadAndConvertImage(imageUrl);
112
- if (replacementImageUrl === 'replace') {
113
- // 使用默认的本地替换图像路径
114
- const defaultReplacementImagePath = './replacement_face.png';
115
- replacementImageBuffer = await Jimp.read(defaultReplacementImagePath);
116
- } else {
117
- // 下载并转换替换图片到内存中
118
- replacementImageBuffer = await downloadAndConvertImage(replacementImageUrl);
119
  }
120
-
121
- // 处理图片
122
- const outputBuffer = await processImage(imageBuffer, classifiersFolder, replacementImageBuffer);
123
-
124
- // 返回处理后的图片
125
- res.set('Content-Type', 'image/jpeg');
126
- res.send(outputBuffer);
127
- } catch (error) {
128
- console.error('Error processing image:', error);
129
- res.status(500).send('Error processing image');
130
- }
131
- });
132
-
133
- app.listen(port, () => {
134
- console.log(`Server is running on http://localhost:${port}`);
135
- });
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
44
 
45
  // 图像处理函数
46
  async function processImage(imageBuffer, classifiersFolder, replacementImageBuffer) {
47
+ try {
48
+ const classifiers = await loadClassifiersFromFolder(classifiersFolder);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
49
 
50
+ const jimpImage = await Jimp.read(imageBuffer);
51
+ if (!jimpImage) {
52
+ throw new Error('Failed to read the image with Jimp. The image file might be corrupted or not supported.');
53
+ }
 
 
 
 
 
 
54
 
55
+ const img = cv.imdecode(imageBuffer);
56
+ if (img.empty) {
57
+ throw new Error('Failed to read the image with OpenCV. The image file might be corrupted or not supported.');
58
+ }
59
+
60
+ const grayImg = img.bgrToGray();
61
+ const allFaces = [];
62
+ classifiers.forEach(classifier => {
63
+ const faces = classifier.detectMultiScale(grayImg).objects;
64
+ allFaces.push(...faces);
65
+ });
66
+
67
+ // 如果没有检测到人脸,抛出错误
68
+ if (allFaces.length === 0) {
69
+ throw new Error('No faces detected in the image.');
70
+ }
71
+
72
+ const replacementFace = await Jimp.read(replacementImageBuffer);
73
+ allFaces.forEach((faceRect, i) => {
74
+ const resizedReplacementFace = replacementFace.resize(faceRect.width, faceRect.height);
75
+ const faceRegion = img.getRegion(faceRect);
76
+
77
+ const replacementBuffer = resizedReplacementFace.bitmap.data;
78
+ const centerX = faceRect.width / 2;
79
+ const centerY = faceRect.height / 2;
80
+ const maxRadius = Math.min(centerX, centerY);
81
+ for (let y = 0; y < faceRect.height; y++) {
82
+ for (let x = 0; x < faceRect.width; x++) {
83
+ const distance = Math.sqrt((x - centerX) ** 2 + (y - centerY) ** 2);
84
+ if (distance <= maxRadius) {
85
+ const idx = (y * faceRect.width + x) << 2;
86
+ const [r, g, b, a] = replacementBuffer.slice(idx, idx + 4);
87
+
88
+ if (a > 0) {
89
+ faceRegion.set(y, x, new cv.Vec3(b, g, r));
90
+ }
91
  }
92
  }
93
  }
94
+ });
95
+ const outputBuffer = cv.imencode('.jpg', img);
96
+ return outputBuffer;
97
+ } catch (error) {
98
+ console.error('Error during image processing:', error);
99
+ throw error;
100
+ }
101
  }
 
102
 
103
  // Express接口
104
  app.get('/process-image', async (req, res) => {
105
+ const { imageUrl, replacementImageUrl } = req.query;
106
+
107
+ if (!imageUrl || !replacementImageUrl) {
108
+ return res.status(400).send('Both image URL and replacement image URL are required');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
109
  }
110
+
111
+ const classifiersFolder = './classifiers';
112
+ let replacementImageBuffer;
113
+ try {
114
+ // 下载并转换输入图片和替换图片到内存中
115
+ const imageBuffer = await downloadAndConvertImage(imageUrl);
116
+ if (replacementImageUrl === 'replace') {
117
+ // 使用默认的本地替换图像路径
118
+ const defaultReplacementImagePath = './replacement_face.png';
119
+ replacementImageBuffer = await Jimp.read(defaultReplacementImagePath);
120
+ } else {
121
+ // 下载并转换替换图片到内存中
122
+ replacementImageBuffer = await downloadAndConvertImage(replacementImageUrl);
123
+ }
124
+
125
+ // 处理图片
126
+ const outputBuffer = await processImage(imageBuffer, classifiersFolder, replacementImageBuffer);
127
+
128
+ // 返回处理后的图片
129
+ res.set('Content-Type', 'image/jpeg');
130
+ res.send(outputBuffer);
131
+ } catch (error) {
132
+ if (error.message === 'No faces detected in the image.') {
133
+ res.status(404).send('No faces detected in the image.');
134
+ } else {
135
+ console.error('Error processing image:', error);
136
+ res.status(500).send('Error processing image');
137
+ }
138
+ }
139
+ });
140
+
141
+ app.listen(port, () => {
142
+ console.log(`Server is running on http://localhost:${port}`);
143
+ });