Rails: загрузка изображений с S3, изменение размера и загрузка обратно на S3

В моем приложении Rails 4 у ​​меня есть большое количество изображений, хранящихся на S3 с помощью Paperclip. URL-адрес изображения выглядит следующим образом: http://s3.amazonaws.com/bucketname/files/images/000/000/012/small/image.jpg?1366900621.

Учитывая следующий класс вложения:

  1. Как я могу загружать изображения с S3 и хранить локально?
  2. Затем, как изменить размер этого локально сохраненного изображения
  3. Загрузите изображение с измененным размером в другую корзину S3 без Paperclip (по пути s3/newbucket/images/{:id}/{imagesize.jpg})

Класс вложения:

class Image < ActiveRecord::Base
  has_attached_file :file, styles: { thumbnail: '320x320', icon: '64x64', original: '1080x1080' }
  validates_attachment :file, presence: true, content_type: { content_type: /\Aimage\/.*\Z/ }
end

person theGeekster    schedule 17.03.2015    source источник


Ответы (1)


Основной совет — не изменять размер изображений на лету, так как это может занять некоторое время, и ваши пользователи могут столкнуться с огромным временем отклика во время этой операции. Если у вас есть какой-то предопределенный набор стилей, было бы разумно сгенерировать их заранее и просто вернуть обратно, когда это необходимо.

Что ж, вот что можно сделать, если нет другого выхода.

def download_from_s3 url_to_s3, filename
  uri = URI(url_to_s3)
  response = Net::HTTP.get_response(uri)
  File.open(filename, 'wb'){|f| f.write(response.body)}
end

Здесь мы в основном загружали изображение, расположенное по заданному URL-адресу, и сохраняли его как файл локально. Изменение размера можно выполнить несколькими способами (это зависит от того, хотите ли вы использовать загруженный файл как вложение Paperclip). Наиболее распространенным подходом здесь было бы использование image-magick и его сценария командной строки convert. Вот пример изменения размера изображения до ширины 30:

convert  -strip -geometry 30 -quality 100 -sharpen 1 '/photos/aws_images/000/000/015/original/index.jpg' '/photos/aws_images/000/000/015/original/S_30_WIDTH__q_100__index.jpg' 2>&1 > /dev/null

Вы можете найти документацию по convert здесь, она подходит не только для изменения размера изображения, но и для преобразование между форматами изображений, размытие, обрезка и многое другое! Также вас может заинтересовать гем "Attachment-on-the-Fly", который кажется немного устарел, но имеет некоторое представление о том, как изменить размер изображений с помощью convert.

Последний шаг — загрузить изображение с измененным размером в какой-нибудь S3 bucket. Я предполагаю, что у вас уже есть aws-sdk gem и AWS::S3 экземпляр (документацию можно найти здесь).

def upload_to_s3 bucket_name, key, file
  s3 = AWS::S3.new(:access_key_id => 'YOUR_ACCESS_KEY_ID', :secret_access_key => 'YOUR_SECRET_ACCESS_KEY')
  bucket = s3.buckets[bucket_name]
  obj = bucket.objects[key]
  obj.write(File.open(file, 'rb'), :acl => :public_read)
end

Итак, здесь вы получаете объект AWS::S3 для связи с сервером S3, указываете имя своей корзины и желаемый ключ, и, по сути, загружаете изображение с возможностью сделать его видимым для всех в Интернете. Обратите внимание, что существует множество дополнительных параметров загрузки (включая шифрование файлов, права доступа, метаданные и многое другое).

person twonegatives    schedule 05.06.2015