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;
                                    }
                                });
                            }
                        });
                    }
                });
            }
        });
    });
}
  • 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. – Volune Aug 18 '14 at 22:02
  • @Volune 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 file –  Aug 18 '14 at 22:10
  • 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. – Volune Aug 18 '14 at 22:25
  • @Volune It becomes empty after doing whatever it's trying to do with it –  Aug 18 '14 at 22:45
  • Try checking if jpgName is [NOT empty](http://stackoverflow.com/questions/23114374/file-uploading-with-express-4-0-req-files-undefined) first. – Alvin K. Aug 19 '14 at 05:07
  • @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. –  Aug 19 '14 at 16:24
  • @Houseman: `gm("image.png").filesize()` fails with latest Node. Can you confirm that? Seems like a `gm()` issue, not coding. – Alvin K. Aug 19 '14 at 19:27

1 Answers1

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);
        }
    });
Eugene Obrezkov
  • 2,910
  • 2
  • 17
  • 34