5
我正在使用CollectionFS來管理圖像。此外,我使用graphicsmagick gm()
來處理圖像。使用graphicsmagick的collectionFS中意外的空writestream
現在我想裁剪已保存的圖像。因此,在點擊事件中調用服務器方法,它執行crop()。但在完成此操作之後,在收集中,我找到一個空的圖像,並在正確的日期更新size=0
。
我不明白,我做錯了什麼。
shared.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"),
]
});
server.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);
}
});
更新
正如Christian所推薦的,我爲writeStream使用了一個tmp文件,因爲writeStream不能像readStream一樣 - 這導致了空的結果。
但寫入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);
});
}
});
那麼有什麼區別這樣做呢? https://github.com/CollectionFS/Meteor-CollectionFS/wiki/How-to:-Convert-a-file-already-stored – user3142695
你有沒有試過,它的工作?我不是流的專家,但我理解他們的方式可能是運氣,如果它確實如此 - 它可能適用於在從緩衝區開始寫入之前整體緩衝的小文件,但不適用於較大文件。但是誰知道,也許collectionfs在內部做了一些聰明的事情來允許這樣做。無論如何,我不認爲我會依賴這一點。讓我知道當你測試這個時你發現了什麼。 –
嗯..你能舉個例子說明你將如何使用臨時流? – user3142695