5

画像の管理に CollectionFS を使用しています。gm()さらに、画像の操作にgraphicsmagickを使用しています。

ここで、既に保存されている画像をトリミングしたいと考えています。したがって、クリック イベントでは、crop() を実行するサーバー メソッドが呼び出されます。しかし、これを行った後、コレクションでsize=0正しい日付に更新された空の画像を見つけました。

私が間違っていることはわかりません。

共有.js

Images = new FS.Collection("images", {
    stores: [
        new FS.Store.FileSystem("thumbnail", { 
            transformWrite: function(fileObj, readStream, writeStream) {
                gm(readStream, fileObj.name()).autoOrient().resize('96', '96' + '^').gravity('Center').extent('96', '96').stream().pipe(writeStream);
            } 
        }),
        new FS.Store.FileSystem("public"),
    ]
});

サーバー.js

Meteor.methods({
    'crop': function (fileId, selection) {
        var file = Images.findOne({ _id: fileId }),
            read = file.createReadStream('public'),
            write = file.createWriteStream('public');

        gm(read)
            .crop(selection.width, selection.height, selection.left, selection.top)
        .stream()
        .pipe(write);
    }
});

client.js

Template.editor.events({
    'click #crop': function () { 
        var fileId      = '123456789',
            selection   = { height: 100, width: 100, top: 10, left: 10 }; 

        Meteor.call('crop', fileId, selection);
    }
});

アップデート

クリスチャンが推奨するように、writeStream は readStream のように同じにすることはできないため、writeStream に tmp ファイルを使用しています。これにより、結果が空になりました。

ただし、tmp ファイルに書き込んだ後、その内容をパブリック ストアにコピーする必要があります。それ、どうやったら出来るの?

Meteor.methods({
    'crop': function (fileId, selection) {

        var fs   = Meteor.npmRequire('fs'),
            file = Images.findOne({ _id: fileId }),
            read = file.createReadStream('public'),
            filename = '/tmp/gm_' + Date.now(),
            tmp  = fs.createWriteStream(filename);

        gm(read)
            .crop(selection.width, selection.height, selection.left, selection.top)
        .stream()
        .pipe(tmp);

        // After writing to tmp -> copy back to stream and delete tmp-file
    }
});

更新2 私はこれを試しました:

// Add temp store
new FS.Store.FileSystem("temp")

// Method
Meteor.methods({
    'crop': function (fileId, selection) {
        var file  = Images.findOne({ _id: fileId }),
            read  = file.createReadStream('public'),
            temp  = file.createWriteStream('temp');

        gm(read)
            .crop(selection.width, selection.height, selection.left, selection.top)
        .stream()
        .pipe(tmp)
        .on('end', function () {
            var tmpread  = file.createReadStream('temp'),
                write    = file.createWriteStream('public');

            gm(tmpread).stream().pipe(write);
        });

    }
});
4

1 に答える 1

2

同じファイルに読み書きすることはできません。これは次のようなものと同等です

cat test | grep 1 > test

シェルに。試してみて、test後で空になることを確認できます。

メソッドで中間の一時ファイルを作成する必要がありますcrop


それが実際に問題であると仮定すると、これはこれを行う1つの方法です(テストされていません):

var fs = Meteor.npmRequire('fs');
var file = Images.findOne({ _id: fileId }),
var read = file.createReadStream('public'),
var filename = '/tmp/gm_' + Date.now();
var tmp = fs.createWriteStream(filename);

var gmread = gm(read)
    .crop(selection.width, selection.height, selection.left, selection.top)
    .stream();

gmread.on('end', function() {
    // done streaming through GM, copy the result back:
    var tmpread = fs.createReadStream(filename);
    var write = file.createWriteStream('public');
    tmpread.pipe(write);
});

gmread.pipe(tmp);
于 2015-11-20T17:36:56.687 に答える