I am new to meteor, what I am trying to do is upload an image store it in the file system and then simply display the images I have loaded.
I am also creating a thumbnail of the images I am uploading like this
var createThumb = function(fileObj, readStream, writeStream) {
// Transform the image into a 10x10px thumbnail
gm(readStream, fileObj.name()).resize('10', '10').stream().pipe(writeStream);
};
Images = new FS.Collection("images", {
stores: [
new FS.Store.FileSystem("thumbs", { transformWrite: createThumb }),
new FS.Store.FileSystem("images", {path: "~/uploads"})
],
filter: {
allow: {
contentTypes: ['image/*'] //allow only images in this FS.Collection
}
}
});
I have couple of issues, first of all I want to specify a path on the computer where I can store the image. I am not sure how I do that. I have created a public folder in the project and would like to store the images there.
When I start doing the thumbnail thing it is not working at all. I am not sure if the images (both original and the thumbnail) are even uploaded.
Can anyone explain or point towards me a good tutorial?
Here are some tutorials
From RaiX
Collection FS Wiki Page
Blog Post by Victor Leung
I haven't used Collection FS in a few months, but this code below should work.
Images = new FS.Collection("images", {
stores: [
new FS.Store.FileSystem("thumbs", { path: "~/public/thumbs", transformWrite: createThumb }),
new FS.Store.FileSystem("images", { path: "~/public/images" })
],
filter: {
allow: {
contentTypes: ['image/*'] //allow only images in this FS.Collection
}
}
});
Related
I have setup meteor application on AWS server. I have used cfs:gridfs package for image uploading. Below is my code for that.
Images are getting uploded but when I am displaying them it does not render on server but works perfectly fine on localhost.
This is my image source
img src="/cfs/files/images/LquzjvKk4HmQRXP3v?store=thumbs"
If i remove store=thumbs from image source then it renders image. It's something related to the store that is causing the issue. I have checked the code and it is ok and works well on local. Below is my code.
var imageStore = new FS.Store.GridFS("images");
var createThumb = function(fileObj, readStream, writeStream) {
// Transform the image into a 59x45px thumbnail
gm(readStream, fileObj.name()).resize('59',
'45').stream().pipe(writeStream);
};
var createLogo = function(fileObj, readStream, writeStream) {
// Transform the image into a 171x57px thumbnail
gm(readStream, fileObj.name()).resize('171',
'57').stream().pipe(writeStream);
};
Images = new FS.Collection("images", {
stores: [
imageStore,
new FS.Store.GridFS("thumbs", { transformWrite: createThumb }),
new FS.Store.GridFS("logos", { transformWrite: createLogo })
],
'defaultPermission':true,
});
Thanks in advance
Model code:
ProfileImage = new FS.Collection('profileImage', {
stores: [
new FS.Store.FileSystem('profile-image')
],
filter: {
maxSize: 524288,
allow: {
extensions: ['png', 'jpg', 'jpeg'],
contentTypes: ['image/png', 'image/jpg', 'image/jpeg']
}
}
});
Insertion code:
ProfileImage.insert('http://graph.facebook.com/' + user.services.facebook.id + '/picture/?type=large', function(error, imageObj) {
console.log(imageObj);
});
with that code I get a file name like this: profileImage-iiGE2ouSifuu3iLjq-undefined .
the name is undefined and without extension at all.
Try this (copied from a project of mine. this works):
//this is the event for when you select an image
'change .yourfileinput': function (event, template) {
FS.Utility.eachFile(event, function (file) {
var yourFile = new FS.File(file);
Images.insert(yourFile, function (err, fileObj) {
var fileUrl = '/cfs/files/profile-image/'+fileObj._id;
Session.set('fileUrl', fileUrl);
});
});
},
//form submit event
"submit .your-form-class": function (event) {
var whichUser = Meteor.userId() //or you could just write this inside the method call instead of adding a variable
var profilePicture = Session.get('fileUrl');
Meteor.call("yourMethod", whichUser, profilePicture);
}
Of course, you need to play on it/customise to your needs. ^ is for default file path of cfs:filesystem.
I switched to gridfs though and I highly recommend it.
Edit your question with all your code if it doesn't work and we'll find a solution. File upload was the biggest problem I encountered along the way.
How to get file url for specific store using collectionFS in meteor?
I need to retrieve it in my onrendered code:
var url = Images.findOne(filesList[index].id).url();
This return me default store for Images, but in Images i have two store:
Images = new FS.Collection("images", {
stores: [fullImage, previewImage],
filter: {
allow: {
contentTypes: ['image/*']
},
onInvalid: function (message) {
if (Meteor.isClient) {
toastr.warning("Impossibile salvare l'immagine a causa di: " + message);
} else {
console.log(message);
}
}
}
});
I need to retrieve previewImage, i cannot use tag code because i need to download it in background on the client..
Just found a simple solution:
Images.findOne(filesList[index].id).url({store: 'preview'});
In my demo I'm using the https://github.com/tomitrescak/meteor-uploads package for image uploading and its working like a charm. Now I want to call my image processing function before the file is uploaded.
Once my image processing function is done, I want to start uploading the image to my local (that is already working by meteor-uploads package).
How it can be achieved?
I would switch over to using CollectionFS. They have image manipulation ( imagemagick, graphicsmagick) abilities for file file uploads. So when you define your collection using CollectionFS use:
Images = new FS.Collection("images", {
stores: [
new FS.Store.FileSystem("thumbs", { transformWrite: createThumb }),
new FS.Store.FileSystem("images"),
],
filter: {
allow: {
contentTypes: ['image/*'] //allow only images in this FS.Collection
}
}
});
var createThumb = function(fileObj, readStream, writeStream) {
// Transform the image into a 10x10px thumbnail
gm(readStream, fileObj.name()).resize('10', '10').stream().pipe(writeStream);
};
Notice that the createThumb is using graphicsmagick in the function createThumb (gm) to resize the image for you before inserting it into the collection images under the specific store thumbs.
I'm trying to use the cfs:graphicsmagick package to generate thumbnails but all that is generated is an empty image.
When I start the server things look good:
I20150108-10:43:14.698(-8)? => GraphicsMagick found
I20150108-10:43:14.901(-8)? available
=> Meteor server restarted
but it seems gm is not available:
if (gm.isAvailable) {
console.log("gm is available");
}
and the console throws out an error:
Uncaught TypeError: Cannot read property 'isAvailable' of undefined
Look into docs, seems like the gm scope its just available on the server side, so there is not problem here, you are having the console.log, pretty find
now you can use, on the fsCollection like this
Images = new FS.Collection("images", {
stores: [
new FS.Store.FileSystem("images"),
new FS.Store.FileSystem("thumbs", {
transformWrite: function(fileObj, readStream, writeStream) {
// Transform the image into a 10x10px thumbnail
gm(readStream, fileObj.name()).resize('10', '10').stream().pipe(writeStream);
}
})
],
filter: {
allow: {
contentTypes: ['image/*'] //allow only images in this FS.Collection
}
}
});
remember gm its just available on the server, so use it on /server or use on if(isServer)
Try this
if (Meteor.isServer) {
if (gm.isAvailable) {
console.log("gm is available and this console.log was printed from my own code");
}
}
Tell me if works
Update answer
If you are declaring FS.collection on both server/client i recommend you declare collection on /lib/collection.js like this
//collections.js
Adopcion = new FS.Collection("Adopcion", {
stores: [
new FS.Store.FileSystem("images"),
new FS.Store.FileSystem("thumbs", {
transformWrite: function(fileObj, readStream, writeStream) {
// Transform the image into a 10x10px thumbnail
gm(readStream, fileObj.name()).resize('10', '10').stream().pipe(writeStream);
}
})
]
});
and on the same file make the subscription
//collection.js
//Subscribe
if(Meteor.isClient) {
Meteor.subscribe('Adopcion');
}
And now on /server/publish.js you only make the publish function
//Publish methods
Meteor.publish('Adopcion', function(){
return Adopcion.find();
});
With that there is no need of Meteor.methods({}) and the first thing meteor will load its the collection, and they will be available on both client/server
Take a look and tell me if works for you