-
-
Notifications
You must be signed in to change notification settings - Fork 237
Image Manipulation
A common use for transformWrite
is to manipulate images before saving them.
To get this set up:
- Install GraphicsMagick or ImageMagick on your development machine and on any server that will host your app. (The free Meteor deployment servers do not have either of these, so you can't deploy to there.) These are normal operating system applications, so you have to install them using the correct method for your OS. For example, on Mac OSX you can use
brew install graphicsmagick
assuming you have Homebrew installed. - Add the
cfs:graphicsmagick
Meteor package to your app:meteor add cfs:graphicsmagick
The following are some examples.
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
}
}
});
Note that this example requires the cfs:filesystem
package.
To convert every file to a specific image format, you can pass a GraphicsMagick format string to the stream
method, but you will also need to alter the FS.File
instance as necessary in a beforeWrite
function.
Images = new FS.Collection("images", {
stores: [
new FS.Store.FileSystem("images"),
new FS.Store.FileSystem("thumbs", {
beforeWrite: function(fileObj) {
// We return an object, which will change the
// filename extension and type for this store only.
return {
extension: 'png',
type: 'image/png'
};
},
transformWrite: function(fileObj, readStream, writeStream) {
// Transform the image into a 10x10px PNG thumbnail
gm(readStream).resize(60).stream('PNG').pipe(writeStream);
// The new file size will be automatically detected and set for this store
}
})
],
filter: {
allow: {
contentTypes: ['image/*'] //allow only images in this FS.Collection
}
}
});
Note that this example requires the cfs-filesystem
package.
You may want to adjust a bunch of images that you've already stored. This can be done easily by streaming out of the store and then back into it. The following example is for illustration purposes, but you should not use it on production data unless you have a throttled queue in a separate process or only a very small number of images.
Images.find().forEach(function (fileObj) {
var readStream = fileObj.createReadStream('images');
var writeStream = fileObj.createWriteStream('images');
gm(readStream).swirl(180).stream().pipe(writeStream);
});
Note that you could also pipe the readStream from one store to the writeStream from another store to move files between stores, for example if you decide to use a different storage adapter and need to quickly and easily migrate the data. (We have not tested this, but it should be possible.)
footer25555555