4

画像をRedisに保存しようとしています。これは、後でResqueタスクで取得して画像サーバーにアップロードされます。

ImageHandleクラスは、画像を取得します。今のところ、私はRedisに画像を出し入れすることだけに関心があります。

class ImageHandle < ActiveRecord::Base
  attr_accessible :uploaded, :image
  after_save :save_image

  def image_data
    $redis.get(redis_key)
  end

  def image=(value)
    @image = value
  end

  private

  def redis_key
    @redis_key ||= "image_handle:#{id}:image"
  end

  def save_image
    $redis.set(redis_key, @image.read)
  end
end

初期化子で$redisが設定されている場合:

$redis = Redis.new

そしてこれは私のテストファイルです:

require 'test_helper'

class ImageHandleTest < ActiveSupport::TestCase
  include ActionDispatch::TestProcess

  setup do
    clear_redis
  end

  test 'saves an image' do    
    image = fixture_file_upload('screaming-eagle.jpg', 'image/jpg')
    # You can only read from a file fixture once
    same_image = fixture_file_upload('screaming-eagle.jpg', 'image/jpg')

    image_handle = ImageHandle.create(image: image)

    expected = same_image.read
    actual   = image_handle.image_data

    puts "length of expected: #{expected.length}"
    puts "length of actual:   #{actual.length}"

    assert_equal expected, actual
  end
end

そして結果は次のとおりです。

length of expected: 81500
length of actual:   78524
F 

Finished tests in 0.270385s, 3.6984 tests/s, 3.6984 assertions/s.

  1) Failure:
test_saves_an_image:23

何が起こっているのかわかりません。

設定( "b" * 81500)してから取得しようとすると、予想される81500の長さで元に戻りました。

あなたが私に与えることができるどんな助けにも感謝します。

4

2 に答える 2

3

redis-rbは、文字列をEncoding::default_external、通常はUTF-8で定義されているデフォルトの外部エンコーディングに変換します。https://github.com/redis/redis-rb/commit/61fa1f884a643cd7dea8e0e56498860594058a39を参照してください

バイナリデータを保存する前にBase64としてエンコードし、取得後にBase64からデコードできます。

class ImageHandle < ActiveRecord::Base
  attr_accessible :uploaded, :image
  after_save :save_image

  def image_data
    Base64.decode $redis.get(redis_key)
  end

  def image=(value)
    @image = value
  end

  private

  def redis_key
    @redis_key ||= "image_handle:#{id}:image"
  end

  def save_image
    $redis.set redis_key, Base64.encode(@image.read)
  end
end
于 2013-03-08T18:19:21.817 に答える
0

データを失うことなく、文字列をASCII-8BITに変換できます。このメソッドを更新します。

def image_data
  $redis.get(redis_key).force_encoding(Encoding::ASCII_8BIT)
end

Base64よりも高速でシンプルです。

于 2013-10-11T16:25:30.743 に答える