DISCLAIMER - Development of this package is currently on hiatus. We are currently not actively developing this package due to both resource constraints and uncertainty about how well supported it will be in the future. We are using this in our active projects, so we will continue to do bug fixes as we encounter them, but feature requests may go unanswered. PRs are still welcome.
Image Upload makes it super easy for you to setup a photo input field along with all the trimmings (S3, collections, permissions, templates, etc.). Under the hood you will find ImageUpload is just a sugary wrapper around collectionFS.
To get familiar with ImageUpload take a look at the rest of this read me as well as our example:
-
AWS S3 account for cloud file storage.
-
GraphicsMagick or ImageMagick on your local machine and deployment server for image manipulation.
-
OS X:
brew install imagemagick
orbrew install graphicsmagick
-
Modulus.io: supports ImageMagick no setup needed
-
Heroku, DigitalOcean, AWS EC2: requires manual ImageMagick/GraphicsMagick installation.
-
Meteor.com free hosting does not support ImageMagick/GraphicsMagick, sorry no way around it :(
Install from your terminal meteor add okgrow:image-upload
.
Configure in common code (server and client ).
API: ImageUpload.configure( options )
Example
ImageUpload.configure({
accessKeyId: YOUR_ACCESS_KEY_ID,
secretAccessKey: YOUR_SECRET_ACCESS_KEY,
bucketName: YOUR_BUCKET_NAME,
bucketUrl: YOUR_BUCKET_URL, //"https://your_bucket_name.s3.amazonaws.com/",
maxUploadSize: 30 // MB
});
WARNING You should never store your keys publicly, instead use Meteor.settings. Start your app using meteor --settings settings.json
. Refer to our example app settings file to see how we do it.
Note Since 0.8.0 publicRead
is now set in the image collection options. ImageUpload will throw an error if you try and pass publicRead
in ImageUpload.configure()
The images you upload will be stored in separate Image Upload collections. You will probably have more than one Image Upload collection. The Image Upload collections are created differently from Meteor collections, we show you how to make these special collections below.
Each Image Upload collection will reference and index it's documents to one of your app's data collections as specified, only one app data collection can be referenced per each Image Upload collection. We show you how to query by reference ids in templating below.
API: ImageUpload.createCollection( name, reference, { [options] } )
Options:
Name | Optional | Description |
---|---|---|
defaultPermissions | optional | Enables default Allow rules on your image collection, see Security Rules to see the rules |
publicRead | optional | set to true to server files directly from S3, bucketUrl in .configure() is also required. Also allows visitors to view images if defaultPermissions is also true. |
sizes | optional | Let ImageMagick create multiple different sizes of each image automatically. Specify a size name as the key followed by an array for X,Y px lengths |
The following creates an image collection called userImages
which will be associated with the Meteor.users
collection with images stored in four sizes:
- The original image
- "thumbnail": 200x200 px
- "normal": 800x800 px
- "large:": 1200x1200 px
UserImages = ImageUpload.createCollection("userImages", Meteor.users, {
defaultPermissions: true,
sizes: {
thumbnail: [200, 200],
normal: [800,800],
large: [1200, 1200]
}
});
Please add your own allow/deny rules and/or enable ImageUpload's defaultPermissions
when creating the ImageUpload collection.
defaultPermissions if enabled:
ImageCollection.allow({
insert: function(userId, doc) {
// Any authenticated user can create images
return !!userId;
},
update: function(userId, doc) {
// User can update their own image only
return doc && doc.addedBy === userId;
},
remove: function(userId, doc) {
// User can remove their own image only
return doc && doc.addedBy === userId;
},
download: function (userId, fileObj) {
// If publicRead has been set anyone can download, otherwise users
// can only download images that they uploaded
if (publicRead) {
return true;
} else {
return fileObj.addedBy === userId;
}
}
});
Note: Since the image collection is based on CollectionFS
, we use their allow
and deny
system. You can view their documentation here:
https://github.com/CollectionFS/Meteor-CollectionFS#security
You want a nice upload button with everything wired up for you? We got ya covered.
API: {{> uploadImage imageCollection=collectionName [option=option] }}
Examples:
{{> uploadImage imageCollection="userImages" size="thumbnail" doc=currentUser classImage="tiny-img round"}}
{{> uploadImage imageCollection="postImages" name="post-image" size="banner" }}
Attributes:
Name | Optional | Description |
---|---|---|
imageCollection | required | Specify the Image Upload collection images go to. hint: This was the first parameter when creating the Image Upload collection. |
doc | optional | When adding a new image to an existing document you can pass the existing document and we will make the reference for you. We pull the reference _id from the supplied object. |
size | optional | Specify the image size you want displayed when upload completes. By default this partial template displays the original uploaded image once complete. hint: You made these sizes when creating your Image Upload collection. |
name | optional | Specify a custom input element name. This overwrites the default input name attribute, image |
classInput | optional | Specify custom CSS class(es) for the input element. Included class is image-file-picker |
classImage | optional | Specify custom CSS class(es) for the image when it displays after upload completes. Included class isuploaded-image |
To display a stored image, you can
<template name="yourTemplate">
<img src="{{image}}"/>
</template>
Which uses a helper which loads a document from the image collection:
Template.yourTemplate.helpers({
image: function() {
var doc = Template.parentData(1);
var image = yourImageCollection.findOne({associatedObjectId: doc._id});
if (image) {
return image.url({store: "userImages-thumbnail"});
}
}
});
In order of fuzzy priority:
- Less configuration to setup
- Better error handling
- Default upload progress bar
- In-browser image cropping/resizing with darkroom.js
- Upload files from a URL
Issues and Pull Requests are always welcome. Please read our contribution guidelines.
At this point we don't have plans to support uploading files directly from the browser's client to AWS's S3. We may add this in the future, but there we will probably wait until CollectionFS supports this (they have it in the works). Pull requests welcome.
Enjoy!