Skip to content

Commit

Permalink
add rmagick and mini_magick extractors renchap#1 tests are failing th…
Browse files Browse the repository at this point in the history
…ere seems to be some kind of additional header info on blurhash
  • Loading branch information
DanBrooker committed Mar 24, 2021
1 parent e8d187b commit 317a54e
Show file tree
Hide file tree
Showing 5 changed files with 114 additions and 57 deletions.
4 changes: 4 additions & 0 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,11 @@ GEM
down (5.1.1)
addressable (~> 2.5)
ffi (1.10.0)
mini_magick (4.11.0)
minitest (5.14.1)
public_suffix (4.0.5)
rake (13.0.1)
rmagick (4.2.2)
ruby-vips (2.0.17)
ffi (~> 1.9)
shrine (3.2.1)
Expand All @@ -29,8 +31,10 @@ PLATFORMS
ruby

DEPENDENCIES
mini_magick
minitest
rake
rmagick
ruby-vips
shrine-blurhash!

Expand Down
5 changes: 4 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -72,14 +72,17 @@ You can either specify the target size or `nil` to disable image resizing comple
Type: `symbol` or `lambda`

```ruby
plugin :blurhash, extractor: :ruby-vips
plugin :blurhash, extractor: :ruby_vips
```

Supported extractors:

| Name | Description |
| :----------- | :----------- |
| `:ruby_vips` | Uses the [ruby-vips] gem to extract pixels from File objects. If non-file IO object is given it will be temporarily downloaded to disk. |
| `:mini_magick` | Uses the [mini_magick] gem to extract pixels from File objects. If non-file IO object is given it will be temporarily downloaded to disk. |
| `:rmagick` | Uses the [rmagick] gem to extract pixels from File objects. If non-file IO object is given it will be temporarily downloaded to disk. |


You can also create your own custom pixel extractor, where you can reuse
any of the built-in analyzers. The analyzer is a lambda that accepts an IO
Expand Down
41 changes: 40 additions & 1 deletion lib/shrine/plugins/blurhash.rb
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ def blurhash
end

class PixelsExtractor
SUPPORTED_EXTRACTORS = [:ruby_vips].freeze
SUPPORTED_EXTRACTORS = %I[ruby_vips rmagick mini_magick].freeze

def initialize(tool, on_error: method(:fail))
unless SUPPORTED_EXTRACTORS.include?(tool)
Expand Down Expand Up @@ -135,6 +135,44 @@ def extract_with_ruby_vips(io, resize_to)
end
end

def extract_with_mini_magick(io, resize_to)
require "mini_magick"

begin
Shrine.with_file(io) do |file|
image = MiniMagick::Image.open(file.path)
image = image.resize("#{resize_to}x#{resize_to}") if resize_to

{
width: image.width,
height: image.height,
pixels: image.get_pixels.flatten,
}
end
rescue Vips::Error => e
on_error(e)
end
end

def extract_with_rmagick(io, resize_to)
require "rmagick"

begin
Shrine.with_file(io) do |file|
image = Magick::ImageList.new(file.path)
image.resize_to_fit!(resize_to, resize_to) if resize_to

{
width: image.columns,
height: image.rows,
pixels: image.export_pixels,
}
end
rescue Vips::Error => e
on_error(e)
end
end

def on_error(error)
@on_error.call(error)
nil
Expand All @@ -145,3 +183,4 @@ def on_error(error)
register_plugin(:blurhash, Blurhash)
end
end

2 changes: 2 additions & 0 deletions shrine-blurhash.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,6 @@ Gem::Specification.new do |gem|
gem.add_development_dependency "minitest"
gem.add_development_dependency "rake"
gem.add_development_dependency "ruby-vips"
gem.add_development_dependency "rmagick"
gem.add_development_dependency "mini_magick"
end
119 changes: 64 additions & 55 deletions test/blurhash_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,74 +7,83 @@
require "shrine/plugins/blurhash"

describe Shrine::Plugins::Blurhash do
before do
uploader_class = Class.new(Shrine)

uploader_class.storages[:cache] = Shrine::Storage::Memory.new
uploader_class.storages[:store] = Shrine::Storage::Memory.new
uploader_class.class_eval { plugin :blurhash, extractor: :ruby_vips }
%I(ruby_vips rmagick mini_magick).each do |extractor|

@shrine = uploader_class
@uploader = uploader_class.new(:store)
end
describe extractor do

def image
File.open("test/fixtures/image1.jpg", binmode: true)
end
before do
uploader_class = Class.new(Shrine)

it "computes the correct blurhash with default options" do
assert_equal "LLHLk~ja2xkBpdoKaeR*%fkCMxnj", @shrine.compute_blurhash(image)
end
uploader_class.storages[:cache] = Shrine::Storage::Memory.new
uploader_class.storages[:store] = Shrine::Storage::Memory.new
uploader_class.class_eval { plugin :blurhash, extractor: extractor }

it "allows to customize components" do
@shrine.plugin :blurhash, components: [2, 2]
assert_equal "AEHLk~jbpyoK", @shrine.compute_blurhash(image)
end
@shrine = uploader_class
@uploader = uploader_class.new(:store)
end

it "allows to customize resize dimensions" do
@shrine.plugin :blurhash, resize_to: 200
assert_equal "LLHV6naf2xk9lAoKaeR*%fkBMxn*", @shrine.compute_blurhash(image)
end
def image
File.open("test/fixtures/image1.jpg", binmode: true)
end

it "allows to not resize before computing blurhash" do
@shrine.plugin :blurhash, resize_to: nil
assert_equal "LLHV6nae2ek8lAo0aeR*%fkCMxn%", @shrine.compute_blurhash(image)
end
it "computes the correct blurhash with default options" do
assert_equal "LLHLk~ja2xkBpdoKaeR*%fkCMxnj", @shrine.compute_blurhash(image)
end

it "automatically computes the blurhash on upload" do
uploaded_file = @uploader.upload(image)
assert_equal "LLHLk~ja2xkBpdoKaeR*%fkCMxnj", uploaded_file.metadata["blurhash"]
end
it "allows to customize components" do
@shrine.plugin :blurhash, components: [2, 2]
assert_equal "AEHLk~jbpyoK", @shrine.compute_blurhash(image)
end

describe "blurhash method" do
it "is added to UploadedFile" do
uploaded_file = @uploader.upload(image)
assert_equal "LLHLk~ja2xkBpdoKaeR*%fkCMxnj", uploaded_file.metadata["blurhash"]
assert_equal "LLHLk~ja2xkBpdoKaeR*%fkCMxnj", uploaded_file.blurhash
end
it "allows to customize resize dimensions" do
@shrine.plugin :blurhash, resize_to: 200
assert_equal "LLHV6naf2xk9lAoKaeR*%fkBMxn*", @shrine.compute_blurhash(image)
end

it "allows a nil blurhash metadata" do
uploaded_file = @uploader.upload(image)
uploaded_file.metadata["blurhash"] = nil
assert_nil uploaded_file.blurhash
end
it "allows to not resize before computing blurhash" do
@shrine.plugin :blurhash, resize_to: nil
assert_equal "LLHV6nae2ek8lAo0aeR*%fkCMxn%", @shrine.compute_blurhash(image)
end

it "allows a missing blurhash metadata" do
uploaded_file = @uploader.upload(image)
uploaded_file.metadata.delete("blurhash")
assert_nil uploaded_file.blurhash
end
end
it "automatically computes the blurhash on upload" do
uploaded_file = @uploader.upload(image)
assert_equal "LLHLk~ja2xkBpdoKaeR*%fkCMxnj", uploaded_file.metadata["blurhash"]
end

describe "auto_extraction: false" do
it "does not add metadata" do
@shrine.plugin :blurhash, auto_extraction: false
uploaded_file = @uploader.upload(image)
assert_nil uploaded_file.metadata["blurhash"]
end
describe "blurhash method" do
it "is added to UploadedFile" do
uploaded_file = @uploader.upload(image)
assert_equal "LLHLk~ja2xkBpdoKaeR*%fkCMxnj", uploaded_file.metadata["blurhash"]
assert_equal "LLHLk~ja2xkBpdoKaeR*%fkCMxnj", uploaded_file.blurhash
end

it "allows a nil blurhash metadata" do
uploaded_file = @uploader.upload(image)
uploaded_file.metadata["blurhash"] = nil
assert_nil uploaded_file.blurhash
end

it "allows a missing blurhash metadata" do
uploaded_file = @uploader.upload(image)
uploaded_file.metadata.delete("blurhash")
assert_nil uploaded_file.blurhash
end
end

describe "auto_extraction: false" do
it "does not add metadata" do
@shrine.plugin :blurhash, auto_extraction: false
uploaded_file = @uploader.upload(image)
assert_nil uploaded_file.metadata["blurhash"]
end

it "provides method to compute blurhash from files" do
assert_equal "LLHLk~ja2xkBpdoKaeR*%fkCMxnj", @shrine.compute_blurhash(image)
end
end

it "provides method to compute blurhash from files" do
assert_equal "LLHLk~ja2xkBpdoKaeR*%fkCMxnj", @shrine.compute_blurhash(image)
end

end
end

0 comments on commit 317a54e

Please sign in to comment.