Node.js集成百度图像处理SDK实现人像动漫化
本文介绍如何通过Node.js调用百度AI开放平台的图像处理API,实现人像动漫化效果。
准备工作
首先需要在百度AI开放平台创建应用,获取APP_ID、API_KEY和SECRET_KEY。平台地址为百度AI开放平台官方文档。
核心实现
以下是完整的图像动漫化处理实现代码:
const fs = require("fs");
const path = require("path");
const { imageProcess } = require("./src/index.js");
// 百度云应用凭证
const APP_ID = "你的APP_ID";
const API_KEY = "你的API_KEY";
const SECRET_KEY = "你的SECRET_KEY";
// 初始化图像处理客户端
const client = new imageProcess(APP_ID, API_KEY, SECRET_KEY);
/**
* 人像动漫化处理
* @param {string} imageBase64 - Base64编码的图片数据
* @param {Object} options - 处理选项
* @returns {Promise<string>} 处理后的Base64数据
*/
async function processAnimeStyle(imageBase64, options = {}) {
const defaultOptions = [
{ type: "anime" },
{ mask_id: 3 }
];
const mergedOptions = [...defaultOptions, ...options];
try {
const result = await client.animeEnhance(imageBase64, mergedOptions);
return result.image;
} catch (error) {
console.error("图像处理失败:", error);
throw error;
}
}
/**
* 读取指定目录下的所有图片文件
* @param {string} dirPath - 目录路径
* @returns {string[]} 图片文件路径数组
*/
function getImageFiles(dirPath) {
const files = fs.readdirSync(dirPath);
return files
.filter(file => /\.(jpg|jpeg|png)$/i.test(file))
.map(file => path.join(dirPath, file));
}
/**
* 将Base64字符串转换为图片文件
* @param {string} base64Str - Base64编码的图像数据
* @param {string} outputPath - 输出文件路径
*/
function saveBase64AsImage(base64Str, outputPath) {
// 移除可能的data URI前缀
const base64Data = base64Str.replace(/^data:image\/\w+;base64,/, '');
const buffer = Buffer.from(base64Data, 'base64');
console.log("数据缓冲区是否为Buffer对象:", Buffer.isBuffer(buffer));
fs.writeFile(outputPath, buffer, (err) => {
if (err) {
console.error("文件写入失败:", err);
} else {
console.log(`文件已保存: ${outputPath}`);
}
});
}
/**
* 批量处理图片目录中的所有图像
* @param {string} inputDir - 输入目录路径
* @param {string} outputDir - 输出目录路径
*/
async function batchProcessImages(inputDir, outputDir) {
// 确保输出目录存在
if (!fs.existsSync(outputDir)) {
fs.mkdirSync(outputDir, { recursive: true });
}
const imageFiles = getImageFiles(inputDir);
console.log(`发现 ${imageFiles.length} 个图片文件`);
const results = {
success: [],
failed: []
};
for (const filePath of imageFiles) {
try {
const imageBuffer = fs.readFileSync(filePath);
const base64Image = imageBuffer.toString('base64');
const processedImage = await processAnimeStyle(base64Image);
const fileName = path.basename(filePath, path.extname(filePath));
const outputPath = path.join(outputDir, `${fileName}_anime.png`);
saveBase64AsImage(processedImage, outputPath);
results.success.push(filePath);
} catch (error) {
results.failed.push({ file: filePath, error: error.message });
console.error(`处理失败: ${filePath}`, error);
}
}
console.log("批量处理完成");
console.log(`成功: ${results.success.length}, 失败: ${results.failed.length}`);
return results;
}
// 主函数
async function main() {
const inputDirectory = "./assets";
const outputDirectory = "./output";
try {
await batchProcessImages(inputDirectory, outputDirectory);
} catch (error) {
console.error("程序执行错误:", error);
}
}
main();
SDK扩展实现
如果官方SDK中缺少人像动漫化接口,可以通过扩展方式添加:
// 在imageProcess类中添加以下方法
const ANIME_ENDPOINT = '/rest/2.0/image-process/v1/selfie_anime';
imageProcess.prototype.animeEnhance = function(image, options = []) {
const param = {
image: image,
targetPath: ANIME_ENDPOINT
};
// 合并自定义选项
const mergedParams = this.mergeOptions(param, options);
return this.commonImpl(mergedParams);
};
imageProcess.prototype.mergeOptions = function(baseParams, options) {
if (!options || options.length === 0) {
return baseParams;
}
options.forEach(opt => {
Object.assign(baseParams, opt);
});
return baseParams;
};
常见问题及解决方案
1. 类引入错误
导入官方SDK时需要注意大小写,正确的引入方式为:
const { imageProcess } = require("baidu-aip-sdk").imageProcess;
// 注意:Process首字母大写
2. 方法不可用
如果实例化后无法调用animeEnhance方法,可能是SDK版本未更新该接口,此时需要手动扩展SDK,参照上文提供的扩展代码实现。
3. Base64数据处理
处理返回的Base64数据时,原始数据可能包含前缀标记,需要正确处理:
// 正确处理Base64数据
const base64Data = result.image.includes('data:image')
? result.image.split(',')[1]
: result.image;
const buffer = Buffer.from(base64Data, 'base64');
4. 批量处理注意事项
批量处理时建议添加重试机制和错误日志,部分图片可能因格式问题导致处理失败,需要做好异常捕获。
效果说明
通过上述代码可以将普通照片转换为动漫风格图像,处理后的图像会保留原图的主体轮廓,同时应用动漫化的色彩和线条风格。