nodejs - GraphicsMagick - 在框架中添加图像以创建另一个图像
nodejs - GraphicMagick - Add images in a frame to create another image
我在服务器中保存了一个示例图像帧(见下文)和一个函数,该函数将获取一组图像 URLs,将图像裁剪成圆形以匹配图像的高度/宽度框架中的猫图像(60px x 60px)并根据图像数量从左侧替换猫,最后将图像保存回来
我需要知道如何在 node.js.
中使用 graphicMagick 来做到这一点
只是为了更清楚
- 我有一张图片frame.png
- 我有一个包含两个 URL 的数组 ['www.someurl.com/image1.jpg', 'www.someurl.com/image2.jpg]
- 对于数组中的每个 URL
- 将图像 i 从 URL 下载到临时位置
- 将图片i裁剪成半径为60的圆形
- 将它放在 frame.png 之上的某个位置 (xi,yi)
- 保存新合成图像
- 上传回来
我在这里发布了我的解决方案,我对图像进行了循环处理,然后将它们组合在框架图像 (png) 上。
此解决方案的唯一缺点是对文件进行了多次写入,而我无法在一次写入中完成。
我希望这对以后的人有所帮助,
const gm = require('gm').subClass({ imageMagick: true })
export async function convertToCircularImage(imagePath: string, resultPath: string) {
const radius = 180
return new Promise(function (resolve, reject) {
gm(imagePath)
.autoOrient()
.gravity('Center')
.resize(radius, radius, '^')
.extent(radius, radius)
.noProfile()
.setFormat('png')
.out('(')
.rawSize(radius, radius)
.out('xc:Black')
.fill('White')
.drawCircle(radius / 2, radius / 2, radius / 2, 1)
.out('-alpha', 'Copy')
.out(')')
.compose('CopyOpacity')
.out('-composite')
.trim()
.write(resultPath, (err: Error) => {
if (err) {
console.error('Failed to crop image.', err)
reject(err)
} else {
console.log(`Cropped image at ${imagePath} and saved it at ${resultPath}`)
resolve(resultPath)
}
})
})
}
export async function composite(
frameImagePath: string,
circularImagesPaths: string[],
resultImagePath: string,
points: string[],
) {
let frameImage = frameImagePath
let index = 0
for (const circularImagePath of circularImagesPaths) {
const point = points[index]
try {
// this method return the resultImagePath which is then used as a frame for next composition
frameImage = await composeImage(frameImage, circularImagePath, point, resultImagePath)
} catch (e) {
console.log('Composite: some error', e)
}
index = index + 1
}
}
async function composeImage(
frameImage: string,
circularImage: string,
point: string,
resultPath: string,
): Promise<string | any> {
console.log('Composing circular image to frame...', frameImage, circularImage)
return new Promise(function (resolve, reject) {
gm(frameImage)
.composite(circularImage)
.in('-compose', 'Dst_Over') // to only overlap on transparent parts
.geometry(point)
.in()
.write(resultPath, function (err: any) {
if (err) {
console.error('Composing failed', err)
reject(err)
} else {
console.log('Composing complete')
resolve(resultPath)
}
})
})
}
我在服务器中保存了一个示例图像帧(见下文)和一个函数,该函数将获取一组图像 URLs,将图像裁剪成圆形以匹配图像的高度/宽度框架中的猫图像(60px x 60px)并根据图像数量从左侧替换猫,最后将图像保存回来 我需要知道如何在 node.js.
中使用 graphicMagick 来做到这一点只是为了更清楚
- 我有一张图片frame.png
- 我有一个包含两个 URL 的数组 ['www.someurl.com/image1.jpg', 'www.someurl.com/image2.jpg]
- 对于数组中的每个 URL
- 将图像 i 从 URL 下载到临时位置
- 将图片i裁剪成半径为60的圆形
- 将它放在 frame.png 之上的某个位置 (xi,yi)
- 保存新合成图像
- 上传回来
我在这里发布了我的解决方案,我对图像进行了循环处理,然后将它们组合在框架图像 (png) 上。 此解决方案的唯一缺点是对文件进行了多次写入,而我无法在一次写入中完成。
我希望这对以后的人有所帮助,
const gm = require('gm').subClass({ imageMagick: true })
export async function convertToCircularImage(imagePath: string, resultPath: string) {
const radius = 180
return new Promise(function (resolve, reject) {
gm(imagePath)
.autoOrient()
.gravity('Center')
.resize(radius, radius, '^')
.extent(radius, radius)
.noProfile()
.setFormat('png')
.out('(')
.rawSize(radius, radius)
.out('xc:Black')
.fill('White')
.drawCircle(radius / 2, radius / 2, radius / 2, 1)
.out('-alpha', 'Copy')
.out(')')
.compose('CopyOpacity')
.out('-composite')
.trim()
.write(resultPath, (err: Error) => {
if (err) {
console.error('Failed to crop image.', err)
reject(err)
} else {
console.log(`Cropped image at ${imagePath} and saved it at ${resultPath}`)
resolve(resultPath)
}
})
})
}
export async function composite(
frameImagePath: string,
circularImagesPaths: string[],
resultImagePath: string,
points: string[],
) {
let frameImage = frameImagePath
let index = 0
for (const circularImagePath of circularImagesPaths) {
const point = points[index]
try {
// this method return the resultImagePath which is then used as a frame for next composition
frameImage = await composeImage(frameImage, circularImagePath, point, resultImagePath)
} catch (e) {
console.log('Composite: some error', e)
}
index = index + 1
}
}
async function composeImage(
frameImage: string,
circularImage: string,
point: string,
resultPath: string,
): Promise<string | any> {
console.log('Composing circular image to frame...', frameImage, circularImage)
return new Promise(function (resolve, reject) {
gm(frameImage)
.composite(circularImage)
.in('-compose', 'Dst_Over') // to only overlap on transparent parts
.geometry(point)
.in()
.write(resultPath, function (err: any) {
if (err) {
console.error('Composing failed', err)
reject(err)
} else {
console.log('Composing complete')
resolve(resultPath)
}
})
})
}