image_vise 0.2.1 → 0.2.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +8 -0
- data/.travis.yml +13 -0
- data/DEVELOPMENT.md +111 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +29 -0
- data/README.md +213 -0
- data/Rakefile +6 -0
- data/SECURITY.md +57 -0
- data/examples/config.ru +17 -0
- data/examples/custom_image_operator.rb +27 -0
- data/examples/error_handline_appsignal.rb +23 -0
- data/examples/error_handling_sentry.rb +25 -0
- data/image_vise.gemspec +43 -0
- data/lib/image_vise/fetchers/fetcher_file.rb +27 -0
- data/lib/image_vise/fetchers/fetcher_http.rb +42 -0
- data/lib/image_vise/file_response.rb +22 -0
- data/lib/image_vise/image_request.rb +70 -0
- data/lib/image_vise/operators/auto_orient.rb +10 -0
- data/lib/image_vise/operators/background_fill.rb +18 -0
- data/lib/image_vise/operators/crop.rb +32 -0
- data/lib/image_vise/operators/ellipse_stencil.rb +70 -0
- data/lib/image_vise/operators/fit_crop.rb +33 -0
- data/lib/image_vise/operators/force_jpg_out.rb +17 -0
- data/lib/image_vise/operators/geom.rb +16 -0
- data/lib/image_vise/operators/sRGB_v4_ICC_preference_displayclass.icc +0 -0
- data/lib/image_vise/operators/sharpen.rb +21 -0
- data/lib/image_vise/operators/srgb.rb +30 -0
- data/lib/image_vise/operators/strip_metadata.rb +10 -0
- data/lib/image_vise/pipeline.rb +64 -0
- data/lib/image_vise/render_engine.rb +298 -0
- data/lib/image_vise/version.rb +3 -0
- data/lib/image_vise/writers/auto_writer.rb +23 -0
- data/lib/image_vise/writers/jpeg_writer.rb +9 -0
- data/lib/image_vise.rb +177 -0
- data/spec/image_vise/auto_orient_spec.rb +10 -0
- data/spec/image_vise/background_fill_spec.rb +39 -0
- data/spec/image_vise/crop_spec.rb +20 -0
- data/spec/image_vise/ellipse_stencil_spec.rb +18 -0
- data/spec/image_vise/fetcher_file_spec.rb +48 -0
- data/spec/image_vise/fetcher_http_spec.rb +44 -0
- data/spec/image_vise/file_response_spec.rb +45 -0
- data/spec/image_vise/fit_crop_spec.rb +20 -0
- data/spec/image_vise/force_jpg_out_spec.rb +36 -0
- data/spec/image_vise/geom_spec.rb +33 -0
- data/spec/image_vise/image_request_spec.rb +62 -0
- data/spec/image_vise/pipeline_spec.rb +72 -0
- data/spec/image_vise/render_engine_spec.rb +336 -0
- data/spec/image_vise/sharpen_spec.rb +17 -0
- data/spec/image_vise/srgb_spec.rb +23 -0
- data/spec/image_vise/strip_metadata_spec.rb +14 -0
- data/spec/image_vise/writers/auto_writer_spec.rb +25 -0
- data/spec/image_vise/writers/jpeg_writer_spec.rb +32 -0
- data/spec/image_vise_spec.rb +110 -0
- data/spec/layers-with-blending.psd +0 -0
- data/spec/spec_helper.rb +112 -0
- data/spec/test_server.rb +61 -0
- data/spec/waterside_magic_hour.jpg +0 -0
- data/spec/waterside_magic_hour.psd +0 -0
- data/spec/waterside_magic_hour_adobergb.jpg +0 -0
- data/spec/waterside_magic_hour_gray.tif +0 -0
- data/spec/waterside_magic_hour_transp.png +0 -0
- metadata +63 -2
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe ImageVise::SRGB do
|
4
|
+
it 'applies the profile, creating a perceptible difference with the original' do
|
5
|
+
# This test will function only if you have RMagick with LCMS2 support
|
6
|
+
# built-in. If you do, the two images will look _very_ much like one
|
7
|
+
# another.
|
8
|
+
#
|
9
|
+
# If you don't, the images will look remarkably different
|
10
|
+
# (the AdobeRGB version has color values that match AdobeRGB
|
11
|
+
# primaries, and will render diffrently in pretty much any
|
12
|
+
# viewer).
|
13
|
+
image = Magick::Image.read(test_image_adobergb_path).first
|
14
|
+
subject.apply!(image)
|
15
|
+
image.strip!
|
16
|
+
examine_image(image, "from-adobergb-SHOULD-LOOK-IDENTICAL")
|
17
|
+
|
18
|
+
image = Magick::Image.read(test_image_path).first
|
19
|
+
subject.apply!(image)
|
20
|
+
image.strip!
|
21
|
+
examine_image(image, "from-srgb-SHOULD-LOOK-IDENTICAL")
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe ImageVise::StripMetadata do
|
4
|
+
it 'applies the strip! method to the image' do
|
5
|
+
image = Magick::Image.read(test_image_path).first
|
6
|
+
expect(image).to receive(:strip!).and_call_original
|
7
|
+
described_class.new.apply!(image)
|
8
|
+
end
|
9
|
+
|
10
|
+
it 'is registered with the operator registry' do
|
11
|
+
op = ImageVise.operator_from('strip_metadata')
|
12
|
+
expect(op).to eq(described_class)
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe ImageVise::AutoWriter do
|
4
|
+
it 'writes out a file with alpha as a PNG' do
|
5
|
+
sample_image = Magick::Image.read(test_image_png_transparency).first
|
6
|
+
tf = Tempfile.new 'outt'
|
7
|
+
subject.write_image!(sample_image, metadata=nil, tf.path)
|
8
|
+
|
9
|
+
tf.rewind
|
10
|
+
expect(tf.size).not_to be_zero
|
11
|
+
fmt = MagicBytes.read_and_detect(tf)
|
12
|
+
expect(fmt.ext).to eq('png')
|
13
|
+
end
|
14
|
+
|
15
|
+
it 'writes out a file without alpha as JPEG' do
|
16
|
+
sample_image = Magick::Image.read(test_image_path_tif).first
|
17
|
+
tf = Tempfile.new 'outt'
|
18
|
+
subject.write_image!(sample_image, metadata=nil, tf.path)
|
19
|
+
|
20
|
+
tf.rewind
|
21
|
+
expect(tf.size).not_to be_zero
|
22
|
+
fmt = MagicBytes.read_and_detect(tf)
|
23
|
+
expect(fmt.ext).to eq('jpg')
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe ImageVise::JPGWriter do
|
4
|
+
it 'writes out a file with alpha as a JPEG regardless' do
|
5
|
+
sample_image = Magick::Image.read(test_image_png_transparency).first
|
6
|
+
tf = Tempfile.new 'outt'
|
7
|
+
|
8
|
+
described_class.new(quality: 75).write_image!(sample_image, metadata=nil, tf.path)
|
9
|
+
|
10
|
+
tf.rewind
|
11
|
+
expect(tf.size).not_to be_zero
|
12
|
+
fmt = MagicBytes.read_and_detect(tf)
|
13
|
+
expect(fmt.ext).to eq('jpg')
|
14
|
+
end
|
15
|
+
|
16
|
+
it 'honors the JPEG compression quality setting, producing a smaller file with smaller quality' do
|
17
|
+
sample_image = Magick::Image.read(test_image_path_tif).first
|
18
|
+
|
19
|
+
tf_hi = Tempfile.new 'hi'
|
20
|
+
tf_lo = Tempfile.new 'lo'
|
21
|
+
|
22
|
+
described_class.new(quality: 50).write_image!(sample_image, metadata=nil, tf_hi.path)
|
23
|
+
described_class.new(quality: 10).write_image!(sample_image, metadata=nil, tf_lo.path)
|
24
|
+
|
25
|
+
tf_hi.rewind
|
26
|
+
tf_lo.rewind
|
27
|
+
|
28
|
+
expect(tf_hi.size).not_to be_zero
|
29
|
+
expect(tf_lo.size).not_to be_zero
|
30
|
+
expect(tf_lo.size).to be < tf_hi.size
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,110 @@
|
|
1
|
+
require_relative 'spec_helper'
|
2
|
+
require 'rack/test'
|
3
|
+
|
4
|
+
describe ImageVise do
|
5
|
+
include Rack::Test::Methods
|
6
|
+
|
7
|
+
def app
|
8
|
+
described_class.new
|
9
|
+
end
|
10
|
+
|
11
|
+
context 'ImageVise.allowed_hosts' do
|
12
|
+
it 'returns the allowed hosts and is empty by default' do
|
13
|
+
expect(described_class.allowed_hosts).to be_empty
|
14
|
+
end
|
15
|
+
|
16
|
+
it 'allows add_allowed_host! and reset_allowed_hosts!' do
|
17
|
+
described_class.add_allowed_host!('www.imageboard.im')
|
18
|
+
expect(described_class.allowed_hosts).to include('www.imageboard.im')
|
19
|
+
described_class.reset_allowed_hosts!
|
20
|
+
expect(described_class.allowed_hosts).not_to include('www.imageboard.im')
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
context 'ImageVise.secret_keys' do
|
25
|
+
it 'raises when asked for a key and no keys has been set' do
|
26
|
+
expect {
|
27
|
+
described_class.secret_keys
|
28
|
+
}.to raise_error("No keys set, add a key using `ImageVise.add_secret_key!(key)'")
|
29
|
+
end
|
30
|
+
|
31
|
+
it 'allows add_secret_key!(key) and reset_secret_keys!' do
|
32
|
+
described_class.add_secret_key!('l33t')
|
33
|
+
expect(described_class.secret_keys).to include('l33t')
|
34
|
+
described_class.reset_secret_keys!
|
35
|
+
expect {
|
36
|
+
expect(described_class.secret_keys)
|
37
|
+
}.to raise_error(/add a key using/)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
describe 'ImageVise.new.call' do
|
42
|
+
it 'instantiates a new app and performs call() on it' do
|
43
|
+
expect_any_instance_of(ImageVise::RenderEngine).to receive(:call).with(:mock_env) { :yes }
|
44
|
+
ImageVise.new.call(:mock_env)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
describe 'ImageVise.call' do
|
49
|
+
it 'instantiates a new app and performs call() on it' do
|
50
|
+
expect_any_instance_of(ImageVise::RenderEngine).to receive(:call).with(:mock_env) { :yes }
|
51
|
+
ImageVise.call(:mock_env)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
describe '.image_params' do
|
56
|
+
it 'generates a Hash with paremeters for processing the resized image' do
|
57
|
+
params = ImageVise.image_params(src_url: 'http://host.com/image.jpg', secret: 'l33t') do |pipe|
|
58
|
+
pipe.fit_crop width: 128, height: 256, gravity: 'c'
|
59
|
+
end
|
60
|
+
expect(params).to be_kind_of(Hash)
|
61
|
+
expect(params[:q]).not_to be_empty
|
62
|
+
expect(params[:sig]).not_to be_empty
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
describe 'methods dealing with fetchers' do
|
67
|
+
it 'returns the fetchers for the default schemes' do
|
68
|
+
http = ImageVise.fetcher_for('http')
|
69
|
+
expect(http).to respond_to(:fetch_uri_to_tempfile)
|
70
|
+
file = ImageVise.fetcher_for('file')
|
71
|
+
expect(http).to respond_to(:fetch_uri_to_tempfile)
|
72
|
+
|
73
|
+
expect {
|
74
|
+
ImageVise.fetcher_for('undernet')
|
75
|
+
}.to raise_error(/No fetcher registered/)
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
describe '.image_path' do
|
80
|
+
it 'returns the path to the image within the application' do
|
81
|
+
path = ImageVise.image_path(src_url: 'file://tmp/img.jpg', secret: 'a') do |p|
|
82
|
+
p.ellipse_stencil
|
83
|
+
end
|
84
|
+
expect(path).to start_with('/')
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
describe 'methods dealing with the operator list' do
|
89
|
+
it 'have the basic operators already set up' do
|
90
|
+
oplist = ImageVise.defined_operator_names
|
91
|
+
expect(oplist).to include('sharpen')
|
92
|
+
expect(oplist).to include('crop')
|
93
|
+
end
|
94
|
+
|
95
|
+
it 'allows an operator to be added and retrieved' do
|
96
|
+
class CustomOp; end
|
97
|
+
ImageVise.add_operator 'custom_op', CustomOp
|
98
|
+
expect(ImageVise.operator_from(:custom_op)).to eq(CustomOp)
|
99
|
+
expect(ImageVise.operator_name_for(CustomOp.new)).to eq('custom_op')
|
100
|
+
expect(ImageVise.defined_operator_names).to include('custom_op')
|
101
|
+
end
|
102
|
+
|
103
|
+
it 'raises an exception when an operator key is requested that does not exist' do
|
104
|
+
class UnknownOp; end
|
105
|
+
expect {
|
106
|
+
ImageVise.operator_name_for(UnknownOp.new)
|
107
|
+
}.to raise_error(/not registered using ImageVise/)
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
Binary file
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,112 @@
|
|
1
|
+
require 'bundler'
|
2
|
+
Bundler.require
|
3
|
+
|
4
|
+
require 'tmpdir'
|
5
|
+
require 'securerandom'
|
6
|
+
|
7
|
+
require 'addressable/uri'
|
8
|
+
require 'strenv'
|
9
|
+
require_relative 'test_server'
|
10
|
+
|
11
|
+
TEST_RENDERS_DIR = Dir.mktmpdir
|
12
|
+
|
13
|
+
module Examine
|
14
|
+
def examine_image(magick_image, name_tag = 'test-img')
|
15
|
+
# When doing TDD, waiting for stuff to open is a drag - allow
|
16
|
+
# it to be squelched using 2 envvars. Also viewing images
|
17
|
+
# makes no sense on CI unless we bother with artifacts.
|
18
|
+
# The first one is what Gitlab-CI sets for us.
|
19
|
+
return if ENV.key?("CI_BUILD_ID")
|
20
|
+
return if ENV.key?("SKIP_INTERACTIVE")
|
21
|
+
|
22
|
+
Dir.mkdir(TEST_RENDERS_DIR) unless File.exist?(TEST_RENDERS_DIR)
|
23
|
+
path = File.join(TEST_RENDERS_DIR, name_tag + '.png')
|
24
|
+
magick_image.format = 'png'
|
25
|
+
magick_image.write(path)
|
26
|
+
`open #{path}`
|
27
|
+
end
|
28
|
+
|
29
|
+
def examine_image_from_string(string)
|
30
|
+
# When doing TDD, waiting for stuff to open is a drag - allow
|
31
|
+
# it to be squelched using 2 envvars. Also viewing images
|
32
|
+
# makes no sense on CI unless we bother with artifacts.
|
33
|
+
# The first one is what Gitlab-CI sets for us.
|
34
|
+
return if ENV.key?("CI_BUILD_ID")
|
35
|
+
return if ENV.key?("SKIP_INTERACTIVE")
|
36
|
+
|
37
|
+
Dir.mkdir(TEST_RENDERS_DIR) unless File.exist?(TEST_RENDERS_DIR)
|
38
|
+
random_name = 'test-image-%s' % SecureRandom.hex(3)
|
39
|
+
path = File.join(TEST_RENDERS_DIR, random_name)
|
40
|
+
File.open(path, 'wb'){|f| f << string }
|
41
|
+
`open #{path}`
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
require 'simplecov'
|
46
|
+
SimpleCov.start do
|
47
|
+
add_filter "/spec/"
|
48
|
+
end
|
49
|
+
|
50
|
+
require_relative '../lib/image_vise'
|
51
|
+
|
52
|
+
RSpec.configure do | config |
|
53
|
+
config.order = 'random'
|
54
|
+
config.include Examine
|
55
|
+
config.before :suite do
|
56
|
+
TestServer.start(nil, ssl=false, port=9001)
|
57
|
+
end
|
58
|
+
|
59
|
+
config.after :each do
|
60
|
+
ImageVise.reset_allowed_hosts!
|
61
|
+
ImageVise.reset_secret_keys!
|
62
|
+
end
|
63
|
+
|
64
|
+
config.after :suite do
|
65
|
+
sleep 2
|
66
|
+
FileUtils.rm_rf(TEST_RENDERS_DIR)
|
67
|
+
end
|
68
|
+
|
69
|
+
def test_image_path
|
70
|
+
File.expand_path(__dir__ + '/waterside_magic_hour.jpg')
|
71
|
+
end
|
72
|
+
|
73
|
+
def test_image_path_psd
|
74
|
+
File.expand_path(__dir__ + '/waterside_magic_hour.psd')
|
75
|
+
end
|
76
|
+
|
77
|
+
def test_image_path_tif
|
78
|
+
File.expand_path(__dir__ + '/waterside_magic_hour_gray.tif')
|
79
|
+
end
|
80
|
+
|
81
|
+
def test_image_adobergb_path
|
82
|
+
File.expand_path(__dir__ + '/waterside_magic_hour_adobergb.jpg')
|
83
|
+
end
|
84
|
+
|
85
|
+
def test_image_png_transparency
|
86
|
+
File.expand_path(__dir__ + '/waterside_magic_hour_transp.png')
|
87
|
+
end
|
88
|
+
|
89
|
+
def public_url
|
90
|
+
'http://localhost:9001/waterside_magic_hour.jpg'
|
91
|
+
end
|
92
|
+
|
93
|
+
def public_url_psd
|
94
|
+
'http://localhost:9001/waterside_magic_hour.psd'
|
95
|
+
end
|
96
|
+
|
97
|
+
def public_url_psd_multilayer
|
98
|
+
'http://localhost:9001/layers-with-blending.psd'
|
99
|
+
end
|
100
|
+
|
101
|
+
def public_url_tif
|
102
|
+
'http://localhost:9001/waterside_magic_hour_gray.tif'
|
103
|
+
end
|
104
|
+
|
105
|
+
def public_url_png_transparency
|
106
|
+
'http://localhost:9001/waterside_magic_hour_transp.png'
|
107
|
+
end
|
108
|
+
|
109
|
+
config.around :each do |e|
|
110
|
+
STRICT_ENV.with_protected_env { e.run }
|
111
|
+
end
|
112
|
+
end
|
data/spec/test_server.rb
ADDED
@@ -0,0 +1,61 @@
|
|
1
|
+
require 'webrick'
|
2
|
+
include WEBrick
|
3
|
+
|
4
|
+
class ForbiddenServlet < HTTPServlet::AbstractServlet
|
5
|
+
def do_GET(req,res)
|
6
|
+
res['Content-Type'] = "text/plain"
|
7
|
+
res.status = 403
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
class TestServer
|
12
|
+
def self.start( log_file = nil, ssl = false, port = 9001 )
|
13
|
+
new(log_file, ssl, port).start
|
14
|
+
end
|
15
|
+
|
16
|
+
def initialize( log_file = nil, ssl = false, port = 9001 )
|
17
|
+
log_file ||= StringIO.new
|
18
|
+
log = WEBrick::Log.new(log_file)
|
19
|
+
|
20
|
+
options = {
|
21
|
+
:Port => port,
|
22
|
+
:Logger => log,
|
23
|
+
:AccessLog => [
|
24
|
+
[ log, WEBrick::AccessLog::COMMON_LOG_FORMAT ],
|
25
|
+
[ log, WEBrick::AccessLog::REFERER_LOG_FORMAT ]
|
26
|
+
],
|
27
|
+
:DocumentRoot => File.expand_path(__dir__),
|
28
|
+
}
|
29
|
+
|
30
|
+
if ssl
|
31
|
+
options[:SSLEnable] = true
|
32
|
+
options[:SSLCertificate] = OpenSSL::X509::Certificate.new(File.open("spec/certs/cacert.pem").read)
|
33
|
+
options[:SSLPrivateKey] = OpenSSL::PKey::RSA.new(File.open("spec/certs/privkey.pem").read)
|
34
|
+
options[:SSLCertName] = [ ["CN", WEBrick::Utils::getservername ] ]
|
35
|
+
end
|
36
|
+
|
37
|
+
@server = WEBrick::HTTPServer.new(options)
|
38
|
+
@server.mount("/forbidden", ForbiddenServlet)
|
39
|
+
end
|
40
|
+
|
41
|
+
def start
|
42
|
+
trap('INT') {
|
43
|
+
begin
|
44
|
+
@server.shutdown unless @server.nil?
|
45
|
+
rescue Object => e
|
46
|
+
$stderr.puts "Error #{__FILE__}:#{__LINE__}\n#{e.message}"
|
47
|
+
end
|
48
|
+
}
|
49
|
+
|
50
|
+
@thread = Thread.new { @server.start }
|
51
|
+
Thread.pass
|
52
|
+
self
|
53
|
+
end
|
54
|
+
|
55
|
+
def join
|
56
|
+
if defined? @thread and @thread
|
57
|
+
@thread.join
|
58
|
+
end
|
59
|
+
self
|
60
|
+
end
|
61
|
+
end
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: image_vise
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Julik Tarkhanov
|
@@ -184,7 +184,68 @@ email:
|
|
184
184
|
executables: []
|
185
185
|
extensions: []
|
186
186
|
extra_rdoc_files: []
|
187
|
-
files:
|
187
|
+
files:
|
188
|
+
- ".gitignore"
|
189
|
+
- ".travis.yml"
|
190
|
+
- DEVELOPMENT.md
|
191
|
+
- Gemfile
|
192
|
+
- LICENSE.txt
|
193
|
+
- README.md
|
194
|
+
- Rakefile
|
195
|
+
- SECURITY.md
|
196
|
+
- examples/config.ru
|
197
|
+
- examples/custom_image_operator.rb
|
198
|
+
- examples/error_handline_appsignal.rb
|
199
|
+
- examples/error_handling_sentry.rb
|
200
|
+
- image_vise.gemspec
|
201
|
+
- lib/image_vise.rb
|
202
|
+
- lib/image_vise/fetchers/fetcher_file.rb
|
203
|
+
- lib/image_vise/fetchers/fetcher_http.rb
|
204
|
+
- lib/image_vise/file_response.rb
|
205
|
+
- lib/image_vise/image_request.rb
|
206
|
+
- lib/image_vise/operators/auto_orient.rb
|
207
|
+
- lib/image_vise/operators/background_fill.rb
|
208
|
+
- lib/image_vise/operators/crop.rb
|
209
|
+
- lib/image_vise/operators/ellipse_stencil.rb
|
210
|
+
- lib/image_vise/operators/fit_crop.rb
|
211
|
+
- lib/image_vise/operators/force_jpg_out.rb
|
212
|
+
- lib/image_vise/operators/geom.rb
|
213
|
+
- lib/image_vise/operators/sRGB_v4_ICC_preference_displayclass.icc
|
214
|
+
- lib/image_vise/operators/sharpen.rb
|
215
|
+
- lib/image_vise/operators/srgb.rb
|
216
|
+
- lib/image_vise/operators/strip_metadata.rb
|
217
|
+
- lib/image_vise/pipeline.rb
|
218
|
+
- lib/image_vise/render_engine.rb
|
219
|
+
- lib/image_vise/version.rb
|
220
|
+
- lib/image_vise/writers/auto_writer.rb
|
221
|
+
- lib/image_vise/writers/jpeg_writer.rb
|
222
|
+
- spec/image_vise/auto_orient_spec.rb
|
223
|
+
- spec/image_vise/background_fill_spec.rb
|
224
|
+
- spec/image_vise/crop_spec.rb
|
225
|
+
- spec/image_vise/ellipse_stencil_spec.rb
|
226
|
+
- spec/image_vise/fetcher_file_spec.rb
|
227
|
+
- spec/image_vise/fetcher_http_spec.rb
|
228
|
+
- spec/image_vise/file_response_spec.rb
|
229
|
+
- spec/image_vise/fit_crop_spec.rb
|
230
|
+
- spec/image_vise/force_jpg_out_spec.rb
|
231
|
+
- spec/image_vise/geom_spec.rb
|
232
|
+
- spec/image_vise/image_request_spec.rb
|
233
|
+
- spec/image_vise/pipeline_spec.rb
|
234
|
+
- spec/image_vise/render_engine_spec.rb
|
235
|
+
- spec/image_vise/sharpen_spec.rb
|
236
|
+
- spec/image_vise/srgb_spec.rb
|
237
|
+
- spec/image_vise/strip_metadata_spec.rb
|
238
|
+
- spec/image_vise/writers/auto_writer_spec.rb
|
239
|
+
- spec/image_vise/writers/jpeg_writer_spec.rb
|
240
|
+
- spec/image_vise_spec.rb
|
241
|
+
- spec/layers-with-blending.psd
|
242
|
+
- spec/spec_helper.rb
|
243
|
+
- spec/test_server.rb
|
244
|
+
- spec/waterside_magic_hour.jpg
|
245
|
+
- spec/waterside_magic_hour.psd
|
246
|
+
- spec/waterside_magic_hour_adobergb.jpg
|
247
|
+
- spec/waterside_magic_hour_gray.tif
|
248
|
+
- spec/waterside_magic_hour_transp.png
|
188
249
|
homepage: https://github.com/WeTransfer/image_vise
|
189
250
|
licenses:
|
190
251
|
- MIT
|