const sharp = require('sharp'); const fs = require('fs'); async function parse_bg_captcha(imgPath, imShow=false, savePath=null) { // 图片还原顺序, 定值 const _Ge = [39, 38, 48, 49, 41, 40, 46, 47, 35, 34, 50, 51, 33, 32, 28, 29, 27, 26, 36, 37, 31, 30, 44, 45, 43, 42, 12, 13, 23, 22, 14, 15, 21, 20, 8, 9, 25, 24, 6, 7, 3, 2, 0, 1, 11, 10, 4, 5, 19, 18, 16, 17]; const w_sep = 10, h_sep = 80; const image = sharp(imgPath); const { width, height } = await image.metadata(); // 还原后的背景图 const newImg = sharp({ create: { width: 260, height: 160, channels: 3, background: { r: 255, g: 255, b: 255 } } }); for (let idx = 0; idx < _Ge.length; idx++) { const x = _Ge[idx] % 26 * 12 + 1; const y = _Ge[idx] > 25 ? h_sep : 0; // 从背景图中裁剪出对应位置的小块 const imgCut = await image.extract({ left: x, top: y, width: w_sep, height: h_sep }).toBuffer(); // 将小块拼接到新图中 const new_x = idx % 26 * 10; const new_y = idx > 25 ? h_sep : 0; await newImg.overlayWith(imgCut, { left: new_x, top: new_y }); } if (imShow) { await newImg.toFile('bg.jpg'); console.log('Image saved as bg.jpg'); } if (savePath) { await newImg.toFile(savePath); console.log(Image saved as ${savePath}); } return newImg; } parse_bg_captcha('bg.webp', true, 'bg1.jpg'); 这段示例代码报错newImg.overlayWith is not a function,请帮我解决
时间: 2023-09-18 21:08:08 浏览: 117
这个错误可能是因为 `sharp` 版本过低导致的。请升级 `sharp` 至最新版本,然后再试一下。你可以使用以下命令升级:
```
npm install sharp@latest
```
如果升级后仍然出现同样的错误,请检查一下是否有其他版本的 `sharp` 被安装在了你的机器上。你可以使用以下命令来列出所有安装的 `sharp` 版本:
```
npm list sharp
```
如果有其他版本的 `sharp` 被列出,请将其卸载并重新运行你的代码。
相关问题
const Jimp = require('jimp'); const _ = require('lodash'); class parse_bg_captcha { // 初始化方法 constructor () { // 读取图片 this.imgPromise = Jimp.read("./bg.png"); // 还原后的背景图 this.newImg = new Jimp(260, 160); // 图片还原顺序, 定值 this.Ge = [39, 38, 48, 49, 41, 40, 46, 47, 35, 34, 50, 51, 33, 32, 28, 29, 27, 26, 36, 37, 31, 30, 44, 45, 43, 42, 12, 13, 23, 22, 14, 15, 21, 20, 8, 9, 25, 24, 6, 7, 3, 2, 0, 1, 11, 10, 4, 5, 19, 18, 16, 17]; this.w_sep = 10; this.h_sep = 80; } // 循环合成图片 async loop_montage_image (imgPath, imShow = false, savePath = null) { const img = await this.imgPromise; // 并行处理裁剪和拼接操作 const promises = this.Ge.map(idx => { const x = idx % 26 * 12 + 1; const y = idx > 25 ? this.h_sep : 0; const imgCut = _.cloneDeep(img).crop(x, y, this.w_sep, this.h_sep); const newX = idx % 26 * 10; const newY = idx > 25 ? this.h_sep : 0; return this.newImg.blitAsync(imgCut, newX, newY); }); await Promise.all(promises); if (imShow) { this.newImg.write('output.jpg'); } if (savePath !== null) { await this.newImg.writeAsync(savePath); } } // run方法 run (imgPath, imShow = false, savePath = null) { this.loop_montage_image(imgPath, imShow, savePath); } } if (__filename === process.mainModule.filename) { console.log("开始"); const c = new parse_bg_captcha(); c.run('./bg.png', true, 'bg.jpg'); } 这段代码帮我优化一下
这段代码已经很不错了,但是可以稍微进行一些优化和改进。以下是一些可能有用的建议:
1. 使用 ES6 的 class 语法来定义类,这样代码更加清晰易读。
2. 将图片读取操作放到 constructor 中,避免每次都重新读取图片。
3. 使用 Jimp 的 `clone()` 方法来避免使用 lodash 的 `cloneDeep()` 方法。
4. 将参数的默认值设为 null,而不是 false,这样可以更好地表示参数是否提供。
5. 将循环合成图片的方法命名为 `montageImage()`,更能描述其功能。
综上所述,以下是经过优化的代码:
```
const Jimp = require('jimp');
class ParseBgCaptcha {
constructor() {
// 读取图片
this.img = null;
Jimp.read('./bg.png').then((img) => {
this.img = img;
}).catch((err) => {
console.error(`读取图片失败: ${err}`);
});
// 还原后的背景图
this.newImg = new Jimp(260, 160);
// 图片还原顺序, 定值
this.Ge = [39, 38, 48, 49, 41, 40, 46, 47, 35, 34, 50, 51, 33, 32, 28, 29, 27, 26, 36, 37, 31, 30, 44, 45, 43, 42, 12, 13, 23, 22, 14, 15, 21, 20, 8, 9, 25, 24, 6, 7, 3, 2, 0, 1, 11, 10, 4, 5, 19, 18, 16, 17];
this.w_sep = 10;
this.h_sep = 80;
}
async montageImage(imgPath, imShow = null, savePath = null) {
const promises = this.Ge.map((idx) => {
const x = idx % 26 * 12 + 1;
const y = idx > 25 ? this.h_sep : 0;
const imgCut = this.img.clone().crop(x, y, this.w_sep, this.h_sep);
const newX = idx % 26 * 10;
const newY = idx > 25 ? this.h_sep : 0;
return this.newImg.blitAsync(imgCut, newX, newY);
});
await Promise.all(promises);
if (imShow) {
this.newImg.write('output.jpg');
}
if (savePath !== null) {
await this.newImg.writeAsync(savePath);
}
}
run(imgPath, imShow = null, savePath = null) {
this.montageImage(imgPath, imShow, savePath);
}
}
if (require.main === module) {
console.log('开始');
const c = new ParseBgCaptcha();
c.run('./bg.png', true, 'bg.jpg');
}
```
注意:在这个版本中,我们将默认值设为 null,然后在代码中检查是否提供参数。这样可以更好地检查参数是否存在,而不是只检查参数是否为真。
const Jimp = require('jimp'); class parse_bg_captcha { // 初始化方法 constructor () { // 读取图片 this.img = Jimp.read("./bg.png"); // 还原后的背景图 this.newImg = new Jimp(260, 160); // 图片还原顺序, 定值 this.Ge = [39, 38, 48, 49, 41, 40, 46, 47, 35, 34, 50, 51, 33, 32, 28, 29, 27, 26, 36, 37, 31, 30, 44, 45, 43, 42, 12, 13, 23, 22, 14, 15, 21, 20, 8, 9, 25, 24, 6, 7, 3, 2, 0, 1, 11, 10, 4, 5, 19, 18, 16, 17] this.w_sep = 10 this.h_sep = 80 } // 循环合成图片 loop_montage_image (imgPath, imShow = false, savePath = null) { for (let idx = 0; idx < this.Ge.length; idx++) { const x = this.Ge[idx] % 26 * 12 + 1; const y = this.Ge[idx] > 25 ? this.h_sep : 0; // 从背景图中裁剪出对应位置的小块 const imgCut = this.img.clone().crop(x, y, this.w_sep, this.h_sep); // 将小块拼接到新图中 const newX = idx % 26 * 10; const newY = idx > 25 ? this.h_sep : 0; this.newImg.blit(imgCut, newX, newY); } if (imShow) { this.newImg.write('output.jpg'); } if (savePath !== null) { this.newImg.writeAsync(savePath); } } // run方法 run (imgPath, imShow = false, savePath = null) { this.loop_montage_image(imgPath, imShow = false, savePath = null) } } if (__filename === process.mainModule.filename) { console.log("开始") const c = new parse_bg_captcha() c.run('./bg.png', true, 'bg.jpg') }帮我优化这段代码
好的,以下是对代码的一些优化建议:
1. 在初始化方法中,将读取图片的操作改为异步操作,并使用 `then()` 方法获取读取结果,避免在后面的操作中出现图片未加载完成的问题。
2. 在 `loop_montage_image()` 方法中,可以使用 `Promise.all()` 方法来并行处理图片裁剪和拼接的操作,以提高代码的运行效率。
3. 在 `run()` 方法中,不需要将参数 `imShow` 和 `savePath` 重新赋值为 `false` 和 `null`,直接使用传入的参数即可。
根据以上建议,可以尝试修改代码如下:
```
const Jimp = require('jimp');
const _ = require('lodash');
class parse_bg_captcha {
// 初始化方法
constructor () {
// 读取图片
this.imgPromise = Jimp.read("./bg.png");
// 还原后的背景图
this.newImg = new Jimp(260, 160);
// 图片还原顺序, 定值
this.Ge = [39, 38, 48, 49, 41, 40, 46, 47, 35, 34, 50, 51, 33, 32, 28, 29, 27, 26, 36, 37, 31, 30, 44, 45, 43, 42, 12, 13, 23, 22, 14, 15, 21, 20, 8, 9, 25, 24, 6, 7, 3, 2, 0, 1, 11, 10, 4, 5, 19, 18, 16, 17];
this.w_sep = 10;
this.h_sep = 80;
}
// 循环合成图片
async loop_montage_image (imgPath, imShow = false, savePath = null) {
const img = await this.imgPromise;
// 并行处理裁剪和拼接操作
const promises = this.Ge.map(idx => {
const x = idx % 26 * 12 + 1;
const y = idx > 25 ? this.h_sep : 0;
const imgCut = _.cloneDeep(img).crop(x, y, this.w_sep, this.h_sep);
const newX = idx % 26 * 10;
const newY = idx > 25 ? this.h_sep : 0;
return this.newImg.blitAsync(imgCut, newX, newY);
});
await Promise.all(promises);
if (imShow) {
this.newImg.write('output.jpg');
}
if (savePath !== null) {
await this.newImg.writeAsync(savePath);
}
}
// run方法
run (imgPath, imShow = false, savePath = null) {
this.loop_montage_image(imgPath, imShow, savePath);
}
}
if (__filename === process.mainModule.filename) {
console.log("开始");
const c = new parse_bg_captcha();
c.run('./bg.png', true, 'bg.jpg');
}
```
希望以上建议能对您有所帮助!
阅读全文