swf_converter 0.0.3
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.
- data/Gemfile +4 -0
- data/autotest/discover.rb +1 -0
- data/check_memory.rb +41 -0
- data/examples/balloon.png +0 -0
- data/examples/balloon.swf +0 -0
- data/examples/balloon/150x150.png +0 -0
- data/examples/balloon/80x80.png +0 -0
- data/examples/rainy_day.png +0 -0
- data/examples/rainy_day.swf +0 -0
- data/lib/swf_converter.rb +26 -0
- data/lib/swf_converter/engine.rb +24 -0
- data/lib/swf_converter/engine/alphize.rb +132 -0
- data/lib/swf_converter/engine/alphize/blender.rb +80 -0
- data/lib/swf_converter/engine/alphize/runner.rb +18 -0
- data/lib/swf_converter/engine/alphize/swfs/black.swf +0 -0
- data/lib/swf_converter/engine/alphize/swfs/src/Preview.as +20 -0
- data/lib/swf_converter/engine/alphize/swfs/src/black.xml +13 -0
- data/lib/swf_converter/engine/alphize/swfs/src/build.sh +3 -0
- data/lib/swf_converter/engine/alphize/swfs/src/classes.swf +0 -0
- data/lib/swf_converter/engine/alphize/swfs/src/white.xml +13 -0
- data/lib/swf_converter/engine/alphize/swfs/white.swf +0 -0
- data/spec/spec_helper.rb +60 -0
- data/spec/swf_converter/engine/alphize_spec.rb +126 -0
- data/spec/swf_converter/engine_spec.rb +40 -0
- data/spec/swf_converter_spec.rb +35 -0
- data/swf_converter.gemspec +12 -0
- metadata +82 -0
data/Gemfile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
Autotest.add_discovery { "rspec2" }
|
data/check_memory.rb
ADDED
@@ -0,0 +1,41 @@
|
|
1
|
+
$:.unshift File.expand_path('../lib', __FILE__)
|
2
|
+
|
3
|
+
require 'swf_converter'
|
4
|
+
|
5
|
+
class MemoryCheckEngine < SwfConverter::Engine::Alphize
|
6
|
+
def blend(*args)
|
7
|
+
puts "About to blend"
|
8
|
+
super
|
9
|
+
puts "Blended"
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
class Swf
|
14
|
+
include SwfConverter
|
15
|
+
|
16
|
+
attr_reader :swf_image_path
|
17
|
+
|
18
|
+
converts_swfs :with => MemoryCheckEngine, :size => [600, 600]
|
19
|
+
|
20
|
+
def initialize(swf_image_path)
|
21
|
+
@swf_image_path = swf_image_path
|
22
|
+
end
|
23
|
+
|
24
|
+
def local_swf_path
|
25
|
+
File.expand_path(File.join('..', 'examples', 'balloon.swf'), __FILE__)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
3.times do |major_iteration|
|
30
|
+
5.times do |minor_iteration|
|
31
|
+
file = Tempfile.new('check_memory')
|
32
|
+
swf = Swf.new(file.path)
|
33
|
+
puts swf.local_swf_path
|
34
|
+
swf.convert_swf!
|
35
|
+
file.close!
|
36
|
+
puts "Finished #{3 * major_iteration + minor_iteration}"
|
37
|
+
end
|
38
|
+
puts "Enter?";gets
|
39
|
+
end
|
40
|
+
puts "All done!";gets
|
41
|
+
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'swf_converter/engine/alphize'
|
2
|
+
|
3
|
+
module SwfConverter
|
4
|
+
module ClassMethods
|
5
|
+
attr_reader :swf_conversion_engine, :swf_conversion_options
|
6
|
+
|
7
|
+
def converts_swfs(options={})
|
8
|
+
options = options.dup
|
9
|
+
engine_class = options.delete(:with)
|
10
|
+
@swf_conversion_engine = engine_class.new if engine_class
|
11
|
+
@swf_conversion_engine.options = options
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def convert_swf!
|
16
|
+
self.class.swf_conversion_engine.convert!(self)
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.included(base)
|
20
|
+
base.extend(ClassMethods)
|
21
|
+
base.converts_swfs :with => Engine::Alphize
|
22
|
+
end
|
23
|
+
|
24
|
+
class InvalidOptions < RuntimeError; end
|
25
|
+
end
|
26
|
+
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'swf_converter'
|
2
|
+
|
3
|
+
require 'swf_converter/engine/alphize'
|
4
|
+
|
5
|
+
module SwfConverter
|
6
|
+
class Engine
|
7
|
+
attr_accessor :parent
|
8
|
+
attr_reader :options
|
9
|
+
|
10
|
+
def initialize
|
11
|
+
@options = {}
|
12
|
+
end
|
13
|
+
|
14
|
+
def options=(new_options)
|
15
|
+
validate_options!(new_options) if respond_to?(:validate_options!)
|
16
|
+
@options = new_options
|
17
|
+
end
|
18
|
+
|
19
|
+
def convert!(swf_parent)
|
20
|
+
raise NotImplementedError, "SwfConverter::Engine#convert! has no defined behavior. Subclass it and define your own."
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
@@ -0,0 +1,132 @@
|
|
1
|
+
require 'fileutils'
|
2
|
+
require 'shellwords'
|
3
|
+
require 'tempfile'
|
4
|
+
|
5
|
+
require 'swf_converter/engine'
|
6
|
+
require 'swf_converter/engine/alphize/blender'
|
7
|
+
require 'swf_converter/engine/alphize/runner'
|
8
|
+
|
9
|
+
module SwfConverter
|
10
|
+
class Engine
|
11
|
+
class Alphize < Engine
|
12
|
+
SWF_PATHS = {}.tap do |paths|
|
13
|
+
[:black, :white].each do |type|
|
14
|
+
paths[type] = File.expand_path("../alphize/swfs/#{type}.swf", __FILE__)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
include Runner
|
19
|
+
|
20
|
+
def initialize
|
21
|
+
@output_images = {}
|
22
|
+
end
|
23
|
+
|
24
|
+
def convert!(swf_parent)
|
25
|
+
images = {
|
26
|
+
:black => Tempfile.open('swf_converter_alphize_black.png'),
|
27
|
+
:white => Tempfile.open('swf_converter_alphize_white.png')
|
28
|
+
}
|
29
|
+
begin
|
30
|
+
write_opaque_images(swf_parent, images)
|
31
|
+
blend(swf_parent, images)
|
32
|
+
if swf_parent.respond_to?(:after_swf_conversion)
|
33
|
+
swf_parent.after_swf_conversion(@output_images)
|
34
|
+
end
|
35
|
+
ensure
|
36
|
+
images[:black].close!
|
37
|
+
images[:white].close!
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
protected
|
42
|
+
|
43
|
+
def write_opaque_images(swf_parent, images)
|
44
|
+
raw = Tempfile.open 'swf_converter_alphize_raw'
|
45
|
+
raw_path = e(raw.path)
|
46
|
+
size = @options[:size]
|
47
|
+
unless size
|
48
|
+
raise ":size option must be set to the original SWF dimensions"
|
49
|
+
end
|
50
|
+
# Each RGBA pixel takes a byte, so the filesize of one frame is the
|
51
|
+
# number of pixels (width * height) times the number of channels (4)
|
52
|
+
frame_filesize = size[0] * size[1] * 4
|
53
|
+
begin
|
54
|
+
images.each do |type, image|
|
55
|
+
wrapper_swf = e(SWF_PATHS[type])
|
56
|
+
params = e("FlashVars=includeSWF=file://#{swf_parent.local_swf_path}")
|
57
|
+
image_path = e(image.path)
|
58
|
+
run "create raw SWF dump on #{type}",
|
59
|
+
"dump-gnash #{wrapper_swf} -P #{params} " +
|
60
|
+
"-D #{raw_path} --max-advances 1 -j #{size[0]} -k #{size[1]} > /dev/null"
|
61
|
+
run "create opaque image from raw on #{type}",
|
62
|
+
"tail -c #{frame_filesize} #{raw_path} | convert -size #{size[0]}x#{size[1]} -depth 8 rgba:- " +
|
63
|
+
"-separate -swap 0,2 -combine png:#{image_path}"
|
64
|
+
end
|
65
|
+
ensure
|
66
|
+
raw.close!
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
def blend(swf_parent, images)
|
71
|
+
begin
|
72
|
+
blender = Blender.new(images)
|
73
|
+
if @options[:output_sizes]
|
74
|
+
blend_and_resize(swf_parent, blender)
|
75
|
+
else
|
76
|
+
output_path = prepare_path(swf_parent.swf_image_path)
|
77
|
+
blender.blend! output_path
|
78
|
+
@output_images[@options[:size]] = output_path
|
79
|
+
end
|
80
|
+
rescue Exception => e
|
81
|
+
raise ConversionError, "Could not blend opaque images: #{e.class}: #{e.message}", e.backtrace
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
def blend_and_resize(swf_parent, blender)
|
86
|
+
original_image = Tempfile.new('swf_converter_alphize_original.png')
|
87
|
+
original_path = original_image.path
|
88
|
+
begin
|
89
|
+
blender.blend! original_path
|
90
|
+
@options[:output_sizes].each do |size|
|
91
|
+
resize(swf_parent, size, original_path)
|
92
|
+
end
|
93
|
+
ensure
|
94
|
+
original_image.close!
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
def prepare_path(path)
|
99
|
+
FileUtils.mkdir_p(File.dirname(path))
|
100
|
+
path
|
101
|
+
end
|
102
|
+
|
103
|
+
def resize(swf_parent, size, original_path)
|
104
|
+
output_path = prepare_path(swf_parent.swf_image_path(size))
|
105
|
+
run "resize #{original_path} to #{size} at #{output_path}",
|
106
|
+
"convert #{original_path} -resize #{size[0]}x#{size[1]} #{output_path}"
|
107
|
+
@output_images[size] = output_path
|
108
|
+
end
|
109
|
+
|
110
|
+
def validate_options!(options)
|
111
|
+
if options[:size]
|
112
|
+
validate_size(options[:size], ":size option")
|
113
|
+
end
|
114
|
+
|
115
|
+
if options[:output_sizes]
|
116
|
+
options[:output_sizes].each_with_index do |size, n|
|
117
|
+
validate_size(size, "Element #{n} of :output_sizes option")
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
def validate_size(size, description)
|
123
|
+
unless size.is_a?(Array) && size.size == 2
|
124
|
+
raise ArgumentError, "#{description} must be a 2-dimensional array, but was #{size}"
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
class ConversionError < StandardError;end
|
129
|
+
end
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
@@ -0,0 +1,80 @@
|
|
1
|
+
require 'swf_converter/engine/alphize/runner'
|
2
|
+
|
3
|
+
module SwfConverter
|
4
|
+
class Engine
|
5
|
+
class Alphize < Engine
|
6
|
+
TEMP_NAMES = [:negative, :alpha, :division]
|
7
|
+
|
8
|
+
class Blender
|
9
|
+
include Runner
|
10
|
+
|
11
|
+
def initialize(images)
|
12
|
+
@originals = images
|
13
|
+
end
|
14
|
+
|
15
|
+
def blend!(output_path)
|
16
|
+
# The strategy here is based on the following principle:
|
17
|
+
# original_image.alpha == (CHANNEL_MAX - image_on_white.red) + image_on_black.red
|
18
|
+
# (Applies to blue and green, too. Derived from the formulas applied
|
19
|
+
# by the original composition; not too hard to work out.)
|
20
|
+
# So, we will first get a grayscale version of an alpha mask by
|
21
|
+
# negating the image-on-white (create_negative!), then add it to the
|
22
|
+
# image-on-black to get the grayscale alpha mask (create_alpha!).
|
23
|
+
# The alpha mask image has white where the original image is opaque,
|
24
|
+
# and black where it is fully transparent, and gray where it is
|
25
|
+
# partially transparent. Once we have that image, since the RGB
|
26
|
+
# values in image-on-black were found by multiplying by the alpha
|
27
|
+
# value, we divide image-on-black by the grayscale alpha mask to get
|
28
|
+
# an opaque version of the image with the correct colors
|
29
|
+
# (create_division!), then apply that grayscale image as an alpha
|
30
|
+
# mask to save the final image (create_final!).
|
31
|
+
with_temps do |temps|
|
32
|
+
create_negative!(temps)
|
33
|
+
create_alpha!(temps)
|
34
|
+
create_division!(temps)
|
35
|
+
create_final!(output_path, temps)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
protected
|
40
|
+
|
41
|
+
def create_alpha!(temps)
|
42
|
+
run "create alpha mask for blending",
|
43
|
+
"convert #{@originals[:black].path} #{temps[:negative].path} " +
|
44
|
+
"-alpha Off -compose Plus -composite #{temps[:alpha].path}"
|
45
|
+
end
|
46
|
+
|
47
|
+
def create_division!(temps)
|
48
|
+
run "create division image for blending",
|
49
|
+
"composite #{@originals[:black].path} #{temps[:alpha].path} " +
|
50
|
+
"-alpha Off -channel RGB -compose Divide #{temps[:division].path}"
|
51
|
+
end
|
52
|
+
|
53
|
+
def create_final!(output_path, temps)
|
54
|
+
run "create final image for blending",
|
55
|
+
"convert #{temps[:division].path} #{temps[:alpha].path} " +
|
56
|
+
"-compose CopyOpacity -composite #{output_path}"
|
57
|
+
end
|
58
|
+
|
59
|
+
def create_negative!(temps)
|
60
|
+
run "create negative image for blending",
|
61
|
+
"convert #{@originals[:white].path} " +
|
62
|
+
"-alpha Off -channel RGB -negate #{temps[:negative].path}"
|
63
|
+
end
|
64
|
+
|
65
|
+
def with_temps
|
66
|
+
temps = (TEMP_NAMES.inject({}) do |hash, name|
|
67
|
+
hash[name] = Tempfile.open ["swf_converter_alphize_blender_#{name}", '.png']
|
68
|
+
hash
|
69
|
+
end)
|
70
|
+
begin
|
71
|
+
yield(temps)
|
72
|
+
ensure
|
73
|
+
temps.each { |name, temp| temp.close! }
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module SwfConverter
|
2
|
+
class Engine
|
3
|
+
class Alphize < Engine
|
4
|
+
module Runner
|
5
|
+
def e(*args)
|
6
|
+
Shellwords.escape(*args)
|
7
|
+
end
|
8
|
+
|
9
|
+
def run(description, command)
|
10
|
+
unless system(command)
|
11
|
+
raise ConversionError, "Failed to #{description}: #{command.inspect}"
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
Binary file
|
@@ -0,0 +1,20 @@
|
|
1
|
+
class Preview extends MovieClip {
|
2
|
+
var mytf:TextField;
|
3
|
+
|
4
|
+
function Preview(scope:MovieClip) {
|
5
|
+
var mc:MovieClip = scope.createEmptyMovieClip("mc", scope.getNextHighestDepth());
|
6
|
+
var my_listener:Object = new Object();
|
7
|
+
|
8
|
+
my_listener.onLoadComplete = function(target_mc:MovieClip) {
|
9
|
+
mc.opaqueBackground = 0x0000FF;
|
10
|
+
}
|
11
|
+
|
12
|
+
var my_loader:MovieClipLoader = new MovieClipLoader();
|
13
|
+
my_loader.addListener(my_listener);
|
14
|
+
my_loader.loadClip(scope.includeSWF, mc);
|
15
|
+
}
|
16
|
+
|
17
|
+
function onLoad() {
|
18
|
+
var preview:Preview = new Preview(_root);
|
19
|
+
}
|
20
|
+
}
|
@@ -0,0 +1,13 @@
|
|
1
|
+
<?xml version="1.0" encoding="utf-8" ?>
|
2
|
+
<movie width="600" height="600" framerate="12">
|
3
|
+
<background color="#000000"/>
|
4
|
+
<clip import="classes.swf" />
|
5
|
+
|
6
|
+
<frame>
|
7
|
+
<library>
|
8
|
+
<clip id="app" class="Preview" />
|
9
|
+
</library>
|
10
|
+
|
11
|
+
<place id="app" name="myApp" depth="0" height="500" width="500" x="0" y="0" />
|
12
|
+
</frame>
|
13
|
+
</movie>
|
Binary file
|
@@ -0,0 +1,13 @@
|
|
1
|
+
<?xml version="1.0" encoding="utf-8" ?>
|
2
|
+
<movie width="600" height="600" framerate="12">
|
3
|
+
<background color="#FFFFFF"/>
|
4
|
+
<clip import="classes.swf" />
|
5
|
+
|
6
|
+
<frame>
|
7
|
+
<library>
|
8
|
+
<clip id="app" class="Preview" />
|
9
|
+
</library>
|
10
|
+
|
11
|
+
<place id="app" name="myApp" depth="0" height="500" width="500" x="0" y="0" />
|
12
|
+
</frame>
|
13
|
+
</movie>
|
Binary file
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,60 @@
|
|
1
|
+
$:.unshift File.expand_path('..', __FILE__)
|
2
|
+
|
3
|
+
require 'swf_converter/engine'
|
4
|
+
|
5
|
+
class Swf
|
6
|
+
include SwfConverter
|
7
|
+
end
|
8
|
+
|
9
|
+
class OtherSwf
|
10
|
+
include SwfConverter
|
11
|
+
end
|
12
|
+
|
13
|
+
class VanillaSwf
|
14
|
+
include SwfConverter
|
15
|
+
end
|
16
|
+
|
17
|
+
class DummyEngine < SwfConverter::Engine; end
|
18
|
+
class OtherDummyEngine < SwfConverter::Engine; end
|
19
|
+
|
20
|
+
class ValidatingEngine < SwfConverter::Engine
|
21
|
+
def validate_options!(new_options)
|
22
|
+
unless new_options[:sizes]
|
23
|
+
raise SwfConverter::InvalidOptions, "CustomEngine requires sizes option"
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
class SupposedlyConvertingEngine < SwfConverter::Engine
|
29
|
+
def convert!(swf_parent)
|
30
|
+
# supposedly convert
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
RSpec::Matchers.define :match_image do |file2|
|
35
|
+
require 'RMagick'
|
36
|
+
|
37
|
+
match do |file1|
|
38
|
+
signatures = [file1, file2].map do |file_or_path|
|
39
|
+
is_file = file_or_path.is_a? File
|
40
|
+
if is_file
|
41
|
+
file = file_or_path
|
42
|
+
else
|
43
|
+
file = File.open(file_or_path, 'r')
|
44
|
+
end
|
45
|
+
|
46
|
+
image = Magick::Image::from_blob(file.read)[0]
|
47
|
+
file.close unless is_file
|
48
|
+
signature = image.signature
|
49
|
+
image.destroy!
|
50
|
+
signature
|
51
|
+
end
|
52
|
+
|
53
|
+
signatures[0] == signatures[1]
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
def example_path(subpath)
|
58
|
+
File.expand_path(File.join('..', '..', 'examples', subpath), __FILE__)
|
59
|
+
end
|
60
|
+
|
@@ -0,0 +1,126 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'swf_converter/engine/alphize'
|
3
|
+
|
4
|
+
require 'tempfile'
|
5
|
+
require 'tmpdir'
|
6
|
+
|
7
|
+
describe SwfConverter::Engine::Alphize do
|
8
|
+
before(:each) do
|
9
|
+
@engine = SwfConverter::Engine::Alphize.new
|
10
|
+
end
|
11
|
+
|
12
|
+
describe "size option" do
|
13
|
+
it "should be settable" do
|
14
|
+
@engine.options = {:size => [300, 500]}
|
15
|
+
@engine.options[:size].should == [300, 500]
|
16
|
+
end
|
17
|
+
|
18
|
+
it "should require a 2-dimensional array" do
|
19
|
+
lambda { @engine.options = {:size => [300, 300]} }.should_not raise_error
|
20
|
+
lambda { @engine.options = {:size => [7, 8]} }.should_not raise_error
|
21
|
+
lambda { @engine.options = {:size => 300} }.should raise_error
|
22
|
+
lambda { @engine.options = {:size => [300]} }.should raise_error
|
23
|
+
lambda { @engine.options = {:size => [300, 300, 300]} }.should raise_error
|
24
|
+
lambda { @engine.options = {:size => [300, 300, 300, 300]} }.should raise_error
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
describe "output_sizes option" do
|
29
|
+
it "should be settable" do
|
30
|
+
@engine.options = {:output_sizes => [[300, 300]]}
|
31
|
+
@engine.options[:output_sizes].should == [[300, 300]]
|
32
|
+
end
|
33
|
+
|
34
|
+
it "should require all elements to be 2-dimensional arrays" do
|
35
|
+
lambda { @engine.options = {:output_sizes => [[300, 300]]} }.should_not raise_error
|
36
|
+
lambda { @engine.options = {:output_sizes => [[300, 300], [7, 8]]} }.should_not raise_error
|
37
|
+
lambda { @engine.options = {:output_sizes => [[300, 300], [7, 8], [1026, 1993]]} }.should_not raise_error
|
38
|
+
lambda { @engine.options = {:output_sizes => 300} }.should raise_error
|
39
|
+
lambda { @engine.options = {:output_sizes => [300]} }.should raise_error
|
40
|
+
lambda { @engine.options = {:output_sizes => [[300]]} }.should raise_error
|
41
|
+
lambda { @engine.options = {:output_sizes => [300, 300]} }.should raise_error
|
42
|
+
lambda { @engine.options = {:output_sizes => [[150, 150], [300]]} }.should raise_error
|
43
|
+
lambda { @engine.options = {:output_sizes => [[300, 300], [150, 150], [10, 26, 1993]]} }.should raise_error
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
describe "with a size of 600x600 set" do
|
48
|
+
before(:each) do
|
49
|
+
@engine.options = {:size => [600, 600]}
|
50
|
+
end
|
51
|
+
|
52
|
+
it "should convert the balloon to a single 600x600 image" do
|
53
|
+
output_file = Tempfile.new 'balloon.png'
|
54
|
+
begin
|
55
|
+
parent = mock('balloon', :local_swf_path => example_path('balloon.swf'),
|
56
|
+
:swf_image_path => output_file.path)
|
57
|
+
@engine.convert! parent
|
58
|
+
output_file.should match_image(example_path('balloon.png'))
|
59
|
+
ensure
|
60
|
+
output_file.close!
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
it "should create the destination directory for the balloon if does not exist" do
|
65
|
+
dir = File.join(Dir.tmpdir, 'swf_converter_alphize_spec_tmpdir')
|
66
|
+
Dir.delete(dir) if Dir.exist?(dir)
|
67
|
+
output_file_path = File.join(dir, 'balloon.png')
|
68
|
+
output_file = nil
|
69
|
+
begin
|
70
|
+
parent = mock('balloon', :local_swf_path => example_path('balloon.swf'),
|
71
|
+
:swf_image_path => output_file_path)
|
72
|
+
@engine.convert! parent
|
73
|
+
output_file = File.open(output_file_path)
|
74
|
+
output_file.should match_image(example_path('balloon.png'))
|
75
|
+
ensure
|
76
|
+
File.delete(output_file_path) if File.exist?(output_file_path)
|
77
|
+
Dir.delete(dir) if Dir.exist?(dir)
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
it "should convert the rainy day to a single 600x600 image" do
|
82
|
+
output_file = Tempfile.new 'rainy_day.png'
|
83
|
+
begin
|
84
|
+
parent = mock('rainy_day', :local_swf_path => example_path('rainy_day.swf'),
|
85
|
+
:swf_image_path => output_file.path)
|
86
|
+
@engine.convert! parent
|
87
|
+
output_file.should match_image(example_path('rainy_day.png'))
|
88
|
+
ensure
|
89
|
+
output_file.close!
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
describe "and 80x80 and 150x150 output sizes set" do
|
94
|
+
before(:each) do
|
95
|
+
@engine.options[:output_sizes] = [
|
96
|
+
[80, 80],
|
97
|
+
[150, 150]
|
98
|
+
]
|
99
|
+
|
100
|
+
@thumbnails = {
|
101
|
+
80 => Tempfile.new('balloon80.png'),
|
102
|
+
150 => Tempfile.new('balloon150.png')
|
103
|
+
}
|
104
|
+
|
105
|
+
@parent = mock('balloon_thumbnails', :local_swf_path => example_path('balloon.swf'))
|
106
|
+
@parent.stub!(:swf_image_path).with([80, 80]).and_return(@thumbnails[80].path)
|
107
|
+
@parent.stub!(:swf_image_path).with([150, 150]).and_return(@thumbnails[150].path)
|
108
|
+
end
|
109
|
+
|
110
|
+
it "should convert the balloon to 80x80 and 150x150 thumbnails" do
|
111
|
+
@engine.convert! @parent
|
112
|
+
@thumbnails[80].should match_image(example_path('balloon/80x80.png'))
|
113
|
+
@thumbnails[150].should match_image(example_path('balloon/150x150.png'))
|
114
|
+
end
|
115
|
+
|
116
|
+
it "should run an after hook if set" do
|
117
|
+
@parent.should_receive(:after_swf_conversion).with({
|
118
|
+
[80, 80] => @thumbnails[80].path,
|
119
|
+
[150, 150] => @thumbnails[150].path
|
120
|
+
})
|
121
|
+
@engine.convert! @parent
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
@@ -0,0 +1,40 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'swf_converter/engine'
|
3
|
+
|
4
|
+
describe SwfConverter::Engine do
|
5
|
+
describe "#options" do
|
6
|
+
it "should return the options set" do
|
7
|
+
engine = SwfConverter::Engine.new
|
8
|
+
engine.options = {:foo => :bar}
|
9
|
+
engine.options.should == {:foo => :bar}
|
10
|
+
end
|
11
|
+
|
12
|
+
it "should allow a subclass to validate options on set" do
|
13
|
+
lambda {
|
14
|
+
engine = ValidatingEngine.new
|
15
|
+
engine.options = {:foo => :bar}
|
16
|
+
}.should raise_error(SwfConverter::InvalidOptions)
|
17
|
+
|
18
|
+
lambda {
|
19
|
+
engine = ValidatingEngine.new
|
20
|
+
engine.options = {:foo => :bar, :sizes => [150, 300]}
|
21
|
+
}.should_not raise_error
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
describe "#convert!" do
|
26
|
+
it "should raise an error if not implemented by subclass" do
|
27
|
+
parent = mock('engine_conversion_parent')
|
28
|
+
|
29
|
+
lambda {
|
30
|
+
engine = SwfConverter::Engine.new
|
31
|
+
engine.convert!(parent)
|
32
|
+
}.should raise_error(NotImplementedError)
|
33
|
+
|
34
|
+
lambda {
|
35
|
+
engine = SupposedlyConvertingEngine.new
|
36
|
+
engine.convert!(parent)
|
37
|
+
}.should_not raise_error
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'swf_converter'
|
3
|
+
|
4
|
+
describe SwfConverter do
|
5
|
+
it "should have alphize set by default" do
|
6
|
+
VanillaSwf.swf_conversion_engine.should be_a SwfConverter::Engine::Alphize
|
7
|
+
end
|
8
|
+
|
9
|
+
it "should allow class to set its own engine" do
|
10
|
+
Swf.converts_swfs :with => DummyEngine
|
11
|
+
OtherSwf.converts_swfs :with => OtherDummyEngine
|
12
|
+
|
13
|
+
Swf.swf_conversion_engine.should be_a DummyEngine
|
14
|
+
OtherSwf.swf_conversion_engine.should be_a OtherDummyEngine
|
15
|
+
end
|
16
|
+
|
17
|
+
it "should allow class to set options" do
|
18
|
+
Swf.converts_swfs :with => DummyEngine, :foo => :bar
|
19
|
+
Swf.swf_conversion_engine.options.should == {:foo => :bar}
|
20
|
+
end
|
21
|
+
|
22
|
+
describe "#convert_swf!" do
|
23
|
+
it "should call engine#convert" do
|
24
|
+
engine_class = mock('swf_engine_requiring_conversion_class')
|
25
|
+
engine = mock('swf_engine_requiring_conversion')
|
26
|
+
engine.stub!(:options=)
|
27
|
+
engine_class.stub!(:new).and_return(engine)
|
28
|
+
Swf.converts_swfs :with => engine_class
|
29
|
+
swf = Swf.new
|
30
|
+
engine.should_receive(:convert!).with(swf)
|
31
|
+
swf.convert_swf!
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
@@ -0,0 +1,12 @@
|
|
1
|
+
Gem::Specification.new do |s|
|
2
|
+
s.name = 'swf_converter'
|
3
|
+
s.version = '0.0.3'
|
4
|
+
s.platform = Gem::Platform::RUBY
|
5
|
+
s.author = 'Matchu'
|
6
|
+
s.email = ['matchu1993@gmail.com']
|
7
|
+
s.summary = 'Converts SWFs to PNGs'
|
8
|
+
s.description = "Include SwfConverter on a class to get #convert_swf!, which writes PNGs from that object's SWF file. Work in progress."
|
9
|
+
s.require_path = 'lib'
|
10
|
+
s.files = `git ls-files`.split("\n")
|
11
|
+
end
|
12
|
+
|
metadata
ADDED
@@ -0,0 +1,82 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: swf_converter
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease:
|
5
|
+
version: 0.0.3
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Matchu
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
|
13
|
+
date: 2011-05-22 00:00:00 -04:00
|
14
|
+
default_executable:
|
15
|
+
dependencies: []
|
16
|
+
|
17
|
+
description: "Include SwfConverter on a class to get #convert_swf!, which writes PNGs from that object's SWF file. Work in progress."
|
18
|
+
email:
|
19
|
+
- matchu1993@gmail.com
|
20
|
+
executables: []
|
21
|
+
|
22
|
+
extensions: []
|
23
|
+
|
24
|
+
extra_rdoc_files: []
|
25
|
+
|
26
|
+
files:
|
27
|
+
- Gemfile
|
28
|
+
- autotest/discover.rb
|
29
|
+
- check_memory.rb
|
30
|
+
- examples/balloon.png
|
31
|
+
- examples/balloon.swf
|
32
|
+
- examples/balloon/150x150.png
|
33
|
+
- examples/balloon/80x80.png
|
34
|
+
- examples/rainy_day.png
|
35
|
+
- examples/rainy_day.swf
|
36
|
+
- lib/swf_converter.rb
|
37
|
+
- lib/swf_converter/engine.rb
|
38
|
+
- lib/swf_converter/engine/alphize.rb
|
39
|
+
- lib/swf_converter/engine/alphize/blender.rb
|
40
|
+
- lib/swf_converter/engine/alphize/runner.rb
|
41
|
+
- lib/swf_converter/engine/alphize/swfs/black.swf
|
42
|
+
- lib/swf_converter/engine/alphize/swfs/src/Preview.as
|
43
|
+
- lib/swf_converter/engine/alphize/swfs/src/black.xml
|
44
|
+
- lib/swf_converter/engine/alphize/swfs/src/build.sh
|
45
|
+
- lib/swf_converter/engine/alphize/swfs/src/classes.swf
|
46
|
+
- lib/swf_converter/engine/alphize/swfs/src/white.xml
|
47
|
+
- lib/swf_converter/engine/alphize/swfs/white.swf
|
48
|
+
- spec/spec_helper.rb
|
49
|
+
- spec/swf_converter/engine/alphize_spec.rb
|
50
|
+
- spec/swf_converter/engine_spec.rb
|
51
|
+
- spec/swf_converter_spec.rb
|
52
|
+
- swf_converter.gemspec
|
53
|
+
has_rdoc: true
|
54
|
+
homepage:
|
55
|
+
licenses: []
|
56
|
+
|
57
|
+
post_install_message:
|
58
|
+
rdoc_options: []
|
59
|
+
|
60
|
+
require_paths:
|
61
|
+
- lib
|
62
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
63
|
+
none: false
|
64
|
+
requirements:
|
65
|
+
- - ">="
|
66
|
+
- !ruby/object:Gem::Version
|
67
|
+
version: "0"
|
68
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
69
|
+
none: false
|
70
|
+
requirements:
|
71
|
+
- - ">="
|
72
|
+
- !ruby/object:Gem::Version
|
73
|
+
version: "0"
|
74
|
+
requirements: []
|
75
|
+
|
76
|
+
rubyforge_project:
|
77
|
+
rubygems_version: 1.6.2
|
78
|
+
signing_key:
|
79
|
+
specification_version: 3
|
80
|
+
summary: Converts SWFs to PNGs
|
81
|
+
test_files: []
|
82
|
+
|