backframe 0.0.23 → 0.0.24
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/backframe/image_cache/image_cache.rb +37 -0
- data/lib/backframe/image_cache/lib/asset.rb +109 -0
- data/lib/backframe/image_cache/lib/cache.rb +67 -0
- data/lib/backframe/image_cache/lib/conversions.rb +132 -0
- data/lib/backframe/version.rb +1 -1
- data/lib/backframe.rb +1 -1
- metadata +5 -2
- data/lib/backframe/image_cache.rb +0 -129
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4fed772ee7c50ff2200092d5650f184207b62b98
|
4
|
+
data.tar.gz: bbfa73a46d0017893199aa11d6d4c9062ada92f9
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6911237facee346e2922ae792d8798f41a9a4090e86563979c77b4405bf6d40a20c6f81d2b4a7cc805e5e2d27af9a8699fea687b6f3c4c02d6669477073068b4
|
7
|
+
data.tar.gz: 7b68e177af76429287cc2c8d6c5f2322e87b1fe128d4aff76ead50ae154e2d802811c7101f3c09d19a4f2a7be99fabb10537f6b3926a8820ebec2df6b90bcff9
|
@@ -0,0 +1,37 @@
|
|
1
|
+
require 'backframe/image_cache/lib/asset'
|
2
|
+
require 'backframe/image_cache/lib/cache'
|
3
|
+
require 'backframe/image_cache/lib/conversions'
|
4
|
+
|
5
|
+
module Backframe
|
6
|
+
|
7
|
+
module ImageCache
|
8
|
+
|
9
|
+
class Base
|
10
|
+
|
11
|
+
def asset(filepath, conversions)
|
12
|
+
Backframe::ImageCache::Asset.new(filepath, conversions).process!
|
13
|
+
end
|
14
|
+
|
15
|
+
def cached(filepath, conversions)
|
16
|
+
Backframe::ImageCache::Cache.new(filepath, conversions).process!
|
17
|
+
end
|
18
|
+
|
19
|
+
def path(filepath, conversions)
|
20
|
+
string = Backframe::ImageCache::Conversions.new(conversions).to_s
|
21
|
+
filekey = filepath || 'default.jpg'
|
22
|
+
"/imagecache/#{string}/#{filekey}"
|
23
|
+
end
|
24
|
+
|
25
|
+
def url(filepath, conversions)
|
26
|
+
Rails.application.config.root_url + path(filepath, conversions)
|
27
|
+
end
|
28
|
+
|
29
|
+
def cdn_url(filepath, conversions)
|
30
|
+
Rails.application.config.cdn_url + path(filepath, conversions)
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
@@ -0,0 +1,109 @@
|
|
1
|
+
require 'stringio'
|
2
|
+
|
3
|
+
module Backframe
|
4
|
+
|
5
|
+
module ImageCache
|
6
|
+
|
7
|
+
class Asset
|
8
|
+
|
9
|
+
def initialize(filepath, conversions)
|
10
|
+
@filepath = filepath
|
11
|
+
@conversions = conversions
|
12
|
+
end
|
13
|
+
|
14
|
+
def process!
|
15
|
+
normalized = Backframe::ImageCache::Conversions.new(conversions)
|
16
|
+
if filepath.present?
|
17
|
+
fullpath = fullpath(filepath)
|
18
|
+
content_type = content_type(filepath)
|
19
|
+
data = download(fullpath)
|
20
|
+
oriented = auto_orient(data)
|
21
|
+
command = expand(normalized)
|
22
|
+
converted = execute(oriented, command)
|
23
|
+
else
|
24
|
+
converted = default_asset
|
25
|
+
end
|
26
|
+
compressed = compress(converted)
|
27
|
+
OpenStruct.new({ :success => true, :data => compressed, :content_type => content_type })
|
28
|
+
end
|
29
|
+
|
30
|
+
private
|
31
|
+
|
32
|
+
attr_reader :filepath, :conversions
|
33
|
+
|
34
|
+
def fullpath(path)
|
35
|
+
File.exist?("#{Rails.root}/public/#{path}") ? "#{Rails.root}/public/#{path}" : "#{Rails.application.config.cdn_url}/#{path}"
|
36
|
+
end
|
37
|
+
|
38
|
+
def download(path)
|
39
|
+
open(path).read
|
40
|
+
end
|
41
|
+
|
42
|
+
def auto_orient(data)
|
43
|
+
execute(data, '-auto-orient')
|
44
|
+
end
|
45
|
+
|
46
|
+
def content_type(filepath)
|
47
|
+
ext = extension(filepath)
|
48
|
+
"image/#{ext}"
|
49
|
+
end
|
50
|
+
|
51
|
+
def extension(filepath)
|
52
|
+
filepath.match(/.*\.([a-z]*)$/)[1]
|
53
|
+
end
|
54
|
+
|
55
|
+
def expand(conversions)
|
56
|
+
command = []
|
57
|
+
conversions.to_a.each do |conversion|
|
58
|
+
if conversion.key?(:fit)
|
59
|
+
width = conversion[:fit][:width] * conversion[:density]
|
60
|
+
height = conversion[:fit][:height] * conversion[:density]
|
61
|
+
command << "-resize \"#{width}x#{height}^\" -gravity center -crop '#{width}x#{height}+0+0'"
|
62
|
+
elsif conversion.key?(:height)
|
63
|
+
height = conversion[:height] * conversion[:density]
|
64
|
+
command << "-resize \"x#{height}\""
|
65
|
+
elsif conversion.key?(:width)
|
66
|
+
width = conversion[:width] * conversion[:density]
|
67
|
+
command << "-resize \"#{width}\""
|
68
|
+
elsif conversion.key?(:crop)
|
69
|
+
command << "-crop '#{parts[1]}x#{parts[2]}+#{parts[3]}+#{parts[4]}'"
|
70
|
+
end
|
71
|
+
end
|
72
|
+
command.join(' ')
|
73
|
+
end
|
74
|
+
|
75
|
+
def default_asset
|
76
|
+
path = "#{Rails.root}/tmp/canvas.png"
|
77
|
+
command = "convert 10x10 canvas:#EEEEEE #{conversions} '#{path}'"
|
78
|
+
Rails.logger.debug(command)
|
79
|
+
output = `#{command}`
|
80
|
+
IO.read(path)
|
81
|
+
end
|
82
|
+
|
83
|
+
#################### UTILITIES ####################
|
84
|
+
|
85
|
+
def tmpfile(data)
|
86
|
+
filename = SecureRandom.hex(32).to_s.upcase[0,8]
|
87
|
+
tmpfile = Tempfile.new(filename, :encoding => 'ascii-8bit')
|
88
|
+
tmpfile.write(data)
|
89
|
+
tmpfile.close if tmpfile && !tmpfile.closed?
|
90
|
+
tmpfile
|
91
|
+
end
|
92
|
+
|
93
|
+
def execute(data, command)
|
94
|
+
tmpfile = tmpfile(data)
|
95
|
+
command = "convert '#{tmpfile.path}' #{command} '#{tmpfile.path}'"
|
96
|
+
Rails.logger.debug(command)
|
97
|
+
output = `#{command}`
|
98
|
+
IO.read(tmpfile.path)
|
99
|
+
end
|
100
|
+
|
101
|
+
def compress(data)
|
102
|
+
ActiveSupport::Gzip.compress(data)
|
103
|
+
end
|
104
|
+
|
105
|
+
end
|
106
|
+
|
107
|
+
end
|
108
|
+
|
109
|
+
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
require 'stringio'
|
2
|
+
|
3
|
+
module Backframe
|
4
|
+
|
5
|
+
module ImageCache
|
6
|
+
|
7
|
+
class Cache
|
8
|
+
|
9
|
+
def initialize(filepath, conversions)
|
10
|
+
@filepath = filepath
|
11
|
+
@conversions = conversions
|
12
|
+
end
|
13
|
+
|
14
|
+
def process!
|
15
|
+
begin
|
16
|
+
test(filepath, conversions)
|
17
|
+
rescue
|
18
|
+
test(nil, conversions)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def test(filepath, conversions)
|
23
|
+
filekey = filepath || 'default.jpg'
|
24
|
+
normalized = Backframe::ImageCache::Conversions.new(conversions)
|
25
|
+
key = "imagecache/#{normalized.to_s}/#{filekey}"
|
26
|
+
if !redis.get(key)
|
27
|
+
asset = Backframe::ImageCache::Asset.new(filepath, normalized).process!
|
28
|
+
upload_to_s3(asset, key)
|
29
|
+
save_to_redis(key)
|
30
|
+
end
|
31
|
+
return OpenStruct.new(:success => true, :url => "#{Rails.application.config.cdn_url}/#{key}")
|
32
|
+
end
|
33
|
+
|
34
|
+
private
|
35
|
+
|
36
|
+
attr_reader :filepath, :conversions
|
37
|
+
|
38
|
+
def save_to_redis(key)
|
39
|
+
redis.set(key, true)
|
40
|
+
redis.expire(key, (7 * 24 * 60 * 60))
|
41
|
+
end
|
42
|
+
|
43
|
+
def upload_to_s3(asset, key)
|
44
|
+
headers = { :acl => 'public-read', :content_type => asset.content_type, :cache_control => 'max-age=315360000, no-transform, public', :content_encoding => 'gzip' }
|
45
|
+
bucket = s3.buckets[aws['bucket']]
|
46
|
+
bucket.objects.create(key, asset.data, headers)
|
47
|
+
end
|
48
|
+
|
49
|
+
def aws
|
50
|
+
@aws ||= YAML.load_file("#{Rails.root}/config/aws.yml")[Rails.env]
|
51
|
+
end
|
52
|
+
|
53
|
+
def s3
|
54
|
+
@s3 ||= AWS::S3.new(:access_key_id => aws['access_key_id'], :secret_access_key => aws['secret_access_key'])
|
55
|
+
end
|
56
|
+
|
57
|
+
def redis
|
58
|
+
return @redis if @redis.present?
|
59
|
+
config = YAML.load_file("#{Rails.root}/config/redis.yml")[Rails.env]
|
60
|
+
@redis = Redis.new(:host => config['host'], :port => config['port'], :db => 2)
|
61
|
+
end
|
62
|
+
|
63
|
+
end
|
64
|
+
|
65
|
+
end
|
66
|
+
|
67
|
+
end
|
@@ -0,0 +1,132 @@
|
|
1
|
+
require 'stringio'
|
2
|
+
|
3
|
+
module Backframe
|
4
|
+
|
5
|
+
module ImageCache
|
6
|
+
|
7
|
+
class Conversions
|
8
|
+
|
9
|
+
def initialize(conversions)
|
10
|
+
@conversions = normalize_conversions(conversions)
|
11
|
+
end
|
12
|
+
|
13
|
+
def to_s
|
14
|
+
output = []
|
15
|
+
conversions.each do |conversion|
|
16
|
+
if conversion.key?(:fit)
|
17
|
+
output << "F#{conversion[:fit][:width]}X#{conversion[:fit][:height]}D#{conversion[:density]}"
|
18
|
+
elsif conversion.key?(:width)
|
19
|
+
output << "W#{conversion[:width]}D#{conversion[:density]}"
|
20
|
+
elsif conversion.key?(:height)
|
21
|
+
output << "H#{conversion[:height]}D#{conversion[:density]}"
|
22
|
+
elsif conversion.key?(:crop)
|
23
|
+
output << "C#{conversion[:crop][:width]}X#{conversion[:crop][:height]}X#{conversion[:crop][:x]}X#{conversion[:crop][:y]}D#{conversion[:density]}"
|
24
|
+
end
|
25
|
+
end
|
26
|
+
output.join("-")
|
27
|
+
end
|
28
|
+
|
29
|
+
def to_a
|
30
|
+
conversions
|
31
|
+
end
|
32
|
+
|
33
|
+
private
|
34
|
+
|
35
|
+
attr_reader :conversions
|
36
|
+
|
37
|
+
#################### CONVERSION HANDLING ####################
|
38
|
+
|
39
|
+
def normalize_conversions(conversions)
|
40
|
+
if conversions.is_a?(String)
|
41
|
+
return normalize_conversion_string(conversions)
|
42
|
+
elsif conversions.is_a?(Symbol)
|
43
|
+
return normalize_conversion_string(conversions.to_s)
|
44
|
+
elsif conversions.is_a?(Hash)
|
45
|
+
return normalize_conversion_array([conversions])
|
46
|
+
elsif conversions.is_a?(Array)
|
47
|
+
return normalize_conversion_array(conversions)
|
48
|
+
elsif conversions.is_a?(Backframe::ImageCache::Conversions)
|
49
|
+
return conversions.to_a
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
def normalize_conversion_string(string)
|
54
|
+
output = []
|
55
|
+
string.upcase.split("-").each do |part|
|
56
|
+
if part == 'PREVIEW'
|
57
|
+
output << { :width => 250, :density => 2 }
|
58
|
+
elsif part == 'TINY'
|
59
|
+
output << { :fit => { :width => 20, :height => 20 }, :density => 2 }
|
60
|
+
elsif part == 'SMALL'
|
61
|
+
output << { :fit => { :width => 40, :height => 40 }, :density => 2 }
|
62
|
+
elsif part == 'MEDIUM'
|
63
|
+
output << { :fit => { :width => 250, :height => 250 }, :density => 2 }
|
64
|
+
elsif matches = part.match(/^F(\d*)X(\d*)(D(\d*))?$/)
|
65
|
+
density = (matches[3]) ? matches[4] : 1
|
66
|
+
output << { :fit => { :width => matches[1].to_i, :height => matches[2].to_i }, :density => density.to_i }
|
67
|
+
elsif matches = part.match(/^W(\d*)(D(\d*))?$/)
|
68
|
+
density = (matches[2]) ? matches[3] : 1
|
69
|
+
output << { :width => matches[1].to_i, :density => density.to_i }
|
70
|
+
elsif matches = part.match(/^H(\d*)(D(\d*))?$/)
|
71
|
+
density = (matches[2]) ? matches[3] : 1
|
72
|
+
output << { :height => matches[1].to_i, :density => density.to_i }
|
73
|
+
elsif matches = part.match(/^C(\d*)X(\d*)X(\d*)X(\d*)(D(\d*))?$/)
|
74
|
+
density = (matches[4]) ? matches[5] : 1
|
75
|
+
output << { :crop => { :width => matches[1].to_i, :height => matches[2].to_i, :x => matches[3].to_i, :y => matches[4].to_i, :density => density.to_i } }
|
76
|
+
end
|
77
|
+
end
|
78
|
+
output
|
79
|
+
end
|
80
|
+
|
81
|
+
def normalize_conversion_array(array)
|
82
|
+
output = []
|
83
|
+
array.each do |conversion|
|
84
|
+
density = conversion[:density].to_i || 1
|
85
|
+
if conversion.key?(:preview)
|
86
|
+
output << { :width => 250, :density => density }
|
87
|
+
elsif conversion.key?(:tiny)
|
88
|
+
output << { :fit => { :width => 20, :height => 20 }, :density => density }
|
89
|
+
elsif conversion.key?(:small)
|
90
|
+
output << { :fit => { :width => 40, :height => 40 }, :density => density }
|
91
|
+
elsif conversion.key?(:medium)
|
92
|
+
output << { :fit => { :width => 250, :height => 250 }, :density => density }
|
93
|
+
elsif conversion.key?(:fit)
|
94
|
+
fit = (conversion[:fit].is_a?(String)) ? parse_geometry_string(conversion[:fit]) : parse_geometry_array(conversion[:fit])
|
95
|
+
output << { :fit => fit, :density => density }
|
96
|
+
elsif conversion.key?(:width)
|
97
|
+
output << { :width => conversion[:width].to_i, :density => density }
|
98
|
+
elsif conversion.key?(:height)
|
99
|
+
output << { :height => conversion[:height].to_i, :density => density }
|
100
|
+
elsif conversion.key?(:crop)
|
101
|
+
crop = (conversion[:crop].is_a?(String)) ? parse_geometry(conversion[:crop]) : parse_geometry_array(conversion[:crop])
|
102
|
+
output << { :crop => crop, :density => density }
|
103
|
+
end
|
104
|
+
end
|
105
|
+
output
|
106
|
+
end
|
107
|
+
|
108
|
+
def parse_geometry_string(string)
|
109
|
+
string = string.upcase
|
110
|
+
if matches = string.match(/^(\d*)X(\d*)$/)
|
111
|
+
{ :width => matches[1].to_i, :height => matches[2].to_i }
|
112
|
+
elsif matches = string.match(/^(\d*)X(\d*)X(\d*)X(\d*)$/)
|
113
|
+
{ :width => matches[1].to_i, :height => matches[2].to_i, :x => matches[3].to_i, :y => matches[4].to_i }
|
114
|
+
elsif matches = string.match(/^(\d*)X(\d*)\+(\d*)\+(\d*)$/)
|
115
|
+
{ :width => matches[1].to_i, :height => matches[2].to_i, :x => matches[3].to_i, :y => matches[4].to_i }
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
def parse_geometry_array(array)
|
120
|
+
output = {}
|
121
|
+
output[:width] = array[:width].to_i if array.key?(:width)
|
122
|
+
output[:height] = array[:height].to_i if array.key?(:height)
|
123
|
+
output[:x] = array[:x].to_i if array.key?(:x)
|
124
|
+
output[:y] = array[:y].to_i if array.key?(:y)
|
125
|
+
output
|
126
|
+
end
|
127
|
+
|
128
|
+
end
|
129
|
+
|
130
|
+
end
|
131
|
+
|
132
|
+
end
|
data/lib/backframe/version.rb
CHANGED
data/lib/backframe.rb
CHANGED
@@ -22,7 +22,7 @@ require 'backframe/models/activity'
|
|
22
22
|
require 'backframe/models/activation'
|
23
23
|
require 'backframe/models/reset'
|
24
24
|
require 'backframe/serializers/activity_serializer'
|
25
|
-
require 'backframe/image_cache'
|
25
|
+
require 'backframe/image_cache/image_cache'
|
26
26
|
|
27
27
|
module Backframe
|
28
28
|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: backframe
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.24
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Greg Kops
|
@@ -113,7 +113,10 @@ files:
|
|
113
113
|
- lib/backframe/activerecord/default_values.rb
|
114
114
|
- lib/backframe/activerecord/filter_sort.rb
|
115
115
|
- lib/backframe/activerecord/migration.rb
|
116
|
-
- lib/backframe/image_cache.rb
|
116
|
+
- lib/backframe/image_cache/image_cache.rb
|
117
|
+
- lib/backframe/image_cache/lib/asset.rb
|
118
|
+
- lib/backframe/image_cache/lib/cache.rb
|
119
|
+
- lib/backframe/image_cache/lib/conversions.rb
|
117
120
|
- lib/backframe/mime.rb
|
118
121
|
- lib/backframe/models/activation.rb
|
119
122
|
- lib/backframe/models/activity.rb
|
@@ -1,129 +0,0 @@
|
|
1
|
-
require 'stringio'
|
2
|
-
|
3
|
-
module Backframe
|
4
|
-
|
5
|
-
class ImageCache
|
6
|
-
|
7
|
-
def initialize(filepath, conversions)
|
8
|
-
@filepath = filepath
|
9
|
-
@conversions = conversions
|
10
|
-
end
|
11
|
-
|
12
|
-
def process!
|
13
|
-
normalized = normalize_conversions(conversions)
|
14
|
-
fullpath = fullpath(filepath)
|
15
|
-
content_type = content_type(filepath)
|
16
|
-
data = download(fullpath)
|
17
|
-
oriented = auto_orient(data)
|
18
|
-
dimensions = dimensions(oriented)
|
19
|
-
command = expand(normalized)
|
20
|
-
converted = execute(oriented, command)
|
21
|
-
OpenStruct.new({ :success => true, :data => converted, :content_type => content_type })
|
22
|
-
end
|
23
|
-
|
24
|
-
private
|
25
|
-
|
26
|
-
attr_reader :filepath, :conversions
|
27
|
-
|
28
|
-
#################### CONVERSION HANDLING ####################
|
29
|
-
|
30
|
-
def normalize_conversions(string)
|
31
|
-
output = []
|
32
|
-
string.upcase.split("-").each do |part|
|
33
|
-
if part == 'PREVIEW'
|
34
|
-
output << { :width => 250, :density => 2 }
|
35
|
-
elsif part == 'TINY'
|
36
|
-
output << { :fit => { :width => 20, :height => 20 }, :density => 2 }
|
37
|
-
elsif part == 'SMALL'
|
38
|
-
output << { :fit => { :width => 40, :height => 40 }, :density => 2 }
|
39
|
-
elsif part == 'MEDIUM'
|
40
|
-
output << { :fit => { :width => 250, :height => 250 }, :density => 2 }
|
41
|
-
elsif matches = part.match(/^F(\d*)X(\d*)(D(\d*))?$/)
|
42
|
-
density = (matches[3]) ? matches[4].to_i : 1
|
43
|
-
output << { :fit => { :width => matches[1].to_i, :height => matches[2].to_i }, :density => density }
|
44
|
-
elsif matches = part.match(/^W(\d*)(D(\d*))?$/)
|
45
|
-
density = (matches[2]) ? matches[3].to_i : 1
|
46
|
-
output << { :width => matches[1].to_i, :density => density }
|
47
|
-
elsif matches = part.match(/^H(\d*)(D(\d*))?$/)
|
48
|
-
density = (matches[2]) ? matches[3].to_i : 1
|
49
|
-
output << { :height => matches[1].to_i, :density => density }
|
50
|
-
elsif matches = part.match(/^C(\d*)X(\d*)X(\d*)X(\d*)(D(\d*))?$/)
|
51
|
-
density = (matches[4]) ? matches[5].to_i : 1
|
52
|
-
output << { :crop => { :width => matches[1].to_i, :height => matches[2].to_i, :x => matches[3].to_i, :y => matches[4].to_i, :density => density } }
|
53
|
-
end
|
54
|
-
end
|
55
|
-
output
|
56
|
-
end
|
57
|
-
|
58
|
-
#################### ASSET HANDLING ####################
|
59
|
-
|
60
|
-
def fullpath(path)
|
61
|
-
File.exist?("#{Rails.root}/public/#{path}") ? "#{Rails.root}/public/#{path}" : "#{Rails.application.config.cdn_url}/#{path}"
|
62
|
-
end
|
63
|
-
|
64
|
-
def download(path)
|
65
|
-
open(path).read
|
66
|
-
end
|
67
|
-
|
68
|
-
def auto_orient(data)
|
69
|
-
execute(data, '-auto-orient')
|
70
|
-
end
|
71
|
-
|
72
|
-
def content_type(filepath)
|
73
|
-
ext = extension(filepath)
|
74
|
-
"image/#{ext}"
|
75
|
-
end
|
76
|
-
|
77
|
-
def extension(filepath)
|
78
|
-
filepath.match(/.*\.([a-z]*)$/)[1]
|
79
|
-
end
|
80
|
-
|
81
|
-
def dimensions(data)
|
82
|
-
tmpfile = tmpfile(data)
|
83
|
-
command = "identify -format '%wx%h,%[exif:orientation]' '#{tmpfile.path}'"
|
84
|
-
output = `#{command}`
|
85
|
-
matches = output.match(/^(\d*)x(\d*)/)
|
86
|
-
{ :width => matches[1], :height => matches[2] }
|
87
|
-
end
|
88
|
-
|
89
|
-
def expand(conversions)
|
90
|
-
command = []
|
91
|
-
conversions.each do |conversion|
|
92
|
-
if conversion.key?(:fit)
|
93
|
-
width = conversion[:fit][:width] * conversion[:density]
|
94
|
-
height = conversion[:fit][:height] * conversion[:density].to_i
|
95
|
-
command << "-resize \"#{width}x#{height}^\" -gravity center -crop '#{width}x#{height}+0+0'"
|
96
|
-
elsif conversion.key?(:height)
|
97
|
-
height = conversion[:height] * conversion[:density].to_i
|
98
|
-
command << "-resize \"x#{height}\""
|
99
|
-
elsif conversion.key?(:width)
|
100
|
-
width = conversion[:width] * conversion[:density].to_i
|
101
|
-
command << "-resize \"#{width}\""
|
102
|
-
elsif conversion.key?(:crop)
|
103
|
-
command << "-crop '#{parts[1]}x#{parts[2]}+#{parts[3]}+#{parts[4]}'"
|
104
|
-
end
|
105
|
-
end
|
106
|
-
command.join(' ')
|
107
|
-
end
|
108
|
-
|
109
|
-
#################### UTILITIES ####################
|
110
|
-
|
111
|
-
def tmpfile(data)
|
112
|
-
filename = SecureRandom.hex(32).to_s.upcase[0,8]
|
113
|
-
tmpfile = Tempfile.new(filename, :encoding => 'ascii-8bit')
|
114
|
-
tmpfile.write(data)
|
115
|
-
tmpfile.close if tmpfile && !tmpfile.closed?
|
116
|
-
tmpfile
|
117
|
-
end
|
118
|
-
|
119
|
-
def execute(data, command)
|
120
|
-
tmpfile = tmpfile(data)
|
121
|
-
command = "convert '#{tmpfile.path}' #{command} '#{tmpfile.path}'"
|
122
|
-
Rails.logger.debug(command)
|
123
|
-
output = `#{command}`
|
124
|
-
IO.read(tmpfile.path)
|
125
|
-
end
|
126
|
-
|
127
|
-
end
|
128
|
-
|
129
|
-
end
|