pixel_curtain 0.0.3 → 0.0.12
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile +1 -3
- data/bin/pixel_curtain +4 -3
- data/lib/pixel_curtain.rb +4 -4
- data/lib/pixel_curtain/complex_curtain.rb +3 -0
- data/lib/pixel_curtain/curtain.rb +44 -21
- data/lib/pixel_curtain/simple_curtain.rb +31 -0
- data/lib/pixel_curtain/version.rb +1 -1
- data/pixel_curtain.gemspec +2 -0
- metadata +32 -5
- data/lib/pixel_curtain/image.rb +0 -23
data/Gemfile
CHANGED
data/bin/pixel_curtain
CHANGED
@@ -4,11 +4,12 @@ dir = File.expand_path(File.dirname(__FILE__))
|
|
4
4
|
require dir + '/../lib/pixel_curtain'
|
5
5
|
|
6
6
|
input_file = ARGV[0]
|
7
|
+
output_file = "#{File.basename(input_file, ".*")}-output.png"
|
7
8
|
|
8
9
|
if input_file.nil?
|
9
10
|
puts "input file required"
|
10
11
|
else
|
11
|
-
curtain = PixelCurtain::
|
12
|
-
curtain.process(20)
|
13
|
-
curtain.save(
|
12
|
+
curtain = PixelCurtain::SimpleCurtain.new(input_file)
|
13
|
+
curtain.process(:number_of_divisions => rand(20)+5)
|
14
|
+
curtain.save(output_file)
|
14
15
|
end
|
data/lib/pixel_curtain.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
|
-
require 'chunky_png'
|
2
|
-
|
3
1
|
dir = File.expand_path(File.dirname(__FILE__))
|
2
|
+
require dir + '/pixel_curtain/curtain'
|
3
|
+
require dir + '/pixel_curtain/simple_curtain'
|
4
|
+
require dir + '/pixel_curtain/complex_curtain'
|
4
5
|
|
5
|
-
|
6
|
-
require dir + '/pixel_curtain/curtain'
|
6
|
+
PixelCurtain::SimpleCurtain
|
@@ -1,30 +1,53 @@
|
|
1
|
-
|
1
|
+
require 'rubygems'
|
2
|
+
require 'RMagick'
|
3
|
+
|
4
|
+
module PixelCurtain
|
2
5
|
class Curtain
|
3
|
-
|
4
|
-
|
5
|
-
@
|
6
|
+
include Magick
|
7
|
+
def initialize(file_path)
|
8
|
+
@source_image = Image.read(file_path).first
|
9
|
+
@output = Image.new(1440,900)
|
6
10
|
end
|
7
11
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
number_of_divisions = @source_image.dimension.width
|
12
|
-
end
|
13
|
-
|
14
|
-
source_division_size = @source_image.dimension.width / number_of_divisions
|
15
|
-
destination_division_size = @output.dimension.width / number_of_divisions
|
16
|
-
|
17
|
-
(0...number_of_divisions).each do |x|
|
18
|
-
avgPixel = @source_image.crop(source_division_size*x,0,
|
19
|
-
source_division_size,@source_image.dimension.height).average_pixel
|
20
|
-
@output.setPixelBlock(x*destination_division_size,0,@output.dimension.height,destination_division_size,avgPixel)
|
21
|
-
end
|
22
|
-
@output
|
12
|
+
# Do nothing, this is to be implemented by subclasses
|
13
|
+
def process(options = {})
|
14
|
+
@output
|
23
15
|
end
|
24
16
|
|
25
|
-
def save(file_name)
|
26
|
-
|
17
|
+
def save(file_name, options = {})
|
18
|
+
|
19
|
+
options[:temp_file] = false if options[:temp_file].nil?
|
20
|
+
|
21
|
+
if options[:temp_file]
|
22
|
+
output_file = Tempfile.new(['pixel_curtain', 'png'])
|
23
|
+
else
|
24
|
+
output_file = File.new(file_name, 'w')
|
25
|
+
end
|
26
|
+
|
27
|
+
@output.write("png:" + output_file.path)
|
28
|
+
|
29
|
+
return output_file
|
27
30
|
end
|
28
31
|
|
32
|
+
private
|
33
|
+
|
34
|
+
def average_color(image)
|
35
|
+
total = 0
|
36
|
+
avg = { :r => 0.0, :g => 0.0, :b => 0.0 }
|
37
|
+
|
38
|
+
image.quantize.color_histogram.each do |c,n|
|
39
|
+
avg[:r] += n * c.red
|
40
|
+
avg[:g] += n * c.green
|
41
|
+
avg[:b] += n * c.blue
|
42
|
+
total += n
|
43
|
+
end
|
44
|
+
|
45
|
+
avg.each_key do |c|
|
46
|
+
avg[c] /= total
|
47
|
+
avg[c] = (avg[c] / QuantumRange * 255).to_i
|
48
|
+
end
|
49
|
+
|
50
|
+
return "rgb(#{avg[:r]},#{avg[:g]},#{avg[:b]})"
|
51
|
+
end
|
29
52
|
end
|
30
53
|
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module PixelCurtain
|
2
|
+
class SimpleCurtain < Curtain
|
3
|
+
def process(options = {})
|
4
|
+
|
5
|
+
if options[:number_of_divisions].nil?
|
6
|
+
number_of_divisions = 10
|
7
|
+
else
|
8
|
+
number_of_divisions = options[:number_of_divisions]
|
9
|
+
end
|
10
|
+
|
11
|
+
if (number_of_divisions > @source_image.columns)
|
12
|
+
number_of_divisions = @source_image.columns
|
13
|
+
end
|
14
|
+
|
15
|
+
source_division_size = @source_image.columns / number_of_divisions
|
16
|
+
destination_division_size = @output.columns / number_of_divisions
|
17
|
+
|
18
|
+
gc = Draw.new
|
19
|
+
|
20
|
+
(0...number_of_divisions).each do |x|
|
21
|
+
avgPixel = average_color(@source_image.crop(source_division_size*x,0,
|
22
|
+
source_division_size,@source_image.rows))
|
23
|
+
gc.fill(avgPixel)
|
24
|
+
gc.rectangle(x*destination_division_size,0,x*destination_division_size+destination_division_size,@output.rows)
|
25
|
+
gc.draw(@output)
|
26
|
+
end
|
27
|
+
|
28
|
+
@output
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
data/pixel_curtain.gemspec
CHANGED
@@ -18,4 +18,6 @@ Gem::Specification.new do |s|
|
|
18
18
|
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
19
19
|
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
20
20
|
s.require_paths = ["lib"]
|
21
|
+
s.add_dependency(%q<rmagick>, [">= 2.12.2"])
|
22
|
+
|
21
23
|
end
|
metadata
CHANGED
@@ -1,8 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: pixel_curtain
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
+
hash: 7
|
4
5
|
prerelease:
|
5
|
-
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 0
|
9
|
+
- 12
|
10
|
+
version: 0.0.12
|
6
11
|
platform: ruby
|
7
12
|
authors:
|
8
13
|
- Nick Rowe
|
@@ -10,10 +15,25 @@ autorequire:
|
|
10
15
|
bindir: bin
|
11
16
|
cert_chain: []
|
12
17
|
|
13
|
-
date: 2011-
|
18
|
+
date: 2011-07-10 00:00:00 -07:00
|
14
19
|
default_executable:
|
15
|
-
dependencies:
|
16
|
-
|
20
|
+
dependencies:
|
21
|
+
- !ruby/object:Gem::Dependency
|
22
|
+
name: rmagick
|
23
|
+
prerelease: false
|
24
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ">="
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
hash: 59
|
30
|
+
segments:
|
31
|
+
- 2
|
32
|
+
- 12
|
33
|
+
- 2
|
34
|
+
version: 2.12.2
|
35
|
+
type: :runtime
|
36
|
+
version_requirements: *id001
|
17
37
|
description: Generate beautiful backgrounds from images
|
18
38
|
email:
|
19
39
|
- nixterrimus@dcxn.com
|
@@ -30,8 +50,9 @@ files:
|
|
30
50
|
- Rakefile
|
31
51
|
- bin/pixel_curtain
|
32
52
|
- lib/pixel_curtain.rb
|
53
|
+
- lib/pixel_curtain/complex_curtain.rb
|
33
54
|
- lib/pixel_curtain/curtain.rb
|
34
|
-
- lib/pixel_curtain/
|
55
|
+
- lib/pixel_curtain/simple_curtain.rb
|
35
56
|
- lib/pixel_curtain/version.rb
|
36
57
|
- pixel_curtain.gemspec
|
37
58
|
has_rdoc: true
|
@@ -48,12 +69,18 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
48
69
|
requirements:
|
49
70
|
- - ">="
|
50
71
|
- !ruby/object:Gem::Version
|
72
|
+
hash: 3
|
73
|
+
segments:
|
74
|
+
- 0
|
51
75
|
version: "0"
|
52
76
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
53
77
|
none: false
|
54
78
|
requirements:
|
55
79
|
- - ">="
|
56
80
|
- !ruby/object:Gem::Version
|
81
|
+
hash: 3
|
82
|
+
segments:
|
83
|
+
- 0
|
57
84
|
version: "0"
|
58
85
|
requirements: []
|
59
86
|
|
data/lib/pixel_curtain/image.rb
DELETED
@@ -1,23 +0,0 @@
|
|
1
|
-
class ChunkyPNG::Image
|
2
|
-
def average_pixel
|
3
|
-
# Sum the total R, G, and B pieces
|
4
|
-
ave = self.pixels.inject([0,0,0]) do |sum,element|
|
5
|
-
sum[0] += ChunkyPNG::Color.r(element)
|
6
|
-
sum[1] += ChunkyPNG::Color.g(element)
|
7
|
-
sum[2] += ChunkyPNG::Color.b(element)
|
8
|
-
sum
|
9
|
-
end
|
10
|
-
# Cache the pixel_count value for speed
|
11
|
-
pixel_count = self.pixels.count
|
12
|
-
# Return the average value of each component as a new Color
|
13
|
-
ChunkyPNG::Color.rgb(ave[0] / pixel_count, ave[1] / pixel_count, ave[2] / pixel_count)
|
14
|
-
end
|
15
|
-
|
16
|
-
def setPixelBlock(startX, startY, height, width, newPixel)
|
17
|
-
(startX...startX+width).each do |x|
|
18
|
-
(startY...startY+height).each do |y|
|
19
|
-
self[x,y] = newPixel
|
20
|
-
end
|
21
|
-
end
|
22
|
-
end
|
23
|
-
end
|