gpt4 book ai didi

javascript - 使用 jimp 为图像着色

转载 作者:行者123 更新时间:2023-12-05 03:22:50 33 4
gpt4 key购买 nike

我正在使用 jimp 为文件夹中的 png 图像着色,但出现错误:w 和 h 必须是数字(第 42 行 - image.color 函数。)。这看起来应该是一个简单的操作,但我发现的解决方案非常复杂。似乎 jimp 是要走的路,但显然它有一些我不熟悉的怪癖。

const { jimpEvChange } = require('@jimp/core');
const { write } = require('jimp');
const { composite } = require('jimp');
const jimp = require('jimp');
var fs = require('fs');

// create an array of 6 colors and specify the colors
const colors = [
['green'],
['red'],
['blue'],
['yellow'],
['purple'],
['orange']
];

// call functions to colorize the images
var pngFiles = GetPNGs("ToColor/");
for (var i = 0; i < pngFiles.length; i++) {
var image = new jimp(pngFiles[i]);
Colorize(image, colors[i]);
image.write(pngFiles[i]);
}


// get pngs from a folder "ToColor" and colorize them each using the colors array
function GetPNGs (folder) {
var pngFiles = [];
const newLocal = fs.readdirSync(folder);
var files = newLocal;
for (var i = 0; i < files.length; i++) {
var file = files[i];
if (file.split(".").pop() == "png") {
pngFiles.push(folder + "/" + file);
}
}
return pngFiles;
}

// colorize the images
function Colorize (image, color) {
image.color([
{ apply: 'red', params: [color[0]] },
{ apply: 'green', params: [color[0]] },
{ apply: 'blue', params: [color[0]] }
]);
}

// loop through the images and colorize them
function ColorizeImages (pngs, colors) {
for (var i = 0; i < pngs.length; i++) {
var image = new jimp(pngs[i]);
Colorize(image, colors[i]);
image.write(pngs[i]);
}
}

如有任何提示,我们将不胜感激。谢谢,詹姆斯。

最佳答案

好吧,我试了一下,想出了这个例子:

请注意,此代码需要位于扩展名为 .mjs 的文件中,因为我们使用的是 import 语句而不是 require。您可以使用与使用 node index.mjs 的普通 .js 文件完全相同的方式运行 .mjs 文件。如果您真的想改用 requires,请将导入更改为 requires 并使用 .js 扩展名正常命名文件。

import jimp from "jimp";
import fs from "fs";

// I wanted to make this example to use async/await properly with Jimp
// So that's why we are using util.promisify to convert fs.readdir
// into a function named readDir, which we can await on
import util from "util";
const readDir = util.promisify(fs.readdir);

// Colors for mix operations
const colors = [
{r: 0, g: 255, b: 154, a: 1},
{r: 255, g: 40, b: 108, a: 1},
{r: 26, g: 172, b: 255, a: 1},
{r: 255, g: 190, b: 171, a: 1},
{r: 255, g: 239, b: 117, a: 1},
{r: 137, g: 91, b: 255, a: 1}
];

// Colorsnames for output file naming, these correspond to colors array
const colorNames = ['green', 'red', 'blue', 'orange', 'yellow', 'purple'];

// Define which color operations we want to do, using mix as an example
// https://www.npmjs.com/package/jimp#colour-manipulation
const operations = colors.map((c) => {
return { apply: "mix", params: [c, 60 ]};
});

// Input and output folder names
const inputFolderName = "./ToColor";
const outputolderName = "./out";
const outputFileSuffix = "edited"; // Optional suffix for the output files

// We're using async/await, so must wrap top level code like this
// https://stackoverflow.com/questions/46515764/how-can-i-use-async-await-at-the-top-level
(async () => {

// Get filenames of the png files in the specified folder
let pngFileNames = await readDir(inputFolderName);

// Optional filtering of only .png files
pngFileNames = pngFileNames.filter((f) => f.includes(".png"));

// Go through each file
// Must use for...of loop here, because we have awaits inside the loop
let i = 0;
for (let fileName of pngFileNames) {

// Optional output file name suffixing
const outPutFileName = outputFileSuffix.length > 0 ? fileName.split('.').reduce((a, b) => `${a}_${outputFileSuffix}.${b}`) : fileName;

// Make an actual Jimp image object from the file
const jimpImage = await jimp.read(`${inputFolderName}/${fileName}`);

// Make one new image per operation, so in total, we output colors.length * pngFileNames.length images
let j = 0;
for(let colorOperation of operations) {
// Apply operation
jimpImage.color([colorOperation]);

// Write the edited image to out folder
await jimpImage.writeAsync(`${outputolderName}/${colorNames[j]}_${outPutFileName}`);
j++;
}

i++;
}

})();

您的代码有很多问题。在阅读实际图像方面存在一些问题,在使用 Jimp 库方面存在大量问题,但除非您希望我这样做,否则我不会一一详述。

关于 Jimp 文档,您是对的,它……太糟糕了。特别是如果您总体上是 JavaScript 新手。

您最大的问题可能是您如何尝试创建新的 Jimp 图像对象。 The documentation说使用 new Jimp(...) 是为了创建图像,这意味着如果您首先没有任何图像,您将使用它。

但是,当您已经在某个文件夹中拥有图像并想加载它们以使用 Jimp 进行编辑时,您需要改用 jimp.read(...)jimp.read 是一个异步函数,这意味着即使尚未读取图像,您的其余代码也会继续运行。出于这个原因,我们需要使用 await jimp.read,您可以将其视为“暂停”程序,直到 jimp.read 实际读取图像。

在读取图像并将图像对象放入名为 jimpImage 的变量中后,我们使用预定义的 操作数组调用 jimpImage.color() ,在本例中我们使用 mix。此函数不是异步的,因此我们不必await

最后,在我们对图像应用着色操作后,我们使用 writeAsync 将图像保存到具有相同名称(和可选后缀)的指定输出文件夹。顾名思义,这是一个异步函数,所以我们必须await它。

程序运行完成后,您可以在指定的输出文件夹中找到修改后的图像。

另请注意,Jimp 将一些文档委托(delegate)给了 TinyColor Github page,尤其是关于“颜色内容”的文档,因为 Jimp 在引擎盖下使用 TinyColor 来处理某些与颜色相关的实用程序。因此,如果您想知道是否可以使用“红色”一词代替“#FF0000”,例如,TinyColor 文档提供了答案。

关于错误:w和h必须是数字-错误;最可能的原因是您使用 var image = new jimp(pngFiles[i]); 为 Jimp 初始化了错误的图像。就像我说的,这是为了从头开始创建新图像,我指的是 the documentation再次,它表示如果您使用此语法来创建新图像,它会像这样使用(其中前两个参数是 widthheight,它们不是在您的代码中给出):

new Jimp(256, 256, (err, image) => {
// this image is 256 x 256, every pixel is set to 0x00000000
});

我已经为您提供了一个简化示例,说明如何读取图像、对图像应用一些操作并将修改后的图像写回某个文件夹。剩下的就交给你了!

有问题就问吧,我现在是 Jimp 大师了。

这些是我使用的测试图像:

testimgs

这些是程序输出的内容(记住数量只有 60 并且我们的基础图像具有强烈的颜色):

output

关于javascript - 使用 jimp 为图像着色,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/72614669/

33 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com