Рендеринг изображения - PullRequest
24 голосов
/ 28 февраля 2011

Так что это должно быть довольно просто, но я не могу заставить его работать.

У меня есть метод контроллера, который находит изображение на основе запроса, а затем вывод кэшируется.Изображение может быть удаленным (flickr, google images и т. Д.) Или локальным.Независимо от источника, мне просто нужно взять содержимое файла изображения и передать его пользователю.По сути, прокси.Проход через удаленные изображения, кажется, работает нормально, но прохождение через локальные образы дает мне:

invalid byte sequence in UTF-8

Так вот что я получил.Я надеюсь, что кто-то может решить проблему или направить меня в лучшем направлении с помощью моего кода.

def image_proxy
  query = params[:query]
  image_url = get_image_url(query) # returns an absolute local file path or a URL

  response.headers['Cache-Control'] = "public, max-age=#{12.hours.to_i}"
  response.headers['Content-Type'] = 'image/jpeg'
  response.headers['Content-Disposition'] = 'inline'
  render :text => open(image_url).read
end

Удаленные файлы работают нормально, локальные файлы - нет.

Бонус для тех, ктоможет помочь решить эту другую проблему:

  1. Мне нужно установить правильный тип содержимого.URL удаленного изображения не говорят мне тип изображения, я просто получаю URL, а иногда URL не содержит расширения.Поэтому я выбрал jpeg, потому что он работает независимо от типа отправленного мне изображения.

Спасибо!

Ответы [ 2 ]

23 голосов
/ 28 февраля 2011

Попробуйте использовать render :text => open(image_url, "rb").read, который сообщает Ruby, что открываемый файл является двоичным, и не пытайтесь читать его как текст.

edit

Бонусный вопрос, вы можете прочитать первые несколько байтов и посмотреть, что они содержат.PNG всегда начинается с шестнадцатеричных значений байтов 89 50 4E 47 0D 0A 1A 0A (или десятичных значений 137 80 78 71 13 10 26 10).

В Википедии есть список магических чисел, используемых для идентификации файла , на который вы можете посмотреть.Просто создайте метод некоторого вида, который читает первые несколько байтов и сравнивает его с этим.

14 голосов
/ 28 февраля 2011

Какая версия Rails?Для Rails 3 вы должны взглянуть на потоковые методы , которые были добавлены.send_data будет правильным способом отправки двоичных данных.Если изображения локальные и ваш веб-сервер поддерживает это, вы можете использовать send_file, который не будет блокировать экземпляр rails, пока пользователь загружает изображение.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...