tvdeyen-fleximage 1.0.5
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.rdoc +14 -0
- data/MIT-LICENSE +20 -0
- data/README.rdoc +36 -0
- data/Rakefile +49 -0
- data/VERSION +1 -0
- data/autotest.rb +5 -0
- data/init.rb +1 -0
- data/lib/dsl_accessor.rb +52 -0
- data/lib/fleximage.rb +59 -0
- data/lib/fleximage/aviary_controller.rb +75 -0
- data/lib/fleximage/blank.rb +70 -0
- data/lib/fleximage/helper.rb +41 -0
- data/lib/fleximage/image_proxy.rb +69 -0
- data/lib/fleximage/legacy_view.rb +63 -0
- data/lib/fleximage/model.rb +713 -0
- data/lib/fleximage/operator/background.rb +62 -0
- data/lib/fleximage/operator/base.rb +189 -0
- data/lib/fleximage/operator/border.rb +50 -0
- data/lib/fleximage/operator/crop.rb +58 -0
- data/lib/fleximage/operator/image_overlay.rb +85 -0
- data/lib/fleximage/operator/resize.rb +92 -0
- data/lib/fleximage/operator/shadow.rb +87 -0
- data/lib/fleximage/operator/text.rb +104 -0
- data/lib/fleximage/operator/trim.rb +14 -0
- data/lib/fleximage/operator/unsharp_mask.rb +36 -0
- data/lib/fleximage/rails3_view.rb +31 -0
- data/lib/fleximage/rmagick_image_patch.rb +7 -0
- data/lib/fleximage/view.rb +57 -0
- data/lib/tasks/fleximage_tasks.rake +154 -0
- data/test/fixtures/100x1.jpg +0 -0
- data/test/fixtures/100x100.jpg +0 -0
- data/test/fixtures/1x1.jpg +0 -0
- data/test/fixtures/1x100.jpg +0 -0
- data/test/fixtures/cmyk.jpg +0 -0
- data/test/fixtures/not_a_photo.xml +1 -0
- data/test/fixtures/photo.jpg +0 -0
- data/test/mock_file.rb +21 -0
- data/test/rails_root/app/controllers/application.rb +10 -0
- data/test/rails_root/app/controllers/avatars_controller.rb +85 -0
- data/test/rails_root/app/controllers/photo_bares_controller.rb +85 -0
- data/test/rails_root/app/controllers/photo_dbs_controller.rb +85 -0
- data/test/rails_root/app/controllers/photo_files_controller.rb +85 -0
- data/test/rails_root/app/helpers/application_helper.rb +3 -0
- data/test/rails_root/app/helpers/avatars_helper.rb +2 -0
- data/test/rails_root/app/helpers/photo_bares_helper.rb +2 -0
- data/test/rails_root/app/helpers/photo_dbs_helper.rb +2 -0
- data/test/rails_root/app/helpers/photo_files_helper.rb +2 -0
- data/test/rails_root/app/locales/de.yml +7 -0
- data/test/rails_root/app/locales/en.yml +8 -0
- data/test/rails_root/app/models/abstract.rb +8 -0
- data/test/rails_root/app/models/avatar.rb +4 -0
- data/test/rails_root/app/models/photo_bare.rb +7 -0
- data/test/rails_root/app/models/photo_custom_error.rb +10 -0
- data/test/rails_root/app/models/photo_db.rb +3 -0
- data/test/rails_root/app/models/photo_file.rb +3 -0
- data/test/rails_root/app/models/photo_s3.rb +5 -0
- data/test/rails_root/app/views/avatars/edit.html.erb +17 -0
- data/test/rails_root/app/views/avatars/index.html.erb +20 -0
- data/test/rails_root/app/views/avatars/new.html.erb +16 -0
- data/test/rails_root/app/views/avatars/show.html.erb +8 -0
- data/test/rails_root/app/views/layouts/avatars.html.erb +17 -0
- data/test/rails_root/app/views/layouts/photo_bares.html.erb +17 -0
- data/test/rails_root/app/views/layouts/photo_dbs.html.erb +17 -0
- data/test/rails_root/app/views/layouts/photo_files.html.erb +17 -0
- data/test/rails_root/app/views/photo_bares/edit.html.erb +12 -0
- data/test/rails_root/app/views/photo_bares/index.html.erb +18 -0
- data/test/rails_root/app/views/photo_bares/new.html.erb +11 -0
- data/test/rails_root/app/views/photo_bares/show.html.erb +3 -0
- data/test/rails_root/app/views/photo_dbs/edit.html.erb +32 -0
- data/test/rails_root/app/views/photo_dbs/index.html.erb +26 -0
- data/test/rails_root/app/views/photo_dbs/new.html.erb +31 -0
- data/test/rails_root/app/views/photo_dbs/show.html.erb +23 -0
- data/test/rails_root/app/views/photo_files/edit.html.erb +27 -0
- data/test/rails_root/app/views/photo_files/index.html.erb +24 -0
- data/test/rails_root/app/views/photo_files/new.html.erb +26 -0
- data/test/rails_root/app/views/photo_files/show.html.erb +18 -0
- data/test/rails_root/config/boot.rb +109 -0
- data/test/rails_root/config/database.yml +7 -0
- data/test/rails_root/config/environment.rb +66 -0
- data/test/rails_root/config/environments/development.rb +18 -0
- data/test/rails_root/config/environments/production.rb +19 -0
- data/test/rails_root/config/environments/sqlite3.rb +0 -0
- data/test/rails_root/config/environments/test.rb +22 -0
- data/test/rails_root/config/initializers/inflections.rb +10 -0
- data/test/rails_root/config/initializers/load_translations.rb +4 -0
- data/test/rails_root/config/initializers/mime_types.rb +5 -0
- data/test/rails_root/config/routes.rb +43 -0
- data/test/rails_root/db/migrate/001_create_photo_files.rb +16 -0
- data/test/rails_root/db/migrate/002_create_photo_dbs.rb +16 -0
- data/test/rails_root/db/migrate/003_create_photo_bares.rb +12 -0
- data/test/rails_root/db/migrate/004_create_avatars.rb +13 -0
- data/test/rails_root/db/migrate/005_create_photo_s3s.rb +12 -0
- data/test/rails_root/public/.htaccess +40 -0
- data/test/rails_root/public/404.html +30 -0
- data/test/rails_root/public/422.html +30 -0
- data/test/rails_root/public/500.html +30 -0
- data/test/rails_root/public/dispatch.cgi +10 -0
- data/test/rails_root/public/dispatch.fcgi +24 -0
- data/test/rails_root/public/dispatch.rb +10 -0
- data/test/rails_root/public/favicon.ico +0 -0
- data/test/rails_root/public/images/rails.png +0 -0
- data/test/rails_root/public/index.html +277 -0
- data/test/rails_root/public/javascripts/application.js +2 -0
- data/test/rails_root/public/javascripts/controls.js +963 -0
- data/test/rails_root/public/javascripts/dragdrop.js +972 -0
- data/test/rails_root/public/javascripts/effects.js +1120 -0
- data/test/rails_root/public/javascripts/prototype.js +4225 -0
- data/test/rails_root/public/robots.txt +5 -0
- data/test/rails_root/public/stylesheets/scaffold.css +74 -0
- data/test/rails_root/vendor/plugins/fleximage/init.rb +2 -0
- data/test/s3_stubs.rb +7 -0
- data/test/test_helper.rb +82 -0
- data/test/unit/abstract_test.rb +20 -0
- data/test/unit/basic_model_test.rb +40 -0
- data/test/unit/blank_test.rb +23 -0
- data/test/unit/default_image_path_option_test.rb +16 -0
- data/test/unit/dsl_accessor_test.rb +120 -0
- data/test/unit/file_upload_from_local_test.rb +31 -0
- data/test/unit/file_upload_from_strings_test.rb +23 -0
- data/test/unit/file_upload_from_url_test.rb +35 -0
- data/test/unit/file_upload_to_db_test.rb +41 -0
- data/test/unit/has_store_test.rb +4 -0
- data/test/unit/i18n_messages_test.rb +49 -0
- data/test/unit/image_directory_option_test.rb +20 -0
- data/test/unit/image_proxy_test.rb +17 -0
- data/test/unit/image_storage_format_option_test.rb +31 -0
- data/test/unit/magic_columns_test.rb +34 -0
- data/test/unit/minimum_image_size_test.rb +56 -0
- data/test/unit/operator_base_test.rb +124 -0
- data/test/unit/operator_resize_test.rb +18 -0
- data/test/unit/preprocess_image_option_test.rb +21 -0
- data/test/unit/require_image_option_test.rb +30 -0
- data/test/unit/temp_image_test.rb +23 -0
- data/test/unit/use_creation_date_based_directories_option_test.rb +16 -0
- data/tvdeyen-fleximage.gemspec +180 -0
- metadata +244 -0
data/CHANGELOG.rdoc
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
== fleximage 1.0.2 12-14-2009
|
2
|
+
|
3
|
+
* Don't prepend Rails.root to absolute image directory path
|
4
|
+
* Added support for an "image_format" magic database column
|
5
|
+
* Fixed an issue with saving temp images in Windows
|
6
|
+
* Fixed a temp image vulnerability with directory traversal
|
7
|
+
|
8
|
+
== fleximage 1.0.1 12-13-2009
|
9
|
+
|
10
|
+
* Now with completely passing tests
|
11
|
+
|
12
|
+
== fleximage 1.0.0 12-13-2009
|
13
|
+
|
14
|
+
* Initial gem release.
|
data/MIT-LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2008 [name of plugin creator]
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.rdoc
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
For all istructions refers to git://github.com/Squeegy/fleximage.
|
2
|
+
I add a rails3_view.rb to manage template in rails3.
|
3
|
+
|
4
|
+
#rails3_view.rb
|
5
|
+
|
6
|
+
module ActionView
|
7
|
+
module TemplateHandlers
|
8
|
+
class Rails3View < TemplateHandler
|
9
|
+
include Compilable
|
10
|
+
class TemplateDidNotReturnImage < RuntimeError #:nodoc:
|
11
|
+
end
|
12
|
+
|
13
|
+
def compile(template)
|
14
|
+
<<-CODE
|
15
|
+
@template_format = :flexi
|
16
|
+
controller.response.content_type ||= Mime::JPG
|
17
|
+
result = #{template.source}
|
18
|
+
requested_format = (params[:format] || :jpg).to_sym
|
19
|
+
begin
|
20
|
+
# Raise an error if object returned from template is not an image record
|
21
|
+
unless result.class.include?(Fleximage::Model::InstanceMethods)
|
22
|
+
raise TemplateDidNotReturnImage, ".flexi template was expected to return a model instance that acts_as_fleximage, but got an instance of instead."
|
23
|
+
end
|
24
|
+
# Figure out the proper format
|
25
|
+
raise 'Image must be requested with an image type format. jpg, gif and png only are supported.' unless [:jpg, :gif, :png].include?(requested_format)
|
26
|
+
result.output_image(:format => requested_format)
|
27
|
+
rescue Exception => e
|
28
|
+
e
|
29
|
+
end
|
30
|
+
CODE
|
31
|
+
ensure
|
32
|
+
GC.start
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
data/Rakefile
ADDED
@@ -0,0 +1,49 @@
|
|
1
|
+
require 'rake'
|
2
|
+
require 'rake/testtask'
|
3
|
+
require 'rake/rdoctask'
|
4
|
+
require 'rubygems'
|
5
|
+
|
6
|
+
desc 'Default: run unit tests.'
|
7
|
+
task :default => :test
|
8
|
+
|
9
|
+
desc 'Test the fleximage plugin.'
|
10
|
+
Rake::TestTask.new(:test) do |t|
|
11
|
+
t.libs << 'lib'
|
12
|
+
t.pattern = 'test/unit/**/*_test.rb'
|
13
|
+
t.verbose = true
|
14
|
+
end
|
15
|
+
|
16
|
+
|
17
|
+
desc 'Generate documentation for the fleximage plugin.'
|
18
|
+
Rake::RDocTask.new(:rdoc) do |rdoc|
|
19
|
+
rdoc.rdoc_dir = 'rdoc'
|
20
|
+
rdoc.title = 'Fleximage'
|
21
|
+
rdoc.options << '--line-numbers' << '--inline-source'
|
22
|
+
rdoc.rdoc_files.include('README.rdoc')
|
23
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
24
|
+
end
|
25
|
+
|
26
|
+
begin
|
27
|
+
require 'jeweler'
|
28
|
+
Jeweler::Tasks.new do |gem|
|
29
|
+
gem.name = "tvdeyen-fleximage"
|
30
|
+
gem.summary = <<EOF
|
31
|
+
Rails plugin for uploading images as resources, with support for resizing, text
|
32
|
+
stamping, and other special effects.
|
33
|
+
EOF
|
34
|
+
gem.description = <<EOF
|
35
|
+
Fleximage is a Rails plugin that tries to make image uploading and rendering
|
36
|
+
super easy.
|
37
|
+
EOF
|
38
|
+
gem.email = "tvdeyen@gmail.com"
|
39
|
+
gem.homepage = "http://github.com/tvdeyen/fleximage"
|
40
|
+
gem.authors = `git log --pretty=format:"%an"`.split("\n").uniq.sort
|
41
|
+
gem.add_dependency "rmagick"
|
42
|
+
gem.add_dependency "aws-s3"
|
43
|
+
gem.add_development_dependency "rails", ">=3.0.0"
|
44
|
+
end
|
45
|
+
Jeweler::GemcutterTasks.new
|
46
|
+
rescue LoadError
|
47
|
+
puts "Jeweler (or a dependency) not available."
|
48
|
+
puts "Install it with: gem install jeweler"
|
49
|
+
end
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
1.0.5
|
data/autotest.rb
ADDED
data/init.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require File.expand_path(File.join(File.dirname(__FILE__), %w(lib fleximage)))
|
data/lib/dsl_accessor.rb
ADDED
@@ -0,0 +1,52 @@
|
|
1
|
+
require 'active_support' unless defined?(ActiveSupport)
|
2
|
+
|
3
|
+
class Class
|
4
|
+
def dsl_accessor(name, options = {})
|
5
|
+
raise TypeError, "DSL Error: options should be a hash. but got `#{options.class}'" unless options.is_a?(Hash)
|
6
|
+
writer = options[:writer] || options[:setter]
|
7
|
+
writer =
|
8
|
+
case writer
|
9
|
+
when NilClass then Proc.new{|value| value}
|
10
|
+
when Symbol then Proc.new{|value| __send__(writer, value)}
|
11
|
+
when Proc then writer
|
12
|
+
else raise TypeError, "DSL Error: writer should be a symbol or proc. but got `#{options[:writer].class}'"
|
13
|
+
end
|
14
|
+
write_inheritable_attribute(:"#{name}_writer", writer)
|
15
|
+
|
16
|
+
default =
|
17
|
+
case options[:default]
|
18
|
+
when NilClass then nil
|
19
|
+
when [] then Proc.new{[]}
|
20
|
+
when {} then Proc.new{{}}
|
21
|
+
when Symbol then Proc.new{__send__(options[:default])}
|
22
|
+
when Proc then options[:default]
|
23
|
+
else Proc.new{options[:default]}
|
24
|
+
end
|
25
|
+
write_inheritable_attribute(:"#{name}_default", default)
|
26
|
+
|
27
|
+
self.class.class_eval do
|
28
|
+
define_method("#{name}=") do |value|
|
29
|
+
writer = read_inheritable_attribute(:"#{name}_writer")
|
30
|
+
value = writer.call(value) if writer
|
31
|
+
write_inheritable_attribute(:"#{name}", value)
|
32
|
+
end
|
33
|
+
|
34
|
+
define_method(name) do |*values|
|
35
|
+
if values.empty?
|
36
|
+
# getter method
|
37
|
+
key = :"#{name}"
|
38
|
+
if !inheritable_attributes.has_key?(key)
|
39
|
+
default = read_inheritable_attribute(:"#{name}_default")
|
40
|
+
value = default ? default.call(self) : nil
|
41
|
+
__send__("#{name}=", value)
|
42
|
+
end
|
43
|
+
read_inheritable_attribute(key)
|
44
|
+
else
|
45
|
+
# setter method
|
46
|
+
__send__("#{name}=", *values)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
data/lib/fleximage.rb
ADDED
@@ -0,0 +1,59 @@
|
|
1
|
+
require 'open-uri'
|
2
|
+
require 'base64'
|
3
|
+
require 'digest/sha1'
|
4
|
+
require 'aws/s3'
|
5
|
+
|
6
|
+
require 'RMagick' unless defined?(Magick)
|
7
|
+
|
8
|
+
# Apply a few RMagick patches
|
9
|
+
require 'fleximage/rmagick_image_patch'
|
10
|
+
|
11
|
+
# Load dsl_accessor from lib
|
12
|
+
require 'dsl_accessor'
|
13
|
+
|
14
|
+
# Load Operators
|
15
|
+
require 'fleximage/operator/base'
|
16
|
+
Dir.entries("#{File.dirname(__FILE__)}/fleximage/operator").each do |filename|
|
17
|
+
require "fleximage/operator/#{filename.gsub('.rb', '')}" if filename =~ /\.rb$/
|
18
|
+
end
|
19
|
+
|
20
|
+
# Setup Model
|
21
|
+
require 'fleximage/model'
|
22
|
+
ActiveRecord::Base.class_eval { include Fleximage::Model }
|
23
|
+
|
24
|
+
# Image Creation
|
25
|
+
require 'fleximage/blank'
|
26
|
+
|
27
|
+
# Image Proxy
|
28
|
+
require 'fleximage/image_proxy'
|
29
|
+
|
30
|
+
# Setup View
|
31
|
+
#ActionController::Base.exempt_from_layout :flexi
|
32
|
+
if defined?(ActionView::Template)
|
33
|
+
# Rails >= 2.1
|
34
|
+
if Rails.version.to_f >= 3
|
35
|
+
require 'fleximage/rails3_view'
|
36
|
+
ActionView::Template.register_template_handler :flexi, ActionView::TemplateHandlers::Rails3View
|
37
|
+
else
|
38
|
+
require 'fleximage/view'
|
39
|
+
ActionView::Template.register_template_handler :flexi, Fleximage::View
|
40
|
+
end
|
41
|
+
else
|
42
|
+
# Rails < 2.1
|
43
|
+
require 'fleximage/legacy_view'
|
44
|
+
ActionView::Base.register_template_handler :flexi, Fleximage::LegacyView
|
45
|
+
end
|
46
|
+
|
47
|
+
# Setup Helper
|
48
|
+
require 'fleximage/helper'
|
49
|
+
ActionView::Base.class_eval { include Fleximage::Helper }
|
50
|
+
|
51
|
+
# Setup Aviary Controller
|
52
|
+
require 'fleximage/aviary_controller'
|
53
|
+
ActionController::Base.class_eval{ include Fleximage::AviaryController }
|
54
|
+
|
55
|
+
# Register mime types
|
56
|
+
Mime::Type.register_alias "image/pjpeg", :jpg # IE6 sends jpg data as "image/pjpeg". Silly IE6.
|
57
|
+
Mime::Type.register "image/jpeg", :jpg
|
58
|
+
Mime::Type.register "image/gif", :gif
|
59
|
+
Mime::Type.register "image/png", :png
|
@@ -0,0 +1,75 @@
|
|
1
|
+
module Fleximage
|
2
|
+
|
3
|
+
module AviaryController
|
4
|
+
def self.api_key(value = nil)
|
5
|
+
value ? @api_key = value : @api_key
|
6
|
+
end
|
7
|
+
|
8
|
+
def self.api_key=(value = nil)
|
9
|
+
api_key value
|
10
|
+
end
|
11
|
+
|
12
|
+
# Include acts_as_fleximage class method
|
13
|
+
def self.included(base) #:nodoc:
|
14
|
+
base.extend(ClassMethods)
|
15
|
+
end
|
16
|
+
|
17
|
+
module ClassMethods
|
18
|
+
|
19
|
+
# Invoke this method to enable this controller to allow editing of images via Aviary
|
20
|
+
def editable_in_aviary(model_class, options = {})
|
21
|
+
unless options.has_key?(:secret)
|
22
|
+
raise ArgumentError, ":secret key in options is required.\nExample: editable_in_aviary(Photo, :secret => \"My-deep-dark-secret\")"
|
23
|
+
end
|
24
|
+
|
25
|
+
# Don't verify authenticity for aviary callback
|
26
|
+
protect_from_forgery :except => :aviary_image_update
|
27
|
+
|
28
|
+
# Include the necesary instance methods
|
29
|
+
include Fleximage::AviaryController::InstanceMethods
|
30
|
+
|
31
|
+
# Add before_filter to secure aviary actions
|
32
|
+
before_filter :aviary_image_security, :only => [:aviary_image, :aviary_image_update]
|
33
|
+
|
34
|
+
# Allow the view access to the image hash generation method
|
35
|
+
helper_method :aviary_image_hash
|
36
|
+
|
37
|
+
# Save the Fleximage model class
|
38
|
+
model_class = model_class.constantize if model_class.is_a?(String)
|
39
|
+
dsl_accessor :aviary_model_class, :default => model_class
|
40
|
+
dsl_accessor :aviary_secret, :default => options[:secret]
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
44
|
+
|
45
|
+
module InstanceMethods
|
46
|
+
|
47
|
+
# Deliver the master image to aviary
|
48
|
+
def aviary_image
|
49
|
+
render :text => @model.load_image.to_blob,
|
50
|
+
:content_type => Mime::Type.lookup_by_extension(self.class.aviary_model_class.image_storage_format.to_s)
|
51
|
+
end
|
52
|
+
|
53
|
+
# Aviary posts the edited image back to the controller here
|
54
|
+
def aviary_image_update
|
55
|
+
@model.image_file_url = params[:imageurl]
|
56
|
+
@model.save
|
57
|
+
render :text => 'Image Updated From Aviary'
|
58
|
+
end
|
59
|
+
|
60
|
+
protected
|
61
|
+
def aviary_image_hash(model)
|
62
|
+
Digest::SHA1.hexdigest("fleximage-aviary-#{model.id}-#{model.created_at}-#{self.class.aviary_secret}")
|
63
|
+
end
|
64
|
+
|
65
|
+
def aviary_image_security
|
66
|
+
@model = self.class.aviary_model_class.find(params[:id])
|
67
|
+
unless aviary_image_hash(@model) == params[:key]
|
68
|
+
render :text => '<h1>403 Not Authorized</h1>', :status => '403'
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
end
|
@@ -0,0 +1,70 @@
|
|
1
|
+
module Fleximage
|
2
|
+
|
3
|
+
# The +Blank+ class allows easy creation of dynamic images for views which depends models that
|
4
|
+
# do not store images. For example, perhaps you want a rendering of a text label, or a comment,
|
5
|
+
# or some other type of data that is not inherently image based.
|
6
|
+
#
|
7
|
+
# Your model doesn't need to know anything about Fleximage. You can instantiate and operate on
|
8
|
+
# a new Fleximage::Blank object right in your view.
|
9
|
+
#
|
10
|
+
# Usage:
|
11
|
+
#
|
12
|
+
# Fleximage::Blank.new(size, options = {}).operate { |image| ... }
|
13
|
+
#
|
14
|
+
# Use the following keys in the +options+ hash:
|
15
|
+
#
|
16
|
+
# * color: the color the image will be. Can be a named color or a Magick::Pixel object.
|
17
|
+
#
|
18
|
+
# Example:
|
19
|
+
#
|
20
|
+
# # app/views/comments/show.png.flexi
|
21
|
+
# Fleximage::Blank.new('400x150')).operate do |image|
|
22
|
+
# # Start with a chat bubble image as the background
|
23
|
+
# image.image_overlay('public/images/comment_bubble.png')
|
24
|
+
#
|
25
|
+
# # Assuming that the user model acts_as_fleximage, this will draw the users image.
|
26
|
+
# image.image_overlay(@comment.user.file_path,
|
27
|
+
# :size => '50x50',
|
28
|
+
# :alignment => :top_left,
|
29
|
+
# :offset => '10x10'
|
30
|
+
# )
|
31
|
+
#
|
32
|
+
# # Add the author name text
|
33
|
+
# image.text(@comment.author,
|
34
|
+
# :alignment => :top_left,
|
35
|
+
# :offset => '10x10',
|
36
|
+
# :color => 'black',
|
37
|
+
# :font_size => 24,
|
38
|
+
# :shadow => {
|
39
|
+
# :blur => 1,
|
40
|
+
# :opacity => 0.5,
|
41
|
+
# }
|
42
|
+
# )
|
43
|
+
#
|
44
|
+
# # Add the comment body text
|
45
|
+
# image.text(@comment.body,
|
46
|
+
# :alignment => :top_left,
|
47
|
+
# :offset => '10x90',
|
48
|
+
# :color => color(128, 128, 128),
|
49
|
+
# :font_size => 14
|
50
|
+
# )
|
51
|
+
# end
|
52
|
+
class Blank
|
53
|
+
include Fleximage::Model
|
54
|
+
acts_as_fleximage
|
55
|
+
|
56
|
+
def initialize(size, options = {})
|
57
|
+
width, height = Fleximage::Operator::Base.size_to_xy(size)
|
58
|
+
|
59
|
+
@uploaded_image = Magick::Image.new(width, height) do
|
60
|
+
self.colorspace = Magick::RGBColorspace
|
61
|
+
self.depth = 8
|
62
|
+
self.density = '72'
|
63
|
+
self.format = 'PNG'
|
64
|
+
self.background_color = options[:color] || 'none'
|
65
|
+
end
|
66
|
+
|
67
|
+
@output_image = @uploaded_image
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
module Fleximage
|
2
|
+
module Helper
|
3
|
+
|
4
|
+
# Creates an image tag that links directly to image data. Recommended for displays of a
|
5
|
+
# temporary upload that is not saved to a record in the databse yet.
|
6
|
+
def embedded_image_tag(model, options = {})
|
7
|
+
model.load_image
|
8
|
+
format = options[:format] || :jpg
|
9
|
+
mime = Mime::Type.lookup_by_extension(format.to_s).to_s
|
10
|
+
image = model.output_image(:format => format)
|
11
|
+
data = Base64.encode64(image)
|
12
|
+
|
13
|
+
options = { :alt => model.class.to_s }.merge(options)
|
14
|
+
|
15
|
+
result = image_tag("data:#{mime};base64,#{data}", options)
|
16
|
+
result.gsub(%r{src=".*/images/data:}, 'src="data:')
|
17
|
+
|
18
|
+
rescue Fleximage::Model::MasterImageNotFound => e
|
19
|
+
nil
|
20
|
+
end
|
21
|
+
|
22
|
+
# Creates a link that opens an image for editing in Aviary.
|
23
|
+
#
|
24
|
+
# Options:
|
25
|
+
#
|
26
|
+
# * image_url: url to the master image used by Aviary for editing. Defauls to <tt>url_for(:action => 'aviary_image', :id => model, :only_path => false)</tt>
|
27
|
+
# * post_url: url where Aviary will post the updated image. Defauls to <tt>url_for(:action => 'aviary_image_update', :id => model, :only_path => false)</tt>
|
28
|
+
#
|
29
|
+
# All other options are passed directly to the @link_to@ helper.
|
30
|
+
def link_to_edit_in_aviary(text, model, options = {})
|
31
|
+
key = aviary_image_hash(model)
|
32
|
+
image_url = options.delete(:image_url) || url_for(:action => 'aviary_image', :id => model, :only_path => false, :key => key)
|
33
|
+
post_url = options.delete(:image_update_url) || url_for(:action => 'aviary_image_update', :id => model, :only_path => false, :key => key)
|
34
|
+
api_key = Fleximage::AviaryController.api_key
|
35
|
+
url = "http://aviary.com/flash/aviary/index.aspx?tid=1&phoenix&apil=#{api_key}&loadurl=#{CGI.escape image_url}&posturl=#{CGI.escape post_url}"
|
36
|
+
|
37
|
+
link_to text, url, { :target => 'aviary' }.merge(options)
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
module Fleximage
|
2
|
+
|
3
|
+
# An instance of this class is yielded when Model#operate is called. It enables image operators
|
4
|
+
# to be called to transform the image. You should never need to directly deal with this class.
|
5
|
+
# You simply call image operators on this object when inside an Model#operate block
|
6
|
+
#
|
7
|
+
# @photo.operate do |image|
|
8
|
+
# image.resize '640x480'
|
9
|
+
# end
|
10
|
+
#
|
11
|
+
# In this example, +image+ is an instance of ImageProxy
|
12
|
+
class ImageProxy
|
13
|
+
|
14
|
+
class OperatorNotFound < NameError #:nodoc:
|
15
|
+
end
|
16
|
+
|
17
|
+
# The image to be manipulated by operators.
|
18
|
+
attr_accessor :image
|
19
|
+
|
20
|
+
# Create a new image operator proxy.
|
21
|
+
def initialize(image, model_obj)
|
22
|
+
@image = image
|
23
|
+
@model = model_obj
|
24
|
+
end
|
25
|
+
|
26
|
+
# Shortcut for accessing current image width
|
27
|
+
def width
|
28
|
+
@image.columns
|
29
|
+
end
|
30
|
+
|
31
|
+
# Shortcut for accessing current image height
|
32
|
+
def height
|
33
|
+
@image.rows
|
34
|
+
end
|
35
|
+
|
36
|
+
# A call to an unknown method will look for an Operator by that method's name.
|
37
|
+
# If it finds one, it will execute that operator.
|
38
|
+
def method_missing(method_name, *args)
|
39
|
+
# Find the operator class
|
40
|
+
class_name = method_name.to_s.camelcase
|
41
|
+
operator_class = "Fleximage::Operator::#{class_name}".constantize
|
42
|
+
|
43
|
+
# Define a method for this operator so future calls to this operation are faster
|
44
|
+
self.class.module_eval <<-EOF
|
45
|
+
def #{method_name}(*args)
|
46
|
+
@image = execute_operator(#{operator_class}, *args)
|
47
|
+
end
|
48
|
+
EOF
|
49
|
+
|
50
|
+
# Call the method that was just defined to perform its functionality.
|
51
|
+
send(method_name, *args)
|
52
|
+
|
53
|
+
rescue NameError => e
|
54
|
+
if e.to_s =~ /uninitialized constant Fleximage::Operator::#{class_name}/
|
55
|
+
raise OperatorNotFound, "No operator Fleximage::Operator::#{class_name} found for the method \"#{method_name}\""
|
56
|
+
else
|
57
|
+
raise e
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
private
|
62
|
+
# Instantiate and execute the requested image Operator.
|
63
|
+
def execute_operator(operator_class, *args)
|
64
|
+
operator_class.new(self, @image, @model).execute(*args)
|
65
|
+
end
|
66
|
+
|
67
|
+
end
|
68
|
+
|
69
|
+
end
|