I currently am running a Node 8 Lambda function using ImageMagick 7 surfaced by the Node gm module (https://github.com/aheckmann/gm) to annotate some image processing. The other ImageMagick functions (such as resize()
or quality()
) that I am using work correctly; however using drawText()
does not error yet also does not result in any text being drawn on the image that is output back to s3. I haven't been able to find much information about using drawText()
in Lambda and am curious if anyone else is successfully doing it, using Node or otherwise. Any firsthand experience or insights would be much appreciated.
I am suspicious that this has something to do with fonts (or lack thereof), and therefore have tried to add my own font of <type name="Gotham" fullname="Gotham-Book" family="Gotham" weight="400" style="normal" stretch="normal" glyphs="/var/task/imagemagick/etc/ImageMagick-7/Gotham-Book.ttf"/>
to the ImageMagick type.xml
file found at etc/ImageMagick-7/type.xml
.
const aws = require('aws-sdk');
const im = require('gm').subClass({
imageMagick: true,
appPath: '/var/task/imagemagick/bin/',
});
const s3 = new aws.S3();
const IMAGEMAGICK_PATH = `${process.env.LAMBDA_TASK_ROOT}/imagemagick/bin/`;
const INPUT_SOURCE_BUCKET = 'input';
const OUTPUT_SOURCE_BUCKET = 'output';
exports.handler = (event, context) => {
process.env.PATH = `${process.env.PATH}:${IMAGEMAGICK_PATH}`;
console.log(`** Event Received ** ${event.Records[0].Sns.Message}`);
const message = JSON.parse(event.Records[0].Sns.Message);
const inputKey = decodeURIComponent(message.Records[0].s3.object.key.replace(/\+/g, ' '));
console.log(`** Image Input Key ** ${inputKey}`);
// This splits the input key on the `/`, creates an array of strings,
// and pulls the last string from that array.
const filename = inputKey.split('/')[3].split('.')[0];
let channel;
let imageBuffer;
let imageType;
let outputKeyPath;
let shootId;
console.log('** Download beginning **');
// Download the image from S3 into a buffer.
const getParams = {
Bucket: INPUT_SOURCE_BUCKET,
Key: inputKey
};
s3.getObject(getParams, (err, response) => {
if (err) {
console.log('err :', err);
return err;
}
imageBuffer = response.Body;
...pause to assign relevant variables & such, and then ...
console.log(imageBuffer, filename);
im(imageBuffer)
.antialias(true)
// Remove profile data http://aheckmann.github.io/gm/docs.html#profile.
.noProfile()
.resize(830)
// Adjusts the jpeg|miff|png|tiff compression level, values
// range from 0 to 100.
.quality(85)
.fill('white')
.font('Gotham', 24)
.drawText(4, 7, 'image text', 'SouthWest')
.toBuffer('PNG', (err, buffer) => {
if (err) {
console.error(`** error - convert - toBuffer - ${err} **`);
return err;
}
const Key = `${outputKeyPath}_full.png`;
console.log(`** Output Path ** ${Key}`);
...end of the relevant bit, processed image is then sent back to s3