attachment_zen 1.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,47 @@
1
+ module RedArtisan
2
+ module CoreImage
3
+ module Filters
4
+ module Scale
5
+
6
+ def resize(width, height)
7
+ create_core_image_context(width, height)
8
+
9
+ scale_x, scale_y = scale(width, height)
10
+
11
+ @original.affine_clamp :inputTransform => OSX::NSAffineTransform.transform do |clamped|
12
+ clamped.lanczos_scale_transform :inputScale => scale_x > scale_y ? scale_x : scale_y, :inputAspectRatio => scale_x / scale_y do |scaled|
13
+ scaled.crop :inputRectangle => vector(0, 0, width, height) do |cropped|
14
+ @target = cropped
15
+ end
16
+ end
17
+ end
18
+ end
19
+
20
+ def thumbnail(width, height)
21
+ create_core_image_context(width, height)
22
+
23
+ transform = OSX::NSAffineTransform.transform
24
+ transform.scaleXBy_yBy *scale(width, height)
25
+
26
+ @original.affine_transform :inputTransform => transform do |scaled|
27
+ @target = scaled
28
+ end
29
+ end
30
+
31
+ def fit(size)
32
+ original_size = @original.extent.size
33
+ scale = size.to_f / (original_size.width > original_size.height ? original_size.width : original_size.height)
34
+ resize (original_size.width * scale).to_i, (original_size.height * scale).to_i
35
+ end
36
+
37
+ private
38
+
39
+ def scale(width, height)
40
+ original_size = @original.extent.size
41
+ return width.to_f / original_size.width.to_f, height.to_f / original_size.height.to_f
42
+ end
43
+
44
+ end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,32 @@
1
+ module RedArtisan
2
+ module CoreImage
3
+ module Filters
4
+ module Watermark
5
+
6
+ def watermark(watermark_image, tile = false, strength = 0.1)
7
+ create_core_image_context(@original.extent.size.width, @original.extent.size.height)
8
+
9
+ if watermark_image.respond_to? :to_str
10
+ watermark_image = OSX::CIImage.from(watermark_image.to_str)
11
+ end
12
+
13
+ if tile
14
+ tile_transform = OSX::NSAffineTransform.transform
15
+ tile_transform.scaleXBy_yBy 1.0, 1.0
16
+
17
+ watermark_image.affine_tile :inputTransform => tile_transform do |tiled|
18
+ tiled.crop :inputRectangle => vector(0, 0, @original.extent.size.width, @original.extent.size.height) do |tiled_watermark|
19
+ watermark_image = tiled_watermark
20
+ end
21
+ end
22
+ end
23
+
24
+ @original.dissolve_transition :inputTargetImage => watermark_image, :inputTime => strength do |watermarked|
25
+ @target = watermarked
26
+ end
27
+ end
28
+
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,122 @@
1
+ require 'osx/cocoa'
2
+ require 'active_support'
3
+
4
+ require 'red_artisan/core_image/filters/scale'
5
+ require 'red_artisan/core_image/filters/color'
6
+ require 'red_artisan/core_image/filters/watermark'
7
+ require 'red_artisan/core_image/filters/quality'
8
+ require 'red_artisan/core_image/filters/perspective'
9
+ require 'red_artisan/core_image/filters/effects'
10
+
11
+ # Generic image processor for scaling images based on CoreImage via RubyCocoa.
12
+ #
13
+ # Example usage:
14
+ #
15
+ # p = Processor.new OSX::CIImage.from(path_to_image)
16
+ # p.resize(640, 480)
17
+ # p.render do |result|
18
+ # result.save('resized.jpg', OSX::NSJPEGFileType)
19
+ # end
20
+ #
21
+ # This will resize the image to the given dimensions exactly, if you'd like to ensure that aspect ratio is preserved:
22
+ #
23
+ # p = Processor.new OSX::CIImage.from(path_to_image)
24
+ # p.fit(640)
25
+ # p.render do |result|
26
+ # result.save('resized.jpg', OSX::NSJPEGFileType)
27
+ # end
28
+ #
29
+ # fit(size) will attempt its best to resize the image so that the longest width/height (depending on image orientation) will match
30
+ # the given size. The second axis will be calculated automatically based on the aspect ratio.
31
+ #
32
+ # Scaling is performed by first clamping the image so that its external bounds become infinite, this helps when scaling so that any
33
+ # rounding discrepencies in dimensions don't affect the resultant image. We then perform a Lanczos transform on the image which scales
34
+ # it to the target size. We then crop the image to the traget dimensions.
35
+ #
36
+ # If you are generating smaller images such as thumbnails where high quality rendering isn't as important, an additional method is
37
+ # available:
38
+ #
39
+ # p = Processor.new OSX::CIImage.from(path_to_image)
40
+ # p.thumbnail(100, 100)
41
+ # p.render do |result|
42
+ # result.save('resized.jpg', OSX::NSJPEGFileType)
43
+ # end
44
+ #
45
+ # This will perform a straight affine transform and scale the X and Y boundaries to the requested size. Generally, this will be faster
46
+ # than a lanczos scale transform, but with a scaling quality trade.
47
+ #
48
+ # More than welcome to intregrate any patches, improvements - feel free to mail me with ideas.
49
+ #
50
+ # Thanks to
51
+ # * Satoshi Nakagawa for working out that OCObjWrapper needs inclusion when aliasing method_missing on existing OSX::* classes.
52
+ # * Vasantha Crabb for general help and inspiration with Cocoa
53
+ # * Ben Schwarz for example image data and collaboration during performance testing
54
+ #
55
+ # Copyright (c) Marcus Crafter <crafterm@redartisan.com> released under the MIT license
56
+ #
57
+ module RedArtisan
58
+ module CoreImage
59
+ class Processor
60
+
61
+ def initialize(original)
62
+ if original.respond_to? :to_str
63
+ @original = OSX::CIImage.from(original.to_str)
64
+ else
65
+ @original = original
66
+ end
67
+ end
68
+
69
+ def render(&block)
70
+ raise "unprocessed image: #{@original}" unless @target
71
+ block.call @target
72
+ end
73
+
74
+ include Filters::Scale, Filters::Color, Filters::Watermark, Filters::Quality, Filters::Perspective, Filters::Effects
75
+
76
+ private
77
+
78
+ def create_core_image_context(width, height)
79
+ output = OSX::NSBitmapImageRep.alloc.initWithBitmapDataPlanes_pixelsWide_pixelsHigh_bitsPerSample_samplesPerPixel_hasAlpha_isPlanar_colorSpaceName_bytesPerRow_bitsPerPixel(nil, width, height, 8, 4, true, false, OSX::NSDeviceRGBColorSpace, 0, 0)
80
+ context = OSX::NSGraphicsContext.graphicsContextWithBitmapImageRep(output)
81
+ OSX::NSGraphicsContext.setCurrentContext(context)
82
+ @ci_context = context.CIContext
83
+ end
84
+
85
+ def vector(x, y, w, h)
86
+ OSX::CIVector.vectorWithX_Y_Z_W(x, y, w, h)
87
+ end
88
+ end
89
+ end
90
+ end
91
+
92
+ module OSX
93
+ class CIImage
94
+ include OCObjWrapper
95
+
96
+ def method_missing_with_filter_processing(sym, *args, &block)
97
+ f = OSX::CIFilter.filterWithName("CI#{sym.to_s.camelize}")
98
+ return method_missing_without_filter_processing(sym, *args, &block) unless f
99
+
100
+ f.setDefaults if f.respond_to? :setDefaults
101
+ f.setValue_forKey(self, 'inputImage')
102
+ options = args.last.is_a?(Hash) ? args.last : {}
103
+ options.each { |k, v| f.setValue_forKey(v, k.to_s) }
104
+
105
+ block.call f.valueForKey('outputImage')
106
+ end
107
+
108
+ alias_method_chain :method_missing, :filter_processing
109
+
110
+ def save(target, format = OSX::NSJPEGFileType, properties = nil)
111
+ bitmapRep = OSX::NSBitmapImageRep.alloc.initWithCIImage(self)
112
+ blob = bitmapRep.representationUsingType_properties(format, properties)
113
+ blob.writeToFile_atomically(target, false)
114
+ end
115
+
116
+ def self.from(filepath)
117
+ raise Errno::ENOENT, "No such file or directory - #{filepath}" unless File.exists?(filepath)
118
+ OSX::CIImage.imageWithContentsOfURL(OSX::NSURL.fileURLWithPath(filepath))
119
+ end
120
+ end
121
+ end
122
+
metadata ADDED
@@ -0,0 +1,255 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: attachment_zen
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Technoweenie
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-02-18 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: activerecord
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: 3.2.21
20
+ - - "<"
21
+ - !ruby/object:Gem::Version
22
+ version: 4.3.0
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ requirements:
27
+ - - ">="
28
+ - !ruby/object:Gem::Version
29
+ version: 3.2.21
30
+ - - "<"
31
+ - !ruby/object:Gem::Version
32
+ version: 4.3.0
33
+ - !ruby/object:Gem::Dependency
34
+ name: actionpack
35
+ requirement: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - ">="
38
+ - !ruby/object:Gem::Version
39
+ version: '0'
40
+ type: :development
41
+ prerelease: false
42
+ version_requirements: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - ">="
45
+ - !ruby/object:Gem::Version
46
+ version: '0'
47
+ - !ruby/object:Gem::Dependency
48
+ name: rake
49
+ requirement: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - ">="
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ type: :development
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - ">="
59
+ - !ruby/object:Gem::Version
60
+ version: '0'
61
+ - !ruby/object:Gem::Dependency
62
+ name: bump
63
+ requirement: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - ">="
66
+ - !ruby/object:Gem::Version
67
+ version: '0'
68
+ type: :development
69
+ prerelease: false
70
+ version_requirements: !ruby/object:Gem::Requirement
71
+ requirements:
72
+ - - ">="
73
+ - !ruby/object:Gem::Version
74
+ version: '0'
75
+ - !ruby/object:Gem::Dependency
76
+ name: wwtd
77
+ requirement: !ruby/object:Gem::Requirement
78
+ requirements:
79
+ - - ">="
80
+ - !ruby/object:Gem::Version
81
+ version: '0'
82
+ type: :development
83
+ prerelease: false
84
+ version_requirements: !ruby/object:Gem::Requirement
85
+ requirements:
86
+ - - ">="
87
+ - !ruby/object:Gem::Version
88
+ version: '0'
89
+ - !ruby/object:Gem::Dependency
90
+ name: mocha
91
+ requirement: !ruby/object:Gem::Requirement
92
+ requirements:
93
+ - - ">="
94
+ - !ruby/object:Gem::Version
95
+ version: '0'
96
+ type: :development
97
+ prerelease: false
98
+ version_requirements: !ruby/object:Gem::Requirement
99
+ requirements:
100
+ - - ">="
101
+ - !ruby/object:Gem::Version
102
+ version: '0'
103
+ - !ruby/object:Gem::Dependency
104
+ name: mysql
105
+ requirement: !ruby/object:Gem::Requirement
106
+ requirements:
107
+ - - ">="
108
+ - !ruby/object:Gem::Version
109
+ version: '0'
110
+ type: :development
111
+ prerelease: false
112
+ version_requirements: !ruby/object:Gem::Requirement
113
+ requirements:
114
+ - - ">="
115
+ - !ruby/object:Gem::Version
116
+ version: '0'
117
+ - !ruby/object:Gem::Dependency
118
+ name: mini_magick
119
+ requirement: !ruby/object:Gem::Requirement
120
+ requirements:
121
+ - - "~>"
122
+ - !ruby/object:Gem::Version
123
+ version: 3.6.0
124
+ type: :development
125
+ prerelease: false
126
+ version_requirements: !ruby/object:Gem::Requirement
127
+ requirements:
128
+ - - "~>"
129
+ - !ruby/object:Gem::Version
130
+ version: 3.6.0
131
+ - !ruby/object:Gem::Dependency
132
+ name: minitest
133
+ requirement: !ruby/object:Gem::Requirement
134
+ requirements:
135
+ - - ">="
136
+ - !ruby/object:Gem::Version
137
+ version: '0'
138
+ type: :development
139
+ prerelease: false
140
+ version_requirements: !ruby/object:Gem::Requirement
141
+ requirements:
142
+ - - ">="
143
+ - !ruby/object:Gem::Version
144
+ version: '0'
145
+ - !ruby/object:Gem::Dependency
146
+ name: minitest-rg
147
+ requirement: !ruby/object:Gem::Requirement
148
+ requirements:
149
+ - - ">="
150
+ - !ruby/object:Gem::Version
151
+ version: '0'
152
+ type: :development
153
+ prerelease: false
154
+ version_requirements: !ruby/object:Gem::Requirement
155
+ requirements:
156
+ - - ">="
157
+ - !ruby/object:Gem::Version
158
+ version: '0'
159
+ - !ruby/object:Gem::Dependency
160
+ name: aws-sdk-v1
161
+ requirement: !ruby/object:Gem::Requirement
162
+ requirements:
163
+ - - ">="
164
+ - !ruby/object:Gem::Version
165
+ version: '0'
166
+ type: :development
167
+ prerelease: false
168
+ version_requirements: !ruby/object:Gem::Requirement
169
+ requirements:
170
+ - - ">="
171
+ - !ruby/object:Gem::Version
172
+ version: '0'
173
+ - !ruby/object:Gem::Dependency
174
+ name: cloudfiles
175
+ requirement: !ruby/object:Gem::Requirement
176
+ requirements:
177
+ - - ">="
178
+ - !ruby/object:Gem::Version
179
+ version: '0'
180
+ type: :development
181
+ prerelease: false
182
+ version_requirements: !ruby/object:Gem::Requirement
183
+ requirements:
184
+ - - ">="
185
+ - !ruby/object:Gem::Version
186
+ version: '0'
187
+ - !ruby/object:Gem::Dependency
188
+ name: byebug
189
+ requirement: !ruby/object:Gem::Requirement
190
+ requirements:
191
+ - - ">="
192
+ - !ruby/object:Gem::Version
193
+ version: '0'
194
+ type: :development
195
+ prerelease: false
196
+ version_requirements: !ruby/object:Gem::Requirement
197
+ requirements:
198
+ - - ">="
199
+ - !ruby/object:Gem::Version
200
+ version: '0'
201
+ description: Adds has_attachment (file store) properties to ActiveRecord. Supports
202
+ local file, file-in-db, S3 and Cloudfiles backends.
203
+ email:
204
+ executables: []
205
+ extensions: []
206
+ extra_rdoc_files: []
207
+ files:
208
+ - CHANGELOG
209
+ - README.md
210
+ - lib/attachment_fu.rb
211
+ - lib/technoweenie/attachment_fu.rb
212
+ - lib/technoweenie/attachment_fu/backends/backend_delegator.rb
213
+ - lib/technoweenie/attachment_fu/backends/cloud_file_backend.rb
214
+ - lib/technoweenie/attachment_fu/backends/db_file_backend.rb
215
+ - lib/technoweenie/attachment_fu/backends/file_system_backend.rb
216
+ - lib/technoweenie/attachment_fu/backends/mogile_fs_backend.rb
217
+ - lib/technoweenie/attachment_fu/backends/s3_backend.rb
218
+ - lib/technoweenie/attachment_fu/geometry.rb
219
+ - lib/technoweenie/attachment_fu/processors/core_image_processor.rb
220
+ - lib/technoweenie/attachment_fu/processors/gd2_processor.rb
221
+ - lib/technoweenie/attachment_fu/processors/image_science_processor.rb
222
+ - lib/technoweenie/attachment_fu/processors/mini_magick_processor.rb
223
+ - lib/technoweenie/attachment_fu/processors/rmagick_processor.rb
224
+ - vendor/red_artisan/core_image/filters/color.rb
225
+ - vendor/red_artisan/core_image/filters/effects.rb
226
+ - vendor/red_artisan/core_image/filters/perspective.rb
227
+ - vendor/red_artisan/core_image/filters/quality.rb
228
+ - vendor/red_artisan/core_image/filters/scale.rb
229
+ - vendor/red_artisan/core_image/filters/watermark.rb
230
+ - vendor/red_artisan/core_image/processor.rb
231
+ homepage: https://github.com/zendesk/attachment_fu
232
+ licenses: []
233
+ metadata: {}
234
+ post_install_message:
235
+ rdoc_options: []
236
+ require_paths:
237
+ - lib
238
+ - vendor
239
+ required_ruby_version: !ruby/object:Gem::Requirement
240
+ requirements:
241
+ - - ">="
242
+ - !ruby/object:Gem::Version
243
+ version: '0'
244
+ required_rubygems_version: !ruby/object:Gem::Requirement
245
+ requirements:
246
+ - - ">="
247
+ - !ruby/object:Gem::Version
248
+ version: '0'
249
+ requirements: []
250
+ rubyforge_project:
251
+ rubygems_version: 2.2.2
252
+ signing_key:
253
+ specification_version: 4
254
+ summary: Adds has_attachment properties to ActiveRecord
255
+ test_files: []