0

I would like to use the AWS Lambda service to convert SVG to PNG with the language NodeJS.

In a second time, the SVG will contain text with custom fonts, I want to know how to use external fonts.

Currently i convert SVG to PNG with PHP Here is an example of conversion in PHP:

$im = new Imagick();
$draw = new ImagickDraw();
$im->setFormat('MSVG');
// Open SVG with ImageMagick
$im->readImageBlob($svgParse->asXML());
$im->setImagePage(0, 0, 0, 0);
$im->scaleImage($viewBox['2'],$viewBox['3'], false);
// Add Text with custom FONT
foreach($ListText as $text){
    // Set Custom FONT
    $draw->setFont(Mage::getBaseDir('media').DS.'font'.DS.$text['font-family'].".ttf");
    $draw->setFontSize( $text['font-size'] );
    $draw->setFillColor ( $text['fill']);
    // Add text in image
    $im->annotateImage($draw, $text['x'], $text['y'], 0, $text['text']);
}
/*png settings*/
// FB image
$imFB = clone $im;
$imFB->setFormat('PNG');
$imFB->cropImage(760, 400,0, 0);
$imFB->scaleImage(600,400,1);
// Save
$imFB->writeImage($filename_FB);
$imFB->clear();
$imFB->destroy();

it would be perfect if I can transform the above code for AWS Lambda. I chose NodeJS because I find more examples on web compared to Python and Java but if you control over Python or Java, no problem I change language

code currently on AWS lambda :

var im = require('imagemagick');
var fs = require('fs');
var util = require("util");


var postProcessResource = function(resource, fn) {
    var ret = null;
    if (resource) {
        if (fn) {
            ret = fn(resource);
        }
        try {
            fs.unlinkSync(resource);
        } catch (err) {
            // Ignore
        }
    }
    return ret;
};

exports.handler = function(event, context) {
    var operation = event.operation;
    delete event.operation;
    if (operation) {
        console.log('Operation', operation, 'requested');
    }

    switch (operation) {
        case 'ping':
            context.succeed('pong');
            break;
        case 'convert':

            var conv = im.convert(['svg:-', 'png:-'])
            conv.on('data', function(data) {
                //console.log('data');
                //console.log(data);
            }); 
            conv.on('end', function() {
                //console.log('end');
            });                                                                                
            conv.stdin.write('<svg height="100%" version="1.1" width="100%"   style="overflow: hidden; position: relative;" id="paper" viewBox="0 0 760 890" preserveAspectRatio="xMinYMin"><desc style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);">Created with Raphaël 2.1.2</desc><defs style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"></defs><image x="0" y="0" width="760" height="890" xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="http://camaieu.akria.fr/media/catalog/product/cache/1/image_position_coeur/9df78eab33525d08d6e5fb8d27136e95/3/_/3_1_2.png" id="svg_image" preserveaspectratio="" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);" stroke-width="1" product_id="22"></image><text x="320" y="400" text-anchor="left" font-family="detex" font-size="32px" stroke="none" fill="#fefefe" id="svg_message" stroke-width="1" height="80" width="170" style="font-size: 32px;"><tspan dy="10.6015625" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);">zdfazerf</tspan></text></svg>');
            conv.stdin.end();
            console.log(conv.toString('base64'));
            break;
        default:
            context.fail(new Error('Unrecognized operation "' + operation + '"'));
    }
};

The process takes 9s but I do not know retrieve the result, I do not even know what that actually

Example unsuccessfully :

I am starting on NodeJS and AWS Lambda.

Thx.

cody
  • 11,045
  • 3
  • 21
  • 36
S8N
  • 1
  • 2
  • maybe you could have a look at elasticTranscoder AWS service https://aws.amazon.com/elastictranscoder/ – Tom Jan 20 '16 at 13:30
  • AWS elastic Transcoder support just format video and audio, it does not allow convert images – S8N Jan 20 '16 at 16:28
  • ow yes sorry my bad. This is a request feature but not available yet – Tom Jan 20 '16 at 16:39

1 Answers1

1

Here's what I just got to work for custom fonts on AWS Lambda with pandoc/xelatex. I'd bet you can adapt this technique for your purposes.

I created a fonts directory in my project and placed all of my fonts there. Also in that directory I created a fonts.conf file that looks like this:

<?xml version="1.0"?>
<!DOCTYPE fontconfig SYSTEM "fonts.dtd">
<fontconfig>
  <dir>/var/task/fonts/</dir>
  <cachedir>/tmp/fonts-cache/</cachedir>
  <config></config>
</fontconfig>

And then in my (node.js based) handler function before shelling out to call pandoc I set an ENV var to tell fontconfig where to find the fonts.

process.env.FONTCONFIG_PATH='/var/task/fonts'

After doing that I can refer to a font, like Bitter, in my template by name (just Bitter) and then pandoc/xelatex/fontconfig/whatever knows which version of the font to use (like Bitter-Bold.otf vs Bitter-Italic.otf) based on the styling that any bit of text is supposed to have.

I figured this out based on the tips in this project for getting RSVG to work with custom fonts on Lambda: https://github.com/claudiajs/rsvg-convert-aws-lambda-binary/blob/master/README.md#using-custom-fonts

Jeremy Green
  • 8,547
  • 1
  • 29
  • 33