【问题标题】:Sinatra: Compressing images from tempfile via MiniMagick before sending to APISinatra:在发送到 API 之前通过 MiniMagick 压缩临时文件中的图像
【发布时间】:2015-11-06 22:50:23
【问题描述】:

我正在尝试在使用此代码向 API 发送请求之前压缩图像:

require 'sinatra'
require 'unirest'
require 'mini_magick'
require 'json'

require 'open-uri'

get '/' do

    File.read('public/views/index.erb')

end

post '/' do
    Unirest.timeout(5)
    image = MiniMagick::Image.open(params['user_image'][:tempfile])
    image.resize "600x400" 
    response = Unirest.post 'https://search.craftar.net/v1/search',
            parameters: {
                token: "703eb042371c49f0",
                image: image                                        
            }

    body = response.body

    url = body['results'][0]['item']['url']

  redirect url

end

当它运行得到结果时,我得到以下错误:

ArgumentError at /
wrong number of arguments (1 for 0)

/usr/local/Cellar/ruby/2.2.3/lib/ruby/2.2.0/tempfile.rb in open
  def open
/usr/local/Cellar/ruby/2.2.3/lib/ruby/2.2.0/open-uri.rb in open
      name.open(*rest, &block)
/usr/local/lib/ruby/gems/2.2.0/gems/mini_magick-4.3.6/lib/mini_magick/image.rb in open
      Kernel.open(path_or_url, "rb") do |file|
server.rb in block in <main>
    image = MiniMagick::Image.open(params['user_image'][:tempfile])
/usr/local/lib/ruby/gems/2.2.0/gems/sinatra-1.4.6/lib/sinatra/base.rb in call
          proc { |a,p| unbound_method.bind(a).call }
/usr/local/lib/ruby/gems/2.2.0/gems/sinatra-1.4.6/lib/sinatra/base.rb in block in compile!
          proc { |a,p| unbound_method.bind(a).call }
/usr/local/lib/ruby/gems/2.2.0/gems/sinatra-1.4.6/lib/sinatra/base.rb in []
            route_eval { block[*args] }
/usr/local/lib/ruby/gems/2.2.0/gems/sinatra-1.4.6/lib/sinatra/base.rb in block (3 levels) in route!
            route_eval { block[*args] }
/usr/local/lib/ruby/gems/2.2.0/gems/sinatra-1.4.6/lib/sinatra/base.rb in route_eval
      throw :halt, yield
/usr/local/lib/ruby/gems/2.2.0/gems/sinatra-1.4.6/lib/sinatra/base.rb in block (2 levels) in route!
            route_eval { block[*args] }
/usr/local/lib/ruby/gems/2.2.0/gems/sinatra-1.4.6/lib/sinatra/base.rb in block in process_route
        block ? block[self, values] : yield(self, values)
/usr/local/lib/ruby/gems/2.2.0/gems/sinatra-1.4.6/lib/sinatra/base.rb in catch
      catch(:pass) do
/usr/local/lib/ruby/gems/2.2.0/gems/sinatra-1.4.6/lib/sinatra/base.rb in process_route
      catch(:pass) do
/usr/local/lib/ruby/gems/2.2.0/gems/sinatra-1.4.6/lib/sinatra/base.rb in block in route!
          returned_pass_block = process_route(pattern, keys, conditions) do |*args|
/usr/local/lib/ruby/gems/2.2.0/gems/sinatra-1.4.6/lib/sinatra/base.rb in each
        routes.each do |pattern, keys, conditions, block|
/usr/local/lib/ruby/gems/2.2.0/gems/sinatra-1.4.6/lib/sinatra/base.rb in route!
        routes.each do |pattern, keys, conditions, block|
/usr/local/lib/ruby/gems/2.2.0/gems/sinatra-1.4.6/lib/sinatra/base.rb in block in dispatch!
        route!
/usr/local/lib/ruby/gems/2.2.0/gems/sinatra-1.4.6/lib/sinatra/base.rb in block in invoke
      res = catch(:halt) { yield }
/usr/local/lib/ruby/gems/2.2.0/gems/sinatra-1.4.6/lib/sinatra/base.rb in catch
      res = catch(:halt) { yield }
/usr/local/lib/ruby/gems/2.2.0/gems/sinatra-1.4.6/lib/sinatra/base.rb in invoke
      res = catch(:halt) { yield }
/usr/local/lib/ruby/gems/2.2.0/gems/sinatra-1.4.6/lib/sinatra/base.rb in dispatch!
      invoke do
/usr/local/lib/ruby/gems/2.2.0/gems/sinatra-1.4.6/lib/sinatra/base.rb in block in call!
      invoke { dispatch! }
/usr/local/lib/ruby/gems/2.2.0/gems/sinatra-1.4.6/lib/sinatra/base.rb in block in invoke
      res = catch(:halt) { yield }
/usr/local/lib/ruby/gems/2.2.0/gems/sinatra-1.4.6/lib/sinatra/base.rb in catch
      res = catch(:halt) { yield }
/usr/local/lib/ruby/gems/2.2.0/gems/sinatra-1.4.6/lib/sinatra/base.rb in invoke
      res = catch(:halt) { yield }
/usr/local/lib/ruby/gems/2.2.0/gems/sinatra-1.4.6/lib/sinatra/base.rb in call!
      invoke { dispatch! }
/usr/local/lib/ruby/gems/2.2.0/gems/sinatra-1.4.6/lib/sinatra/base.rb in call
      dup.call!(env)
/usr/local/lib/ruby/gems/2.2.0/gems/rack-protection-1.5.3/lib/rack/protection/xss_header.rb in call
        status, headers, body = @app.call(env)
/usr/local/lib/ruby/gems/2.2.0/gems/rack-protection-1.5.3/lib/rack/protection/path_traversal.rb in call
        app.call env
/usr/local/lib/ruby/gems/2.2.0/gems/rack-protection-1.5.3/lib/rack/protection/json_csrf.rb in call
        status, headers, body = app.call(env)
/usr/local/lib/ruby/gems/2.2.0/gems/rack-protection-1.5.3/lib/rack/protection/base.rb in call
        result or app.call(env)
/usr/local/lib/ruby/gems/2.2.0/gems/rack-protection-1.5.3/lib/rack/protection/base.rb in call
        result or app.call(env)
/usr/local/lib/ruby/gems/2.2.0/gems/rack-protection-1.5.3/lib/rack/protection/frame_options.rb in call
        status, headers, body        = @app.call(env)
/usr/local/lib/ruby/gems/2.2.0/gems/rack-1.6.4/lib/rack/logger.rb in call
      @app.call(env)
/usr/local/lib/ruby/gems/2.2.0/gems/rack-1.6.4/lib/rack/commonlogger.rb in call
      status, header, body = @app.call(env)
/usr/local/lib/ruby/gems/2.2.0/gems/sinatra-1.4.6/lib/sinatra/base.rb in call
        call_without_check(env)
/usr/local/lib/ruby/gems/2.2.0/gems/sinatra-1.4.6/lib/sinatra/base.rb in call
      env['sinatra.commonlogger'] ? @app.call(env) : super
/usr/local/lib/ruby/gems/2.2.0/gems/rack-1.6.4/lib/rack/head.rb in call
    status, headers, body = @app.call(env)
/usr/local/lib/ruby/gems/2.2.0/gems/rack-1.6.4/lib/rack/methodoverride.rb in call
      @app.call(env)
/usr/local/lib/ruby/gems/2.2.0/gems/sinatra-1.4.6/lib/sinatra/show_exceptions.rb in call
      @app.call(env)
/usr/local/lib/ruby/gems/2.2.0/gems/sinatra-1.4.6/lib/sinatra/base.rb in call
      result, callback = app.call(env), env['async.callback']
/usr/local/lib/ruby/gems/2.2.0/gems/sinatra-1.4.6/lib/sinatra/base.rb in call
      @stack.call(env)
/usr/local/lib/ruby/gems/2.2.0/gems/sinatra-1.4.6/lib/sinatra/base.rb in block in call
        synchronize { prototype.call(env) }
/usr/local/lib/ruby/gems/2.2.0/gems/sinatra-1.4.6/lib/sinatra/base.rb in synchronize
          yield
/usr/local/lib/ruby/gems/2.2.0/gems/sinatra-1.4.6/lib/sinatra/base.rb in call
        synchronize { prototype.call(env) }
/usr/local/lib/ruby/gems/2.2.0/gems/rack-1.6.4/lib/rack/handler/webrick.rb in service
        status, headers, body = @app.call(env)
/usr/local/Cellar/ruby/2.2.3/lib/ruby/2.2.0/webrick/httpserver.rb in service
      si.service(req, res)
/usr/local/Cellar/ruby/2.2.3/lib/ruby/2.2.0/webrick/httpserver.rb in run
          server.service(req, res)
/usr/local/Cellar/ruby/2.2.3/lib/ruby/2.2.0/webrick/server.rb in block in start_thread
          block ? block.call(sock) : run(sock)

如果这不起作用,我如何提取用户上传的临时存储的图像并将其压缩到 API 需要的特定要求。

不胜感激!

【问题讨论】:

    标签: ruby api sinatra temporary-files minimagick


    【解决方案1】:

    image.rb 中的代码在临时文件上调用 Kernel.open。这从 open-uri.rb 调用 open,如果对象响应它,它将调用 open。临时文件响应打开,但不接受从 image.rb 到它的 'rb' 参数 open-uri 委托。

    我认为最简单的解决方案是将临时文件包装成一个普通文件并从那里开始:

    image = MiniMagick::Image.open(File.new(params[:user_image][:tempfile]))
    

    代码仍然失败,但我认为 MiniMagick 中的错误 (unrecognized option -to-ary') 无关。

    【讨论】:

      猜你喜欢
      • 2019-06-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-05-17
      • 2017-02-26
      相关资源
      最近更新 更多