use*_*695 5 javascript graphicsmagick meteor collectionfs
我正在使用CollectionFS来管理图像.此外,我正在使用graphicsmagick gm()来处理图像.
现在我想要裁剪已保存的图像.因此,在单击事件上调用服务器方法,该方法执行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"),
]
});
Run Code Online (Sandbox Code Playgroud)
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);
}
});
Run Code Online (Sandbox Code Playgroud)
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);
}
});
Run Code Online (Sandbox Code Playgroud)
更新
正如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
}
});
Run Code Online (Sandbox Code Playgroud)
更新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);
});
}
});
Run Code Online (Sandbox Code Playgroud)
您无法读取和写入同一个文件。这相当于类似的事情
cat test | grep 1 > test
Run Code Online (Sandbox Code Playgroud)
在外壳上。你可以尝试一下,test然后就会看到它是空的。
您需要在您的crop方法中创建一个中间临时文件。
假设这确实是问题所在,那么这是执行此操作的一种方法(未经测试):
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);
Run Code Online (Sandbox Code Playgroud)