pixelflut 0.0.8 → 0.0.10
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.
- checksums.yaml +4 -4
- data/README.md +24 -10
- data/TODO.md +1 -0
- data/bin/pxf-convert +10 -9
- data/bin/pxf-help +9 -13
- data/bin/pxf-send +44 -0
- data/lib/pixelflut.rb +1 -0
- data/lib/pixelflut/canvas/buffered.rb +2 -4
- data/lib/pixelflut/client.rb +35 -0
- data/lib/pixelflut/client/socket.rb +59 -0
- data/lib/pixelflut/converter.rb +29 -35
- data/lib/pixelflut/server/connection.rb +2 -0
- data/lib/pixelflut/version.rb +1 -1
- metadata +6 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 53fa839b0f1e655d481296ff80e16c50bcb14cb8b65002508a6cbdb6cf602d18
|
4
|
+
data.tar.gz: dc278f90adf043c2acfa484ea1beaadb04c12dd70e18e7ed2daa88db69ea1f28
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1bbf4d13ed7bc852d20000103456680ececcfc4286225b0fb7be74afce25ad89dff6fdcb5e89120737c599645591400c5761e4c0172e632c742599975ee5a5da
|
7
|
+
data.tar.gz: 53368ac74848597f441952344f40e30744517da98db162405d7837f461d15096a66a37e0291763672d60119a8fe1d8266ee91c2ca7764bd7a2eef71620b3ec95
|
data/README.md
CHANGED
@@ -29,14 +29,15 @@ $ pxf
|
|
29
29
|
usage: pxf command [options]
|
30
30
|
|
31
31
|
valid commands:
|
32
|
-
convert Convert given IMAGE file to Pixelflut format.
|
32
|
+
convert Convert given IMAGE file to Pixelflut ASCII format.
|
33
33
|
generate Execute given generator FILEs.
|
34
34
|
help Print help for given COMMAND.
|
35
|
+
send Send given Pixelflut ASCII file to a server.
|
35
36
|
server Start Pixelflut server.
|
36
37
|
version Print version information.
|
37
38
|
```
|
38
39
|
|
39
|
-
### Start a
|
40
|
+
### Start a Sserver
|
40
41
|
|
41
42
|
Starting the server on default port `1234` and open a drawing screen is quite simple:
|
42
43
|
|
@@ -56,21 +57,21 @@ With these options you can configure the server:
|
|
56
57
|
-f, --[no-]fullscreen run in fullscreen mode
|
57
58
|
```
|
58
59
|
|
59
|
-
### Convert an
|
60
|
+
### Convert an Image
|
60
61
|
|
61
|
-
There is a conversion command which can be used to convert a given image to the Pixelflut text format:
|
62
|
+
There is a conversion command which can be used to convert a given image to the Pixelflut ASCII text format:
|
62
63
|
|
63
64
|
```bash
|
64
65
|
$ pxf convert image.png
|
65
66
|
```
|
66
67
|
|
67
|
-
The result can directly
|
68
|
+
The result can send directly to a server (sample assumes the server runs on localhost port 1234):
|
68
69
|
|
69
70
|
```bash
|
70
|
-
$ pxf convert image.png |
|
71
|
+
$ pxf convert image.png | pxf send
|
71
72
|
```
|
72
73
|
|
73
|
-
The converter can help you to resize and positioning the image
|
74
|
+
The converter can help you to resize and positioning the image at the servers canvas. These options are avail:
|
74
75
|
|
75
76
|
```
|
76
77
|
-x, --transpose-x X transpose image X pixels
|
@@ -79,9 +80,22 @@ The converter can help you to resize and positioning the image and the servers c
|
|
79
80
|
-h, --height HEIGHT resize the image to given HEIGHT
|
80
81
|
```
|
81
82
|
|
82
|
-
It maybe faster to pre-process your
|
83
|
+
It maybe faster to pre-process your images and send them later:
|
83
84
|
|
84
85
|
```bash
|
85
|
-
$ pxf convert -x 50 -y 100 --width
|
86
|
-
$
|
86
|
+
$ pxf convert -x 50 -y 100 --width 100 image1.png > image1.px
|
87
|
+
$ pxf convert -x 150 --width 2100 image2.png > image2.px
|
88
|
+
$ pxf send -h pixel_host image1.px image2.px
|
87
89
|
```
|
90
|
+
|
91
|
+
### Send Pixelflut ASCII Text
|
92
|
+
|
93
|
+
The `pxf send` command can be used to send given Pixelflut ASCII text files to a server. It uses several connections at the same time to fasten the transmission.
|
94
|
+
|
95
|
+
Next sample will send the Pixelflut ASCII text file named `pixels.px` to the server on port 1234 at address `pixelhost` using 12 connections:
|
96
|
+
|
97
|
+
```bash
|
98
|
+
$ pxf send -h pixelhost -p 1234 -c 12 pixels.px
|
99
|
+
```
|
100
|
+
|
101
|
+
If no file is given the STDIN will be read and send afterwards to the server.
|
data/TODO.md
CHANGED
data/bin/pxf-convert
CHANGED
@@ -8,8 +8,8 @@ def options(cfg)
|
|
8
8
|
opts.banner = 'usage: pxf convert [options] IMAGE'
|
9
9
|
opts.separator(nil)
|
10
10
|
opts.separator('valid options:')
|
11
|
-
opts.on('-x', '--transpose-x X', Integer, 'transpose image X pixels'){ |v| cfg[:
|
12
|
-
opts.on('-y', '--transpose-y Y', Integer, 'transpose image Y pixels'){ |v| cfg[:
|
11
|
+
opts.on('-x', '--transpose-x X', Integer, 'transpose image X pixels'){ |v| cfg[:offset_x] = v }
|
12
|
+
opts.on('-y', '--transpose-y Y', Integer, 'transpose image Y pixels'){ |v| cfg[:offset_y] = v }
|
13
13
|
opts.on('-w', '--width WIDTH', Integer, 'resize the image to given WIDTH'){ |v| cfg[:width] = v }
|
14
14
|
opts.on('-h', '--height HEIGHT', Integer, 'resize the image to given HEIGHT'){ |v| cfg[:height] = v }
|
15
15
|
end
|
@@ -27,25 +27,26 @@ def err(msg, code = 1)
|
|
27
27
|
end
|
28
28
|
|
29
29
|
def create_options
|
30
|
-
cfg
|
31
|
-
options(cfg).parse!
|
32
|
-
cfg
|
30
|
+
{}.tap{ |cfg| options(cfg).parse! }
|
33
31
|
rescue OptionParser::ParseError => e
|
34
32
|
err(e)
|
35
33
|
end
|
36
34
|
|
37
35
|
help(false) if '--help' == ARGV[0]
|
38
36
|
help(true) if '--short-help' == ARGV[0]
|
39
|
-
err('too few arguments') if ARGV.empty?
|
40
37
|
options = create_options
|
38
|
+
err('too few arguments') if ARGV.empty?
|
41
39
|
require File.realdirpath('../../lib/pixelflut/converter.rb', __FILE__)
|
40
|
+
err('unable to load library - RMagick') unless Pixelflut::Converter::AVAIL
|
41
|
+
require File.realdirpath('../../lib/pixelflut/canvas/streamed.rb', __FILE__)
|
42
42
|
begin
|
43
|
+
canvas = Pixelflut::Canvas::Streamed.new($stdout)
|
44
|
+
canvas.offset_x = options[:offset_x] if options[:offset_x]
|
45
|
+
canvas.offset_y = options[:offset_y] if options[:offset_y]
|
43
46
|
ARGV.each do |file_name|
|
44
47
|
cvt = Pixelflut::Converter.new(file_name)
|
45
|
-
cvt.x_offset = options[:x_offset] if options[:x_offset]
|
46
|
-
cvt.y_offset = options[:y_offset] if options[:y_offset]
|
47
48
|
cvt.resize_to(options[:width], options[:height]) if options[:width]
|
48
|
-
cvt.
|
49
|
+
cvt.draw(canvas)
|
49
50
|
end
|
50
51
|
rescue Pixelflut::Converter::Error => e
|
51
52
|
err(e.message, 2)
|
data/bin/pxf-help
CHANGED
@@ -4,6 +4,7 @@
|
|
4
4
|
def help(short)
|
5
5
|
puts('usage: pxf help COMMAND', nil) unless short
|
6
6
|
puts('Print help for given COMMAND.')
|
7
|
+
exit
|
7
8
|
end
|
8
9
|
|
9
10
|
def err(msg)
|
@@ -11,17 +12,12 @@ def err(msg)
|
|
11
12
|
exit(1)
|
12
13
|
end
|
13
14
|
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
ARGV.each do |cmd|
|
23
|
-
fname = File.join(root, 'pxf-' + cmd)
|
24
|
-
err("no such command - #{cmd}") unless File.executable?(fname)
|
25
|
-
system(fname, '--help')
|
26
|
-
end
|
15
|
+
help(false) if ARGV[0] == '--help'
|
16
|
+
help(true) if ARGV[0] == '--short-help'
|
17
|
+
root = File.realdirpath('../', __FILE__).freeze
|
18
|
+
exec(File.join(root, 'pxf')) if ARGV.empty?
|
19
|
+
ARGV.each do |cmd|
|
20
|
+
fname = File.join(root, 'pxf-' + cmd)
|
21
|
+
err("no such command - #{cmd}") unless File.executable?(fname)
|
22
|
+
system(fname, '--help')
|
27
23
|
end
|
data/bin/pxf-send
ADDED
@@ -0,0 +1,44 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
def options(cfg)
|
5
|
+
require 'optparse'
|
6
|
+
OptionParser.new do |opts|
|
7
|
+
opts.summary_indent = ' '
|
8
|
+
opts.banner = 'usage: pxf send [options] FILE'
|
9
|
+
opts.separator(nil)
|
10
|
+
opts.separator('valid options:')
|
11
|
+
opts.on('-h', '--host HOST', String, 'target host name (default localhost)'){ |v| cfg[:host] = v }
|
12
|
+
opts.on('-p', '--port PORT', Integer, 'target port (default 1234)'){ |v| cfg[:port] = v }
|
13
|
+
opts.on('-c', '--connections COUNT', Integer, 'count of connections (default 8)'){ |v| cfg[:count] = v }
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def help(short)
|
18
|
+
puts(options(nil), nil) unless short
|
19
|
+
puts('Send given Pixelflut ASCII file to a server.')
|
20
|
+
exit
|
21
|
+
end
|
22
|
+
|
23
|
+
def err(msg, code = 1)
|
24
|
+
$stderr.puts("pxf: #{msg}")
|
25
|
+
exit(code)
|
26
|
+
end
|
27
|
+
|
28
|
+
def create_options
|
29
|
+
{port: 1234, count: 8}.tap{ |cfg| options(cfg).parse! }
|
30
|
+
rescue OptionParser::ParseError => e
|
31
|
+
err(e)
|
32
|
+
end
|
33
|
+
|
34
|
+
help(false) if '--help' == ARGV[0]
|
35
|
+
help(true) if '--short-help' == ARGV[0]
|
36
|
+
options = create_options
|
37
|
+
require File.realdirpath('../../lib/pixelflut/client.rb', __FILE__)
|
38
|
+
begin
|
39
|
+
Pixelflut::Client.new(options[:host], options[:port], ARGF.readlines, options[:count]).run
|
40
|
+
rescue SystemCallError => e
|
41
|
+
err(e.message, 2)
|
42
|
+
rescue Interrupt
|
43
|
+
exit
|
44
|
+
end
|
data/lib/pixelflut.rb
CHANGED
@@ -3,5 +3,6 @@ module Pixelflut
|
|
3
3
|
autoload :App, File.join(LibDir, 'app.rb')
|
4
4
|
autoload :Server, File.join(LibDir, 'server.rb')
|
5
5
|
autoload :Canvas, File.join(LibDir, 'canvas.rb')
|
6
|
+
autoload :Converter, File.join(LibDir, 'converter.rb')
|
6
7
|
autoload :VERSION, File.join(LibDir, 'version.rb')
|
7
8
|
end
|
@@ -10,13 +10,11 @@ module Pixelflut
|
|
10
10
|
end
|
11
11
|
|
12
12
|
def each(&block)
|
13
|
-
|
14
|
-
@lines.each(&block)
|
15
|
-
yield "QUIT\n"
|
13
|
+
block ? @lines.each(&block) : to_enum(__method__)
|
16
14
|
end
|
17
15
|
|
18
16
|
def to_s
|
19
|
-
@lines.join
|
17
|
+
@lines.join
|
20
18
|
end
|
21
19
|
|
22
20
|
private
|
@@ -0,0 +1,35 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'client/socket'
|
4
|
+
|
5
|
+
module Pixelflut
|
6
|
+
class Client
|
7
|
+
def initialize(host, port, data, socket_count)
|
8
|
+
@sockets = create_sockets(Addrinfo.tcp(host, port), sliced(data, socket_count))
|
9
|
+
end
|
10
|
+
|
11
|
+
def run
|
12
|
+
loop{ break if call }
|
13
|
+
end
|
14
|
+
|
15
|
+
def call
|
16
|
+
@sockets.size == @sockets.count do |socket|
|
17
|
+
socket.call
|
18
|
+
socket.state == :closed
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
def sliced(data, count)
|
25
|
+
data = data.split("\n") if data.is_a?(String)
|
26
|
+
data = data.each_slice(data.size / count).to_a
|
27
|
+
data[-2] += data.pop unless (data.size % count).zero?
|
28
|
+
data.map!(&:join)
|
29
|
+
end
|
30
|
+
|
31
|
+
def create_sockets(address, slices)
|
32
|
+
slices.map{ |data| Socket.new(address, data) }
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'socket'
|
4
|
+
|
5
|
+
module Pixelflut
|
6
|
+
class Client
|
7
|
+
class Socket < ::Socket
|
8
|
+
attr_reader :state
|
9
|
+
|
10
|
+
def initialize(address, data)
|
11
|
+
super(address.ipv6? ? :INET6 : :INET, :STREAM)
|
12
|
+
configure
|
13
|
+
@addr = ::Socket.pack_sockaddr_in(address.ip_port, address.ip_address)
|
14
|
+
@data = data
|
15
|
+
@size = data.bytesize
|
16
|
+
@state = :not_connected
|
17
|
+
end
|
18
|
+
|
19
|
+
def call
|
20
|
+
case @state
|
21
|
+
when :not_connected
|
22
|
+
do_connect
|
23
|
+
when :wait_connect
|
24
|
+
do_wait_for_connect
|
25
|
+
when :write
|
26
|
+
do_write
|
27
|
+
else
|
28
|
+
close
|
29
|
+
@state = :closed
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
private
|
34
|
+
|
35
|
+
def do_connect
|
36
|
+
@state = :wait_writable === connect_nonblock(@addr, exception: false) ? :wait_connect : :write
|
37
|
+
end
|
38
|
+
|
39
|
+
def do_wait_for_connect
|
40
|
+
@state = :write unless wait_writable(0.1).nil?
|
41
|
+
end
|
42
|
+
|
43
|
+
def do_write
|
44
|
+
written = write_nonblock(@data, exception: false)
|
45
|
+
return if Symbol === written
|
46
|
+
@size -= written
|
47
|
+
return @state = :write_finished if @size <= 0
|
48
|
+
@data = @data.byteslice(written, @data.bytesize - written)
|
49
|
+
end
|
50
|
+
|
51
|
+
def configure
|
52
|
+
self.sync = true
|
53
|
+
setsockopt(:TCP, :NODELAY, 1)
|
54
|
+
setsockopt(:SOCKET, :KEEPALIVE, 0)
|
55
|
+
self.do_not_reverse_lookup = true
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
data/lib/pixelflut/converter.rb
CHANGED
@@ -3,50 +3,44 @@
|
|
3
3
|
module Pixelflut
|
4
4
|
class Converter
|
5
5
|
Error = Class.new(RuntimeError)
|
6
|
+
end
|
6
7
|
|
7
|
-
|
8
|
+
begin
|
9
|
+
require 'rmagick'
|
8
10
|
|
9
|
-
|
10
|
-
|
11
|
-
@images = load_image(file_name)
|
12
|
-
@x_offset = @y_offset = 0
|
13
|
-
end
|
11
|
+
class Converter
|
12
|
+
AVAIL = true
|
14
13
|
|
15
|
-
|
16
|
-
|
17
|
-
|
14
|
+
def initialize(file_name)
|
15
|
+
@images = load_images(file_name)
|
16
|
+
end
|
18
17
|
|
19
|
-
|
20
|
-
|
21
|
-
@images.each do |image|
|
22
|
-
image.each_pixel do |color, x, y|
|
23
|
-
yield(
|
24
|
-
x + @x_offset,
|
25
|
-
y + @y_offset,
|
26
|
-
color.to_color(Magick::AllCompliance, true, 8, true)[1, 8]
|
27
|
-
) unless 0xffff == color.opacity
|
28
|
-
end
|
18
|
+
def resize_to(width, height = nil)
|
19
|
+
@images.each{ |image| image.resize_to_fit!(width, height) }
|
29
20
|
end
|
30
|
-
end
|
31
21
|
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
22
|
+
def each_pixel
|
23
|
+
return to_enum(__method__) unless block_given?
|
24
|
+
@images.each do |image|
|
25
|
+
image.each_pixel do |color, x, y|
|
26
|
+
yield(x, y, color.to_color(Magick::AllCompliance, true, 8, true)[1, 8]) unless 0xffff == color.opacity
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
36
30
|
|
37
|
-
|
31
|
+
def draw(canvas)
|
32
|
+
each_pixel{ |x, y, rgba| canvas[x, y] = rgba }
|
33
|
+
end
|
38
34
|
|
39
|
-
|
40
|
-
Magick::ImageList.new(file_name)
|
41
|
-
rescue Magick::ImageMagickError => e
|
42
|
-
raise(Error, e.message)
|
43
|
-
end
|
35
|
+
private
|
44
36
|
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
37
|
+
def load_images(file_name)
|
38
|
+
Magick::ImageList.new(file_name)
|
39
|
+
rescue Magick::ImageMagickError => e
|
40
|
+
raise(Error, e.message)
|
41
|
+
end
|
49
42
|
end
|
50
|
-
|
43
|
+
rescue LoadError
|
44
|
+
Converter::AVAIL = false
|
51
45
|
end
|
52
46
|
end
|
data/lib/pixelflut/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: pixelflut
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.10
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Mike Blumtritt
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-03-
|
11
|
+
date: 2018-03-10 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: gosu
|
@@ -62,6 +62,7 @@ executables:
|
|
62
62
|
- pxf-server
|
63
63
|
- pxf-convert
|
64
64
|
- pxf-help
|
65
|
+
- pxf-send
|
65
66
|
- pxf-version
|
66
67
|
extensions: []
|
67
68
|
extra_rdoc_files:
|
@@ -74,6 +75,7 @@ files:
|
|
74
75
|
- bin/pxf-convert
|
75
76
|
- bin/pxf-generate
|
76
77
|
- bin/pxf-help
|
78
|
+
- bin/pxf-send
|
77
79
|
- bin/pxf-server
|
78
80
|
- bin/pxf-version
|
79
81
|
- gems.rb
|
@@ -84,6 +86,8 @@ files:
|
|
84
86
|
- lib/pixelflut/canvas/buffered.rb
|
85
87
|
- lib/pixelflut/canvas/color.rb
|
86
88
|
- lib/pixelflut/canvas/streamed.rb
|
89
|
+
- lib/pixelflut/client.rb
|
90
|
+
- lib/pixelflut/client/socket.rb
|
87
91
|
- lib/pixelflut/converter.rb
|
88
92
|
- lib/pixelflut/server.rb
|
89
93
|
- lib/pixelflut/server/configuration.rb
|