forked from technoweenie/attachment_fu
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add support for Core Image in attachment_fu via a new core_image_proc…
…essor class that uses a vendor imported mini core image library. Updated attachment_fu to automatically use core image when available and fall back to Image Science, Rmagick and MiniMagick when not available.
- Loading branch information
Showing
13 changed files
with
422 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
56 changes: 56 additions & 0 deletions
56
lib/technoweenie/attachment_fu/processors/core_image_processor.rb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
require 'red_artisan/core_image/processor' | ||
|
||
module Technoweenie # :nodoc: | ||
module AttachmentFu # :nodoc: | ||
module Processors | ||
module CoreImageProcessor | ||
def self.included(base) | ||
base.send :extend, ClassMethods | ||
base.alias_method_chain :process_attachment, :processing | ||
end | ||
|
||
module ClassMethods | ||
def with_image(file, &block) | ||
block.call OSX::CIImage.from(file) | ||
end | ||
end | ||
|
||
protected | ||
def process_attachment_with_processing | ||
return unless process_attachment_without_processing | ||
with_image do |img| | ||
self.width = img.extent.size.width if respond_to?(:width) | ||
self.height = img.extent.size.height if respond_to?(:height) | ||
resize_image_or_thumbnail! img | ||
callback_with_args :after_resize, img | ||
end if image? | ||
end | ||
|
||
# Performs the actual resizing operation for a thumbnail | ||
def resize_image(img, size) | ||
processor = ::RedArtisan::CoreImage::Processor.new(img) | ||
size = size.first if size.is_a?(Array) && size.length == 1 | ||
if size.is_a?(Fixnum) || (size.is_a?(Array) && size.first.is_a?(Fixnum)) | ||
if size.is_a?(Fixnum) | ||
processor.fit(size) | ||
else | ||
processor.resize(size[0], size[1]) | ||
end | ||
else | ||
new_size = [img.extent.size.width, img.extent.size.height] / size.to_s | ||
processor.resize(new_size[0], new_size[1]) | ||
end | ||
|
||
processor.render do |result| | ||
self.width = result.extent.size.width if respond_to?(:width) | ||
self.height = result.extent.size.height if respond_to?(:height) | ||
result.save self.temp_path, OSX::NSJPEGFileType | ||
self.size = File.size(self.temp_path) | ||
end | ||
end | ||
end | ||
end | ||
end | ||
end | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
require File.expand_path(File.join(File.dirname(__FILE__), '..', 'test_helper')) | ||
|
||
class CoreImageTest < Test::Unit::TestCase | ||
attachment_model CoreImageAttachment | ||
|
||
if Object.const_defined?(:OSX) | ||
def test_should_resize_image | ||
attachment = upload_file :filename => '/files/rails.png' | ||
assert_valid attachment | ||
assert attachment.image? | ||
# test core image thumbnail | ||
assert_equal 42, attachment.width | ||
assert_equal 55, attachment.height | ||
|
||
thumb = attachment.thumbnails.detect { |t| t.filename =~ /_thumb/ } | ||
geo = attachment.thumbnails.detect { |t| t.filename =~ /_geometry/ } | ||
|
||
# test exact resize dimensions | ||
assert_equal 50, thumb.width | ||
assert_equal 51, thumb.height | ||
|
||
# test geometry string | ||
assert_equal 31, geo.width | ||
assert_equal 41, geo.height | ||
end | ||
else | ||
def test_flunk | ||
puts "CoreImage not loaded, tests not running" | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
module RedArtisan | ||
module CoreImage | ||
module Filters | ||
module Color | ||
|
||
def greyscale(color = nil, intensity = 1.00) | ||
create_core_image_context(@original.extent.size.width, @original.extent.size.height) | ||
|
||
color = OSX::CIColor.colorWithString("1.0 1.0 1.0 1.0") unless color | ||
|
||
@original.color_monochrome :inputColor => color, :inputIntensity => intensity do |greyscale| | ||
@target = greyscale | ||
end | ||
end | ||
|
||
def sepia(intensity = 1.00) | ||
create_core_image_context(@original.extent.size.width, @original.extent.size.height) | ||
|
||
@original.sepia_tone :inputIntensity => intensity do |sepia| | ||
@target = sepia | ||
end | ||
end | ||
|
||
end | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
module RedArtisan | ||
module CoreImage | ||
module Filters | ||
module Effects | ||
|
||
def spotlight(position, points_at, brightness, concentration, color) | ||
create_core_image_context(@original.extent.size.width, @original.extent.size.height) | ||
|
||
@original.spot_light :inputLightPosition => vector3(*position), :inputLightPointsAt => vector3(*points_at), | ||
:inputBrightness => brightness, :inputConcentration => concentration, :inputColor => color do |spot| | ||
@target = spot | ||
end | ||
end | ||
|
||
def edges(intensity = 1.00) | ||
create_core_image_context(@original.extent.size.width, @original.extent.size.height) | ||
|
||
@original.edges :inputIntensity => intensity do |edged| | ||
@target = edged | ||
end | ||
end | ||
|
||
private | ||
|
||
def vector3(x, y, w) | ||
OSX::CIVector.vectorWithX_Y_Z(x, y, w) | ||
end | ||
end | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
module RedArtisan | ||
module CoreImage | ||
module Filters | ||
module Perspective | ||
|
||
def perspective(top_left, top_right, bottom_left, bottom_right) | ||
create_core_image_context(@original.extent.size.width, @original.extent.size.height) | ||
|
||
@original.perspective_transform :inputTopLeft => top_left, :inputTopRight => top_right, :inputBottomLeft => bottom_left, :inputBottomRight => bottom_right do |transformed| | ||
@target = transformed | ||
end | ||
end | ||
|
||
def perspective_tiled(top_left, top_right, bottom_left, bottom_right) | ||
create_core_image_context(@original.extent.size.width, @original.extent.size.height) | ||
|
||
@original.perspective_tile :inputTopLeft => top_left, :inputTopRight => top_right, :inputBottomLeft => bottom_left, :inputBottomRight => bottom_right do |tiled| | ||
@target = tiled | ||
end | ||
end | ||
|
||
end | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
module RedArtisan | ||
module CoreImage | ||
module Filters | ||
module Quality | ||
|
||
def reduce_noise(level = 0.02, sharpness = 0.4) | ||
create_core_image_context(@original.extent.size.width, @original.extent.size.height) | ||
|
||
@original.noise_reduction :inputNoiseLevel => level, :inputSharpness => sharpness do |noise_reduced| | ||
@target = noise_reduced | ||
end | ||
end | ||
|
||
def adjust_exposure(input_ev = 0.5) | ||
create_core_image_context(@original.extent.size.width, @original.extent.size.height) | ||
|
||
@original.exposure_adjust :inputEV => input_ev do |adjusted| | ||
@target = adjusted | ||
end | ||
end | ||
|
||
end | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
module RedArtisan | ||
module CoreImage | ||
module Filters | ||
module Scale | ||
|
||
def resize(width, height) | ||
create_core_image_context(width, height) | ||
|
||
scale_x, scale_y = scale(width, height) | ||
|
||
@original.affine_clamp :inputTransform => OSX::NSAffineTransform.transform do |clamped| | ||
clamped.lanczos_scale_transform :inputScale => scale_x > scale_y ? scale_x : scale_y, :inputAspectRatio => scale_x / scale_y do |scaled| | ||
scaled.crop :inputRectangle => vector(0, 0, width, height) do |cropped| | ||
@target = cropped | ||
end | ||
end | ||
end | ||
end | ||
|
||
def thumbnail(width, height) | ||
create_core_image_context(width, height) | ||
|
||
transform = OSX::NSAffineTransform.transform | ||
transform.scaleXBy_yBy *scale(width, height) | ||
|
||
@original.affine_transform :inputTransform => transform do |scaled| | ||
@target = scaled | ||
end | ||
end | ||
|
||
def fit(size) | ||
original_size = @original.extent.size | ||
scale = size.to_f / (original_size.width > original_size.height ? original_size.width : original_size.height) | ||
resize (original_size.width * scale).to_i, (original_size.height * scale).to_i | ||
end | ||
|
||
private | ||
|
||
def scale(width, height) | ||
original_size = @original.extent.size | ||
return width.to_f / original_size.width.to_f, height.to_f / original_size.height.to_f | ||
end | ||
|
||
end | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
module RedArtisan | ||
module CoreImage | ||
module Filters | ||
module Watermark | ||
|
||
def watermark(watermark_image, tile = false, strength = 0.1) | ||
create_core_image_context(@original.extent.size.width, @original.extent.size.height) | ||
|
||
if watermark_image.respond_to? :to_str | ||
watermark_image = OSX::CIImage.from(watermark_image.to_str) | ||
end | ||
|
||
if tile | ||
tile_transform = OSX::NSAffineTransform.transform | ||
tile_transform.scaleXBy_yBy 1.0, 1.0 | ||
|
||
watermark_image.affine_tile :inputTransform => tile_transform do |tiled| | ||
tiled.crop :inputRectangle => vector(0, 0, @original.extent.size.width, @original.extent.size.height) do |tiled_watermark| | ||
watermark_image = tiled_watermark | ||
end | ||
end | ||
end | ||
|
||
@original.dissolve_transition :inputTargetImage => watermark_image, :inputTime => strength do |watermarked| | ||
@target = watermarked | ||
end | ||
end | ||
|
||
end | ||
end | ||
end | ||
end |
Oops, something went wrong.