GraphicsMagick processes resulting in empty file
Asked Answered
L

1

9

I'm doing this

gm(jpgName).setFormat('jpg')
    .resize(160,158)
    .compress('JPEG')
.write(fs.createWriteStream(jpgName),function(err){
    if(err){
        console.log(err,jpgName);
    res.send(400);
    }else{
        console.log('file formated to jpg' + jpgName);

And I get

{ [Error: Command failed: gm convert: Empty input file (/home/ubuntu/node/uploads/icon.jpg). ] code: 1, signal: null }

If I stop the code right before the first line written here, and then look at the file, it has a file length. If I let this process happen (error out) then look at the file, then it has a size of 0 bytes.

I also tried this:

fs.stat(jpgName, function (err, stats) {
    console.log('file size:',stats.size);
    gm(jpgName).setFormat('jpg')
        .resize(160,158)
        .compress('JPEG')
        .write(fs.createWriteStream(jpgName),function(err){
            if(err){
                console.log('console.log error writing jpg file',err,jpgName);
                    fs.unlink(jpgName);
                        callback(400);
                        return;
                    }else{//...

And I'm getting a file size back, so I know it's not empty before I start this process.

EDIT: I now start this process on form.on('end') so I could be sure the entire upload process was done.

The entire function:

function formatProfileImage(req,form,file,callback){
    console.log('formatting profile image');
    var ext = file.name.split('.')[1].toLowerCase();
    var name = encodeURIComponent(file.name.split('.')[0].toLowerCase());
    var smallName = form.uploadDir+"/"+"small_"+name+".jpg";
    var jpgName = form.uploadDir + "/" + name+'.jpg';

    console.log('extension:',ext);
    console.log('name:',name);
    console.log('smallName:',smallName);
    console.log('jpgName:',jpgName);

    if(!(ext == "png" || ext == "jpeg"|| ext == "jpg"|| ext == "gif")){
        fs.unlink(file.path);
        console.log("extension rejected");
        callback(415);
        return; 
    }

    console.log('renaming file from ' + file.path + ' to ' + jpgName);

    fs.rename(file.path,jpgName,function(err){
        if(err){
            console.log('error renaming file',err);
            callback(400);
            return;
        }

        console.log('file renamed');
        fs.stat(jpgName, function (err, stats) {
            console.log('file size:',stats.size);
            if(!(typeof req.query.tenant === 'undefined')){
                //rename to jpg
                gm(jpgName).setFormat('jpg')
                .resize(160,158)
                .compress('JPEG')
                .write(fs.createWriteStream(jpgName),function(err){
                    if(err){
                        console.log('console.log error writing jpg file',err,jpgName);
                        fs.unlink(jpgName);
                        callback(400);
                        return;
                    }else{
                        console.log('file formated to jpg' + jpgName);
                        //make "thumbnail"
                        gm(jpgName).setFormat('jpg')
                        .resize(50)
                        .write(fs.createWriteStream(smallName),function(err){
                            if(err){
                                fs.unlink(smallName);
                                console.log('error writing thumbnail',err,smallName);
                                callback(400);
                                return;
                            }else{
                                console.log('thumbnail created' + smallName);
                                //upload everything
                                uploadS3(jpgName,req.query.tenant,function(back){
                                    if(back.success){
                                        console.log('success ' +back.url);
                                        callback(back.url);
                                        fs.unlink(jpgName);
                                    }else{
                                        console.log('error uploading' + jpgName, back);
                                        callback(400);
                                        fs.unlink(jpgName);
                                        return;
                                    }
                                });
                                uploadS3(smallName,req.query.tenant,function(back){
                                    if(back.success){
                                        console.log('success ' +back.url);
                                        fs.unlink(smallName);
                                    }else{
                                        console.log('error uploading ' + smallName, back);
                                        callback(400);
                                        fs.unlink(smallName);
                                        return;
                                    }
                                });
                            }
                        });
                    }
                });
            }
        });
    });
}
Lisettelisha answered 18/8, 2014 at 21:35 Comment(7)
Have you checked that your input file isn't currently empty ? Could have become empty on a previous pass because fs.createWriteStream(jpgName) wrote nothing because of a different error.Curdle
@Curdle I can put a return just before the first line is run and look at the size of my file before this process occurs, so I can confirm it's not empty. I have logs before and after every other process that happens with this file, so I don't think that anything else is happening to the fileLisettelisha
I'll try it later (don't have gm for now), but I'm curious why the error message says the input file is empty if it's not.Curdle
@Curdle It becomes empty after doing whatever it's trying to do with itLisettelisha
Try checking if jpgName is NOT empty first.Sarazen
@AlvinK I'm doing fs.stat(jpgName) and I'm getting non-zero file size back right before I do the first gm operation. I posted that code.Lisettelisha
@Houseman: gm("image.png").filesize() fails with latest Node. Can you confirm that? Seems like a gm() issue, not coding.Sarazen
B
6

.write() accept string as path. So you need replace your stream with string (location, where resulting image must me saved).

GM support 3 ways of saving files.

1) Save to file. Simple, just use .write() and send as parameter string, where file should saved. Example:

gm('image.png')
    .resize()
    .write('resized.png', function (error) {
        if (error) {
            console.error(error);
        }
    });

2) Use streams, example:

gm('image.png')
    .resize()
    .stream(function (error, stdout, stderr) {
        var writeStream = fs.createWriteStream('resized.jpg');
        stdout.pipe(writeStream);
    });

3) And last one - buffers:

gm('image.png')
    .resize()
    .toBuffer(function (error, buffer) {
        if (error) {
            console.error(error);
        }
    });
Bukovina answered 19/8, 2014 at 17:4 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.