Class: Pixelart::Image
- Inherits:
-
Object
- Object
- Pixelart::Image
- Defined in:
- lib/pixelart/silhouette.rb,
lib/pixelart/led.rb,
lib/pixelart/blur.rb,
lib/pixelart/image.rb,
lib/pixelart/spots.rb,
lib/pixelart/circle.rb,
lib/pixelart/sketch.rb,
lib/pixelart/stripes.rb,
lib/pixelart/ukraine.rb,
lib/pixelart/transparent.rb
Overview
todo/check:
use a different name for silhouette
- why not - outline ???
or - shadow ???
or - profile ???
or - figure ???
or - shape ???
or - form ???
Direct Known Subclasses
Constant Summary collapse
- CHARS =
todo/check: rename to default chars or such? why? why not?
'.@xo^~%*+=:'
- PALETTE8BIT =
predefined palette8bit color maps
(grayscale to sepia/blue/false/etc.) - todo/check - keep "shortcut" convenience predefined map - why? why not?
{ sepia: Palette8bit::GRAYSCALE.zip( Palette8bit::SEPIA ).to_h, blue: Palette8bit::GRAYSCALE.zip( Palette8bit::BLUE ).to_h, false: Palette8bit::GRAYSCALE.zip( Palette8bit::FALSE ).to_h, }
- RAINBOW_RED =
todo/check: move colors to (reusable) constants int Color !!!! why? why not?
Color.parse( '#E40303' )
- RAINBOW_ORANGE =
Color.parse( '#FF8C00' )
- RAINBOW_YELLOW =
Color.parse( '#FFED00' )
- RAINBOW_GREEN =
Color.parse( '#008026' )
- RAINBOW_BLUE =
Color.parse( '#004DFF' )
- RAINBOW_VIOLET =
Color.parse( '#750787' )
- UKRAINE_BLUE =
todo/check: move colors to (reusable) constants int Color !!!! why? why not?
Color.parse( '#0057b7' )
- UKRAINE_YELLOW =
Color.parse( '#ffdd00' )
Class Method Summary collapse
- .calc_stripes(length, n: 2, debug: false) ⇒ Object
-
.parse(pixels, colors:, chars: CHARS) ⇒ Object
todo/check: support default chars encoding auto-of-the-box always or require user-defined chars to be passed in - why? why not?.
- .parse_colors(colors) ⇒ Object
-
.parse_pixels(pixels) ⇒ Object
helpers.
-
.read(path) ⇒ Object
convenience helper.
Instance Method Summary collapse
- #[](x, y) ⇒ Object
- #[]=(x, y, value) ⇒ Object
- #_change_colors!(img, color_map) ⇒ Object
- #_parse_color_map(color_map) ⇒ Object
-
#_parse_colors(colors) ⇒ Object
private helpers.
- #blur(blur = 2) ⇒ Object
-
#change_colors(color_map) ⇒ Object
(also: #recolor)
add replace_colors alias too? - why? why not?.
- #change_palette8bit(palette) ⇒ Object (also: #change_palette256)
- #circle ⇒ Object
- #compose!(other, x = 0, y = 0) ⇒ Object (also: #paste!)
- #crop(x, y, crop_width, crop_height) ⇒ Object
- #flip ⇒ Object (also: #flip_horizontally)
-
#grayscale ⇒ Object
(also: #greyscale)
filter / effects.
- #height ⇒ Object
-
#image ⇒ Object
return image ref - use a different name - why? why not? change to to_image - why? why not?.
-
#initialize(width, height, initial = Color::TRANSPARENT) ⇒ Image
constructor
A new instance of Image.
- #led(led = 8, spacing: 2, round_corner: false) ⇒ Object
- #mirror ⇒ Object (also: #flip_vertically, #flop)
- #pixels ⇒ Object
- #rainbow ⇒ Object (also: #pride)
-
#rotate_clockwise ⇒ Object
(also: #rotate_right)
90 degrees.
-
#rotate_counter_clockwise ⇒ Object
(also: #rotate_left)
90 degrees.
-
#save(path, constraints = {}) ⇒ Object
(also: #write)
(image) delegates todo/check: add some more??.
- #silhouette(color = '#000000') ⇒ Object
- #sketch(sketch = 4, line: 1) ⇒ Object
- #spots(spot = 10, spacing: 0, center: nil, radius: nil, background: nil, lightness: nil, odd: false) ⇒ Object
- #spots_hidef(spot = 10, spacing: 0, center: nil, radius: nil, background: nil, lightness: nil, odd: false) ⇒ Object (also: #spots_hd)
- #stripes_horizontal(*colors) ⇒ Object (also: #stripes)
- #transparent(style = :solid, fuzzy: false) ⇒ Object
- #ukraine ⇒ Object
- #width ⇒ Object
- #zoom(zoom = 2, spacing: 0) ⇒ Object (also: #scale)
Constructor Details
#initialize(width, height, initial = Color::TRANSPARENT) ⇒ Image
Returns a new instance of Image.
52 53 54 55 56 57 58 59 60 61 62 63 |
# File 'lib/pixelart/image.rb', line 52 def initialize( width, height, initial=Color::TRANSPARENT ) ### todo/fix: ## change params to *args only - why? why not? ## make width/height optional if image passed in? if initial.is_a?( ChunkyPNG::Image ) @img = initial else ## todo/check - initial - use parse_color here too e.g. allow "#fff" too etc. @img = ChunkyPNG::Image.new( width, height, initial ) end end |
Class Method Details
.calc_stripes(length, n: 2, debug: false) ⇒ Object
5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 |
# File 'lib/pixelart/stripes.rb', line 5 def self.calc_stripes( length, n: 2, debug: false ) stripes = [] base_step = length / n ## pixels per pixel err_step = (length % n) * 2 ## multiply by 2 denominator = n * 2 # denominator (in de - nenner e.g. 1/nenner 4/nenner) overflow = err_step*n/denominator ## todo/check - assert that div is always WITHOUT remainder!!!!! if debug puts puts "base_step (pixels per stripe):" puts " #{base_step} - #{base_step}px * #{n} = #{base_step*n}px" puts "err_step (in 1/#{length}*2):" puts " #{err_step} / #{denominator} - #{err_step*n} / #{denominator} = +#{err_step*n/denominator}px overflow" puts end err = 0 stripe = 0 n.times do |i| stripe = base_step err += err_step if err >= denominator ## overflow puts " -- overflow #{err}/#{denominator} - add +1 pixel to stripe #{i}" if debug stripe += 1 err -= denominator end puts " #{i} => #{stripe} -- #{err} / #{denominator}" if debug stripes[i] = stripe end ## note: assert calculation - sum of stripes MUST be equal length sum = stripes.sum puts " sum: #{sum}" if debug if sum != length puts "!! ERROR - stripes sum #{sum} calculation failed; expected #{length}:" pp stripes exit 1 end stripes end |
.parse(pixels, colors:, chars: CHARS) ⇒ Object
todo/check: support default chars encoding auto-of-the-box always
or require user-defined chars to be passed in - why? why not?
17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 |
# File 'lib/pixelart/image.rb', line 17 def self.parse( pixels, colors:, chars: CHARS ) has_keys = colors.is_a?(Hash) ## check if passed-in user-defined keys (via hash table)? colors = parse_colors( colors ) pixels = parse_pixels( pixels ) width = pixels.reduce(1) {|width,row| row.size > width ? row.size : width } height = pixels.size img = new( width, height ) pixels.each_with_index do |row,y| row.each_with_index do |color,x| pixel = if has_keys ## if passed-in user-defined keys check only the user-defined keys colors[color] else ## try map ascii art char (.@xo etc.) to color index (0,1,2) ## if no match found - fallback on assuming draw by number (0 1 2 etc.) encoding pos = chars.index( color ) if pos colors[ pos.to_s ] else ## assume nil (not found) colors[ color ] end end img[x,y] = pixel end # each row end # each data img end |
.parse_colors(colors) ⇒ Object
263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 |
# File 'lib/pixelart/image.rb', line 263 def self.parse_colors( colors ) if colors.is_a?( Array ) ## convenience shortcut ## note: always auto-add color 0 as pre-defined transparent - why? why not? h = { '0' => Color::TRANSPARENT } colors.each_with_index do |color, i| h[ (i+1).to_s ] = Color.parse( color ) end h else ## assume hash table with color map ## convert into ChunkyPNG::Color colors.map do |key,color| ## always convert key to string why? why not? use symbol? [ key.to_s, Color.parse( color ) ] end.to_h end end |
.parse_pixels(pixels) ⇒ Object
helpers
247 248 249 250 251 252 253 254 255 256 257 258 259 |
# File 'lib/pixelart/image.rb', line 247 def self.parse_pixels( pixels ) data = [] pixels.each_line do |line| line = line.strip next if line.start_with?( '#' ) || line.empty? ## note: allow comments and empty lines ## note: allow multiple spaces or tabs to separate pixel codes ## e.g. o o o o o o o o o o o o dg lg w w lg w lg lg dg dg w w lg dg o o o o o o o o o o o ## or data << line.split( /[ \t]+/) end data end |
.read(path) ⇒ Object
convenience helper
5 6 7 8 9 |
# File 'lib/pixelart/image.rb', line 5 def self.read( path ) ## convenience helper img_inner = ChunkyPNG::Image.from_file( path ) img = new( img_inner.width, img_inner.height, img_inner ) img end |
Instance Method Details
#[](x, y) ⇒ Object
230 |
# File 'lib/pixelart/image.rb', line 230 def []( x, y ) @img[x,y]; end |
#[]=(x, y, value) ⇒ Object
231 |
# File 'lib/pixelart/image.rb', line 231 def []=( x, y, value ) @img[x,y]=value; end |
#_change_colors!(img, color_map) ⇒ Object
194 195 196 197 198 199 200 201 202 |
# File 'lib/pixelart/image.rb', line 194 def _change_colors!( img, color_map ) img.width.times do |x| img.height.times do |y| color = img[x,y] new_color = color_map[color] img[x,y] = new_color if new_color end end end |
#_parse_color_map(color_map) ⇒ Object
188 189 190 191 192 |
# File 'lib/pixelart/image.rb', line 188 def _parse_color_map( color_map ) color_map.map do |k,v| [Color.parse(k), Color.parse(v)] end.to_h end |
#_parse_colors(colors) ⇒ Object
private helpers
184 185 186 |
# File 'lib/pixelart/image.rb', line 184 def _parse_colors( colors ) colors.map {|color| Color.parse( color ) } end |
#blur(blur = 2) ⇒ Object
5 6 7 8 9 10 11 12 13 14 15 |
# File 'lib/pixelart/blur.rb', line 5 def blur( blur=2 ) @img.save( MAGICK_INPUT ) MiniMagick::Tool::Magick.new do |magick| magick << MAGICK_INPUT magick.blur( "#{blur}x#{blur}" ) magick << MAGICK_OUTPUT end Image.read( MAGICK_OUTPUT ) end |
#change_colors(color_map) ⇒ Object Also known as: recolor
add replace_colors alias too? - why? why not?
139 140 141 142 143 144 145 146 147 |
# File 'lib/pixelart/image.rb', line 139 def change_colors( color_map ) color_map = _parse_color_map( color_map ) img = @img.dup ## note: make a deep copy!!! _change_colors!( img, color_map ) ## wrap into Pixelart::Image - lets you use zoom() and such Image.new( img.width, img.height, img ) end |
#change_palette8bit(palette) ⇒ Object Also known as: change_palette256
161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 |
# File 'lib/pixelart/image.rb', line 161 def change_palette8bit( palette ) ## step 0: mapping from grayscale to new 8bit palette (256 colors) color_map = if palette.is_a?( String ) || palette.is_a?( Symbol ) PALETTE8BIT[ palette.to_sym ] ## todo/fix: check for missing/undefined palette not found - why? why not? else ## make sure we have colors all in Integer not names, hex, etc. palette = _parse_colors( palette ) Palette8bit::GRAYSCALE.zip( palette ).to_h end ## step 1: convert to grayscale (256 colors) img = @img.grayscale _change_colors!( img, color_map ) ## wrap into Pixelart::Image - lets you use zoom() and such Image.new( img.width, img.height, img ) end |
#circle ⇒ Object
10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
# File 'lib/pixelart/circle.rb', line 10 def circle ### for radius use min of width / height r = [@img.width, @img.height].min / 2 center_x = width / 2 center_y = height / 2 ################ # try with 96x96 # center_x: 96 / 2 = 48 # center_y: 96 / 2 = 48 # # r: 96 / 2 = 48 img = Image.new( @img.width, @img.height ) @img.width.times do |x| @img.height.times do |y| ## change to float calcuation (instead of ints) - why? why not? xx, yy, rr = x - center_x, y - center_y, r img[ x, y] = if xx*xx+yy*yy < rr*rr @img[ x, y ] else 0 ## transparent - alpha(0) end end end img end |
#compose!(other, x = 0, y = 0) ⇒ Object Also known as: paste!
221 222 223 |
# File 'lib/pixelart/image.rb', line 221 def compose!( other, x=0, y=0 ) @img.compose!( other.image, x, y ) ## note: "unwrap" inner image ref end |
#crop(x, y, crop_width, crop_height) ⇒ Object
92 93 94 95 |
# File 'lib/pixelart/image.rb', line 92 def crop( x, y, crop_width, crop_height ) Image.new( nil, nil, image.crop( x,y, crop_width, crop_height ) ) end |
#flip ⇒ Object Also known as: flip_horizontally
110 111 112 113 |
# File 'lib/pixelart/image.rb', line 110 def flip img = @img.flip Image.new( img.width, img.height, img ) end |
#grayscale ⇒ Object Also known as: greyscale
filter / effects
102 103 104 105 |
# File 'lib/pixelart/image.rb', line 102 def grayscale img = @img.grayscale Image.new( img.width, img.height, img ) end |
#height ⇒ Object
228 |
# File 'lib/pixelart/image.rb', line 228 def height() @img.height; end |
#image ⇒ Object
return image ref - use a different name - why? why not?
change to to_image - why? why not?
240 |
# File 'lib/pixelart/image.rb', line 240 def image() @img; end |
#led(led = 8, spacing: 2, round_corner: false) ⇒ Object
5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
# File 'lib/pixelart/led.rb', line 5 def led( led=8, spacing: 2, round_corner: false ) width = @img.width*led + (@img.width-1)*spacing height = @img.height*led + (@img.height-1)*spacing puts " #{width}x#{height}" img = Image.new( width, height, Color::BLACK ) @img.width.times do |x| @img.height.times do |y| pixel = @img[x,y] pixel = Color::BLACK if pixel == Color::TRANSPARENT led.times do |n| led.times do |m| ## round a little - drop all four corners for now next if round_corner && [[0,0],[0,1],[1,0],[1,1],[0,2],[2,0], [0,led-1],[0,led-2],[1,led-1],[1,led-2],[0,led-3],[2,led-1], [led-1,0],[led-1,1],[led-2,0],[led-2,1],[led-1,2],[led-3,0], [led-1,led-1],[led-1,led-2],[led-2,led-1],[led-2,led-2],[led-1,led-3],[led-3,led-1], ].include?( [n,m] ) img[x*led+n + spacing*x, y*led+m + spacing*y] = pixel end end end end img end |
#mirror ⇒ Object Also known as: flip_vertically, flop
116 117 118 119 |
# File 'lib/pixelart/image.rb', line 116 def mirror img = @img.mirror Image.new( img.width, img.height, img ) end |
#pixels ⇒ Object
233 |
# File 'lib/pixelart/image.rb', line 233 def pixels() @img.pixels; end |
#rainbow ⇒ Object Also known as: pride
97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 |
# File 'lib/pixelart/stripes.rb', line 97 def rainbow ## # the most common variant consists of six stripes: # red, orange, yellow, green, blue, and violet. # The flag is typically flown horizontally, # with the red stripe on top, as it would be in a natural rainbow # # see https://en.wikipedia.org/wiki/Rainbow_flag_(LGBT) stripes( RAINBOW_RED, RAINBOW_ORANGE, RAINBOW_YELLOW, RAINBOW_GREEN, RAINBOW_BLUE, RAINBOW_VIOLET ) end |
#rotate_clockwise ⇒ Object Also known as: rotate_right
90 degrees
130 131 132 133 |
# File 'lib/pixelart/image.rb', line 130 def rotate_clockwise # 90 degrees img = @img.rotate_clockwise Image.new( img.width, img.height, img ) end |
#rotate_counter_clockwise ⇒ Object Also known as: rotate_left
90 degrees
124 125 126 127 |
# File 'lib/pixelart/image.rb', line 124 def rotate_counter_clockwise # 90 degrees img = @img.rotate_counter_clockwise Image.new( img.width, img.height, img ) end |
#save(path, constraints = {}) ⇒ Object Also known as: write
(image) delegates
todo/check: add some more??
210 211 212 213 214 215 216 217 |
# File 'lib/pixelart/image.rb', line 210 def save( path, constraints = {} ) # step 1: make sure outdir exits outdir = File.dirname( path ) FileUtils.mkdir_p( outdir ) unless Dir.exist?( outdir ) # step 2: save @img.save( path, constraints ) end |
#silhouette(color = '#000000') ⇒ Object
14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
# File 'lib/pixelart/silhouette.rb', line 14 def silhouette( color='#000000' ) color = Color.parse( color ) img = Image.new( @img.width, @img.height ) @img.width.times do |x| @img.height.times do |y| pixel = @img[x,y] img[x,y] = if pixel == Color::TRANSPARENT # transparent (0) Color::TRANSPARENT else color end end end img end |
#sketch(sketch = 4, line: 1) ⇒ Object
6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 |
# File 'lib/pixelart/sketch.rb', line 6 def sketch( sketch=4, line: 1 ) # todo: line - find a better name eg. line_strenght/width or such? width = @img.width*sketch + (@img.width+1)*line height = @img.height*sketch + (@img.height+1)*line puts " #{width}x#{height}" img = Image.new( width, height, Color::WHITE ) @img.width.times do |x| @img.height.times do |y| pixel = @img[x,y] ## get surrounding pixels - if "out-of-bound" use transparent (0) left = x == 0 ? Color::TRANSPARENT : @img[x-1,y] top = y == 0 ? Color::TRANSPARENT : @img[x ,y-1] if pixel != left ## draw vertical line (sketch+line*2).times do |n| line.times do |m| img[ x*sketch + line*x + m, n + y*sketch + line*y] = Color::BLACK end end end if pixel != top ## draw horizontal line (sketch+line*2).times do |n| line.times do |m| img[n + x*sketch + line*x, y*sketch + line*y + m] = Color::BLACK end end end ## check special edge case for x and y to add "finish-up" right and bottom line if x == @img.width-1 && pixel != Color::TRANSPARENT ## draw vertical line (sketch+line*2).times do |n| line.times do |m| img[ (x+1)*sketch + line*(x+1) + m, n + y*sketch + line*y] = Color::BLACK end end end if y== @img.height-1 && pixel != Color::TRANSPARENT ## draw horizontal line (sketch+line*2).times do |n| line.times do |m| img[n + x*sketch + line*x, (y+1)*sketch + line*(y+1) + m] = Color::BLACK end end end end end img end |
#spots(spot = 10, spacing: 0, center: nil, radius: nil, background: nil, lightness: nil, odd: false) ⇒ Object
124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 |
# File 'lib/pixelart/spots.rb', line 124 def spots( spot=10, spacing: 0, center: nil, radius: nil, background: nil, lightness: nil, odd: false ) v = spots_hidef( spot, spacing: spacing, center: center, radius: radius, background: background, lightness: lightness, odd: odd ) v.to_image end |
#spots_hidef(spot = 10, spacing: 0, center: nil, radius: nil, background: nil, lightness: nil, odd: false) ⇒ Object Also known as: spots_hd
6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 |
# File 'lib/pixelart/spots.rb', line 6 def spots_hidef( spot=10, spacing: 0, center: nil, radius: nil, background: nil, lightness: nil, odd: false ) width = @img.width*spot+(@img.width-1)*spacing height = @img.height*spot+(@img.height-1)*spacing ## puts " #{width}x#{height}" ## settings in a hash for "pretty printing" in comments settings = { spot: spot } settings[ :spacing ] = spacing if spacing settings[ :center ] = center if center settings[ :radius ] = radius if radius settings[ :background ] = background if background settings[ :lightness ] = lightness if lightness settings[ :odd ] = odd if odd v = Vector.new( width, height, header: <<TXT ) generated by pixelart/v#{VERSION} on #{Time.now.utc} spots_hidef with settings: #{settings.to_json} TXT min_center, max_center = center ? center : [0,0] min_radius, max_radius = radius ? radius : [0,0] ## note: allow passing in array of colors (will get randomally picked) background_colors = if background ## check for array; otherwise assume single color passed in background_ary = background.is_a?( Array) ? background : [background] background_ary.map { |background| Color.parse( background ) } else [0] # transparent (default - no background) end min_lightness, max_lightness = lightness ? lightness : [0.0,0.0] @img.width.times do |x| @img.height.times do |y| color = @img[ x, y ] if color == 0 ## transparent next if background.nil? color = if background_colors.size == 1 background_colors[0] else ## pick random background color background_colors[ rand( background_colors.size ) ] end end if lightness ## todo/check: make it work with alpha too h,s,l = Color.to_hsl( color, include_alpha: false ) h = h % 360 ## make sure h(ue) is always positive!!! ## note: rand() return between 0.0 and 1.0 l_diff = min_lightness + (max_lightness-min_lightness)*rand() lnew = [1.0, l+l_diff].min lnew = [0.0, lnew].max ## print " #{l}+#{l_diff}=#{lnew} " color = Color.from_hsl( h, [1.0, s].min, lnew ) end ## note: return hexstring with leading # # e.g. 0 becomes #00000000 # and so on color_hex = Color.to_hex( color, include_alpha: true ) cx_offset, cy_offset = if center ## randomize (offset off center +/-) [(spot/2 + min_center) + rand( max_center-min_center ), (spot/2 + min_center) + rand( max_center-min_center )] else [spot/2, ## center spot/2] end cx = x*spot + x*spacing + cx_offset cy = y*spot + y*spacing + cx_offset r = if radius ## randomize (radius +/-) min_radius + rand( max_radius-min_radius ) else spot/2 end cx += spot/2 if odd && (y % 2 == 1) ## add odd offset v.circle( cx: cx, cy: cy, r: r, fill: color_hex) end end v end |
#stripes_horizontal(*colors) ⇒ Object Also known as: stripes
58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 |
# File 'lib/pixelart/stripes.rb', line 58 def stripes_horizontal( *colors ) colors = colors.map { |color| Color.parse( color ) } img = Image.new( @img.width, @img.height ) n = colors.size lengths = self.class.calc_stripes( @img.height, n: n ) i = 0 length = lengths[0] color = colors[0] @img.height.times do |y| if y >= length i += 1 length += lengths[i] color = colors[i] end @img.width.times do |x| img[x,y] = color end end img.compose!( self ) ## paste/compose image onto backgorund img end |
#transparent(style = :solid, fuzzy: false) ⇒ Object
5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 |
# File 'lib/pixelart/transparent.rb', line 5 def transparent( style = :solid, fuzzy: false ) img = Image.new( width, height ) background = self[0,0] bh,bs,bl = Color.to_hsl( background ) bh = (bh % 360) ## might might negative degree (always make positive) height.times do |y| if style == :linear background = self[0,y] bh,bs,bl = Color.to_hsl( background ) bh = (bh % 360) ## might might negative degree (always make positive) end width.times do |x| pixel = self[x,y] if background == 0 ## special case if background is already transparent keep going img[x,y] = pixel elsif fuzzy ## check for more transparents ## not s is 0.0 to 0.99 (100%) ## and l is 0.0 to 0.99 (100%) h,s,l = Color.to_hsl( pixel ) h = (h % 360) ## might might negative degree (always make positive) ## try some kind-of fuzzy "heuristic" match on background color if ((h >= bh-5) && (h <= bh+5)) && ((s >= bs-0.07) && (s <= bs+0.07)) && ((l >= bl-0.07) && (l <= bl+0.07)) img[x,y] = 0 ## Color::TRANSPARENT if h != bh || s != bs || l != bl # report fuzzy background color puts " #{x}/#{y} fuzzy background #{[h,s,l]} ~= #{[bh,bs,bl]}" end else img[x,y] = pixel end else if pixel == background img[x,y] = 0 ## Color::TRANSPARENT else img[x,y] = pixel end end end end img end |
#ukraine ⇒ Object
16 |
# File 'lib/pixelart/ukraine.rb', line 16 def ukraine() stripes( UKRAINE_BLUE, UKRAINE_YELLOW ); end |
#width ⇒ Object
227 |
# File 'lib/pixelart/image.rb', line 227 def width() @img.width; end |
#zoom(zoom = 2, spacing: 0) ⇒ Object Also known as: scale
67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 |
# File 'lib/pixelart/image.rb', line 67 def zoom( zoom=2, spacing: 0 ) ## create a new zoom factor x image (2x, 3x, etc.) width = @img.width*zoom+(@img.width-1)*spacing height = @img.height*zoom+(@img.height-1)*spacing img = Image.new( width, height ) @img.width.times do |x| @img.height.times do |y| pixel = @img[x,y] zoom.times do |n| zoom.times do |m| img[n+zoom*x+spacing*x, m+zoom*y+spacing*y] = pixel end end end # each x end # each y img end |