2015-11-20 7 views
5

का उपयोग कर संग्रहएफएस में अप्रत्याशित खाली लेखस्ट्रीम मैं छवियों के प्रबंधन के लिए संग्रहFS का उपयोग कर रहा हूं। इसके अलावा मैं छवियों में हेरफेर करने के लिए ग्राफिक्समैजिक gm() का उपयोग कर रहा हूं।ग्राफिक्समैजिक

अब मैं पहले से ही सहेजी गई छवि को फसल करना चाहता हूं। इसलिए एक क्लिक ईवेंट पर एक सर्वर-विधि कहा जाता है, जो फसल() करता है। लेकिन ऐसा करने के बाद, संग्रह में मुझे 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); 
    } 
}); 

अद्यतन

ईसाई द्वारा सिफारिश के रूप में मैं writeStream के लिए एक tmp फ़ाइल का उपयोग कर रहा है, क्योंकि writeStream readStream की तरह समान नहीं हो सकती - जो खाली परिणाम का कारण बना।

लेकिन tmp-file पर लिखने के बाद, इसकी सामग्री को सार्वजनिक स्टोर में कॉपी करना होगा। मैं उसको कैसे करू?

// 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); 
     }); 

    } 
}); 

उत्तर

2

आप पढ़ सकते हैं और एक ही फाइल में लिख नहीं सकता:

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 मैं इस एक कोशिश की। यह

cat test | grep 1 > test 

शैल पर चीजों के बराबर है। आप इसे आजमा सकते हैं और देख सकते हैं कि 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); 
+0

तो यह करने के लिए क्या अंतर है:


यह मानते हुए कि वास्तव में है समस्या है, तो यह ऐसा करने का एक ही रास्ता (परीक्षण नहीं) है? https://github.com/CollectionFS/Meteor-CollectionFS/wiki/How-to:-Convert-a-file-already-stored – user3142695

+0

क्या आपने कोशिश की है और यह काम करता है? मैं धाराओं में एक विशेषज्ञ नहीं हूं, लेकिन जिस तरह से मैं उन्हें समझता हूं, यह भाग्यशाली हो सकता है अगर यह किया जाता है - यह छोटी फाइलों के लिए काम कर सकता है जो बफर से लिखने से पहले पूरी तरह से buffered मिलता है, लेकिन बड़े लोगों के लिए नहीं। लेकिन कौन जानता है, शायद संग्रह की अनुमति देने के लिए संग्रह कुछ आंतरिक रूप से स्मार्ट करता है। एक तरफ या दूसरा, मुझे नहीं लगता कि मैं उस पर भरोसा करता हूं। जब आप इसका परीक्षण करते हैं तो मुझे बताएं कि आप क्या खोजते हैं। –

+0

हम्म .. क्या आप कृपया एक उदाहरण दे सकते हैं कि आप एक अस्थायी धारा का उपयोग कैसे करेंगे? – user3142695