Search code examples
ruby-on-railsamazon-s3imagemagickrmagickcarrierwave

Image manipulation Rails Carrierwave to Amazon S3


I am uploading images using jquery upload to Amazon s3, I am using Ruby Gems carrierwave and fog to make it work... But what I am trying to do is when I upload an image to s3, the image generated by carrierwave that will be store in amazon S3 should not be larger than 500kb even though the original img filesize uploaded was 3mb or bigger.

basically I wan't to have a control and limit the filesize of the final image.

And also 1 more thing what should I do if I wan't to keep track of the height and width of my files in Amazon S3. i.e. I wan't to save those WxH of the images to database so that I will have some reference if I need it.

Any Comments, Ideas, or Suggestions are much appriciated.

Thanks.


Solution

  • A good pattern to use is to upload the file directly to Amazon s3 and then add it into your app with Carrierwave from that location. If you store the file in a temporary bucket/location on s3, you can then have carrierwave effectively process then move it. After it is directly uploaded to s3, and assuming you have available the bucket and address you uploaded it to, you can use code like this to have Carrierwave pick it up, process it, and "move" it:

      def add_file_from_URL(bucket, object_address)
        s3 = AWS::S3::new
        bucket = s3.buckets[bucket]
        object = bucket.objects[object_address]
        object_url = object.url_for(:read, :expires => 60*60, :secure => true) #expires in 1 hour
        self.remote_attachment_url = object_url.to_s
        self.save
        object.delete()
      end
    

    This code would go in your model that has the file within it.

    I have left out the code to process (resize) the file, as you should be able to find that within the Carrierwave docs easily if you don't already have that part done.

    To keep track of meta data for the file I would suggest use a :before_save callback to store this information in fields along side the file. You would have a method like this:

      private
        def update_file_attributes
          if file.present?
            self.file_content_type = attachment.file.content_type
            self.file_size = attachment.file.size
          end
        end
    

    In this example, I am saving the actual file size, but you could tweak this for dimensions instead. This goes in the model that you save the file in.