mir_processing 0.0.2
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 +7 -0
- data/bin/mir +4 -0
- data/lib/mir/00_info_display.rb +37 -0
- data/lib/mir/00_version.rb +3 -0
- data/lib/mir/01_model.rb +153 -0
- data/lib/mir/01_runner.rb +63 -0
- data/lib/mir/02_viewer.rb +81 -0
- data/lib/mir.rb +6 -0
- metadata +64 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 89a5cadd98ec1b8041a0975fad823ada96957b9c5b600c8ed3c83a4503d7cb03
|
4
|
+
data.tar.gz: 4670d0ad67c51e9119642576f83accd8c9f60fd13c6f32e4c57f128c8d478ff2
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 71f358287c53440cbfdd43ef7ab6e9e7df9a82966c0a84e85bcfa06e6c74ee33284d27799efef3bf1727dd4d0aa0025bb353a96f0be4f8d576a1830d093cdc6c
|
7
|
+
data.tar.gz: a193f81d97d3c0641a78cefeda37fb55ae2e1eab050d995ec2a043a445881aab1bf8b691162eb11adeaa82a6418946bfcc7d54c18096ce476cf04f82d8604a49
|
data/bin/mir
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
module InfoDisplay
|
2
|
+
def info(level,str,other="")
|
3
|
+
case level
|
4
|
+
when 0
|
5
|
+
space_bar=""
|
6
|
+
when 1
|
7
|
+
space_bar=" |-"
|
8
|
+
else
|
9
|
+
space_bar=" "*3*(level-1)+" |-"
|
10
|
+
end
|
11
|
+
str="#{space_bar}[+] #{str}"
|
12
|
+
other="#{other}"
|
13
|
+
if other.size > 0
|
14
|
+
puts str.ljust(40,'.')+" #{other}"
|
15
|
+
else
|
16
|
+
puts str
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def hit_a_key str=""
|
21
|
+
puts str
|
22
|
+
puts "hit_a_key"
|
23
|
+
$stdin.gets
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
if $PROGRAM_NAME==__FILE__
|
28
|
+
include InfoDisplay
|
29
|
+
info 0,"I"
|
30
|
+
info 1,"A"
|
31
|
+
info 2,"1"
|
32
|
+
info 1,"B"
|
33
|
+
info 2,"1"
|
34
|
+
info 2,"2"
|
35
|
+
info 2,"3"
|
36
|
+
info 3,"a"
|
37
|
+
end
|
data/lib/mir/01_model.rb
ADDED
@@ -0,0 +1,153 @@
|
|
1
|
+
module Mir
|
2
|
+
Size=Struct.new(:x,:y)
|
3
|
+
|
4
|
+
# not used systematically...
|
5
|
+
Vect=Struct.new(:y,:x) do
|
6
|
+
def +(v)
|
7
|
+
Vect.new y+v.y,x+v.x
|
8
|
+
end
|
9
|
+
|
10
|
+
def scale fact
|
11
|
+
Vect.new y*fact,x*fact
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
class Rgb
|
16
|
+
attr_accessor :r,:g,:b
|
17
|
+
def initialize r,g,b
|
18
|
+
@r,@g,@b=r,g,b
|
19
|
+
end
|
20
|
+
|
21
|
+
def to_a
|
22
|
+
[self.r,self.g,self.b]
|
23
|
+
end
|
24
|
+
|
25
|
+
def to_s
|
26
|
+
"(#{r.to_s.rjust(3)},#{g.to_s.rjust(3)},#{b.to_s.rjust(3)})"
|
27
|
+
end
|
28
|
+
|
29
|
+
def self.random
|
30
|
+
Rgb.new rand(255),rand(255),rand(255)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
class Yuv
|
35
|
+
attr_accessor :y,:u,:v
|
36
|
+
def initialize y,u,v
|
37
|
+
@y,@u,@v=y,u,v
|
38
|
+
end
|
39
|
+
def to_a
|
40
|
+
[self.y,self.u,self.v]
|
41
|
+
end
|
42
|
+
def to_s
|
43
|
+
"(#{y.to_s.rjust(3)},#{u.to_s.rjust(3)},#{v.to_s.rjust(3)})"
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
class Grid
|
48
|
+
attr_accessor :size
|
49
|
+
def initialize width,height
|
50
|
+
@size=Size.new(width,height)
|
51
|
+
@values=Array.new(height){Array.new(width)}
|
52
|
+
end
|
53
|
+
|
54
|
+
def [](y,x)
|
55
|
+
@values[y][x]
|
56
|
+
end
|
57
|
+
|
58
|
+
def []=(y,x,v)
|
59
|
+
@values[y][x]=v
|
60
|
+
end
|
61
|
+
|
62
|
+
def to_a
|
63
|
+
@values.flatten
|
64
|
+
end
|
65
|
+
|
66
|
+
def each &block
|
67
|
+
@values.each do |row|
|
68
|
+
row.each do |v|
|
69
|
+
yield v
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
def fill_with v
|
75
|
+
@values.each_with_index do |row,y|
|
76
|
+
row.each_with_index do |pix,x|
|
77
|
+
self[y,x]=v
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
def print
|
83
|
+
@values.each do |row|
|
84
|
+
puts row.map{|pix| pix.to_s.rjust(3)}.join(" ")
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
def self.from_a ary1d,sx,sy
|
89
|
+
ret=self.new(sx,sy)
|
90
|
+
sy.times do |y|
|
91
|
+
sx.times do |x|
|
92
|
+
index=y*(sx)+x
|
93
|
+
ret[y,x]=ary1d[index]
|
94
|
+
end
|
95
|
+
end
|
96
|
+
ret
|
97
|
+
end
|
98
|
+
|
99
|
+
def self.random sx,sy,klass
|
100
|
+
ret=self.new(sx,sy)
|
101
|
+
sy.times do |y|
|
102
|
+
sx.times do |x|
|
103
|
+
ret[y,x]=klass.random
|
104
|
+
end
|
105
|
+
end
|
106
|
+
ret
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
class Image < Grid
|
111
|
+
include InfoDisplay
|
112
|
+
attr_accessor :name
|
113
|
+
def self.open(filename)
|
114
|
+
unless File.exist?(filename)
|
115
|
+
raise "file '#{filename}' not found"
|
116
|
+
end
|
117
|
+
image=nil
|
118
|
+
File.open(filename, 'r') do |f|
|
119
|
+
header=[]
|
120
|
+
begin
|
121
|
+
unless (line=f.gets.chomp).start_with?('#')
|
122
|
+
header << line
|
123
|
+
end
|
124
|
+
end until header.size==3
|
125
|
+
width, height = header[1].split.map {|n| n.to_i }
|
126
|
+
if header[0] != 'P6' or header[2] != '255' or width < 1 or height < 1
|
127
|
+
raise StandardError, "file '#{filename}' does not start with the expected header"
|
128
|
+
end
|
129
|
+
f.binmode
|
130
|
+
image = self.new(width, height)
|
131
|
+
|
132
|
+
height.times do |y|
|
133
|
+
width.times do |x|
|
134
|
+
# read 3 bytes
|
135
|
+
red, green, blue = f.read(3).unpack('C3')
|
136
|
+
image[y,x] = Rgb.new(red, green, blue)
|
137
|
+
end
|
138
|
+
end
|
139
|
+
end
|
140
|
+
image.name=File.basename(filename)
|
141
|
+
image
|
142
|
+
end
|
143
|
+
|
144
|
+
def each_pixel &block
|
145
|
+
each &block
|
146
|
+
end
|
147
|
+
|
148
|
+
def Image.random sx,sy
|
149
|
+
ary=Grid.random(sx,sy,Rgb).to_a
|
150
|
+
Image.from_a ary,sx,sy
|
151
|
+
end
|
152
|
+
end
|
153
|
+
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
require "optparse"
|
2
|
+
|
3
|
+
module Mir
|
4
|
+
|
5
|
+
class Runner
|
6
|
+
|
7
|
+
def self.run *arguments
|
8
|
+
new.run(arguments)
|
9
|
+
end
|
10
|
+
|
11
|
+
def run arguments
|
12
|
+
options = args = parse_options(arguments)
|
13
|
+
begin
|
14
|
+
if filename=args[:file]
|
15
|
+
image=Mir::Image.open(filename)
|
16
|
+
viewer=ViewerApp.new(image)
|
17
|
+
viewer.run
|
18
|
+
else
|
19
|
+
raise "need a ppm file : mir [options] <file>"
|
20
|
+
end
|
21
|
+
rescue Exception => e
|
22
|
+
puts e unless options[:mute]
|
23
|
+
return false
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def header
|
28
|
+
puts "Mir (#{VERSION}) - (c) JC Le Lann 2023"
|
29
|
+
end
|
30
|
+
|
31
|
+
private
|
32
|
+
def parse_options(arguments)
|
33
|
+
|
34
|
+
parser = OptionParser.new
|
35
|
+
|
36
|
+
no_arguments=arguments.empty?
|
37
|
+
|
38
|
+
options = {}
|
39
|
+
|
40
|
+
parser.on("-h", "--help", "Show help message") do
|
41
|
+
puts parser
|
42
|
+
exit(true)
|
43
|
+
end
|
44
|
+
|
45
|
+
parser.on("-v", "--version", "Show version number") do
|
46
|
+
puts VERSION
|
47
|
+
exit(true)
|
48
|
+
end
|
49
|
+
|
50
|
+
parser.parse!(arguments)
|
51
|
+
|
52
|
+
header unless options[:mute]
|
53
|
+
|
54
|
+
options[:file]=arguments.shift #the remaining file
|
55
|
+
|
56
|
+
if no_arguments
|
57
|
+
puts parser
|
58
|
+
end
|
59
|
+
|
60
|
+
options
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
@@ -0,0 +1,81 @@
|
|
1
|
+
require "gtk3"
|
2
|
+
|
3
|
+
module Mir
|
4
|
+
class PixelBoard < Gtk::DrawingArea
|
5
|
+
def initialize image
|
6
|
+
super()
|
7
|
+
@image=image
|
8
|
+
override_background_color(:normal, Gdk::RGBA.new(0, 0, 0, 1))
|
9
|
+
signal_connect "draw" do
|
10
|
+
on_expose
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def on_expose
|
15
|
+
cr = window.create_cairo_context
|
16
|
+
draw_pixels cr
|
17
|
+
end
|
18
|
+
|
19
|
+
def draw_pixels cr
|
20
|
+
@image.size.y.times do |y|
|
21
|
+
@image.size.x.times do |x|
|
22
|
+
pix=@image[y,x]
|
23
|
+
r,g,b=pix.to_a.map{|v| v/255.0}
|
24
|
+
xx,yy=x*3,y*3
|
25
|
+
cr.set_source_rgb r,g,b
|
26
|
+
cr.rectangle(x, y,1,1)
|
27
|
+
cr.stroke
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
class ViewerWindow < Gtk::ApplicationWindow
|
34
|
+
def initialize app,image
|
35
|
+
super(app)
|
36
|
+
set_title image.name||"Mir::Viewer"
|
37
|
+
if image.size.x < 200
|
38
|
+
size=[200,100]
|
39
|
+
else
|
40
|
+
size=*image.size
|
41
|
+
end
|
42
|
+
set_default_size *size
|
43
|
+
set_window_position(:center)
|
44
|
+
signal_connect(:destroy){Gtk.main_quit}
|
45
|
+
# Create a box to hold the contents of the window
|
46
|
+
box = Gtk::Box.new(:vertical,0)
|
47
|
+
# Add a button to the window to quit the application
|
48
|
+
button = Gtk::Button.new(label: 'Quit')
|
49
|
+
button.signal_connect('clicked') { application.quit }
|
50
|
+
|
51
|
+
board = PixelBoard.new(image)
|
52
|
+
|
53
|
+
# Add the button to the box
|
54
|
+
box.pack_start(board, :expand => true, :fill => true, :padding => 0)
|
55
|
+
box.pack_start(button, :expand => false, :fill => true, :padding => 0)
|
56
|
+
|
57
|
+
# Add the box to the window
|
58
|
+
add(box)
|
59
|
+
show_all
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
class Viewer < Gtk::Application
|
64
|
+
def initialize image
|
65
|
+
super('com.Mir.viewer', :flags_none)
|
66
|
+
signal_connect(:activate){on_activate(image)}
|
67
|
+
end
|
68
|
+
|
69
|
+
def on_activate image
|
70
|
+
window = ViewerWindow.new(self,image)
|
71
|
+
window.present
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
if $PROGRAM_NAME==__FILE__
|
77
|
+
require_relative "../mir.rb"
|
78
|
+
image=Mir::Image.open ARGV.first
|
79
|
+
app = Mir::Viewer.new image
|
80
|
+
app.run
|
81
|
+
end
|
data/lib/mir.rb
ADDED
metadata
ADDED
@@ -0,0 +1,64 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: mir_processing
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.2
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Jean-Christophe Le Lann
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2023-12-15 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: colorize
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - '='
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 0.8.1
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - '='
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 0.8.1
|
27
|
+
description: MIR means 'Manipulations d'Images en Ruby
|
28
|
+
email: lelannje@ensta-bretagne.fr
|
29
|
+
executables:
|
30
|
+
- mir
|
31
|
+
extensions: []
|
32
|
+
extra_rdoc_files: []
|
33
|
+
files:
|
34
|
+
- bin/mir
|
35
|
+
- lib/mir.rb
|
36
|
+
- lib/mir/00_info_display.rb
|
37
|
+
- lib/mir/00_version.rb
|
38
|
+
- lib/mir/01_model.rb
|
39
|
+
- lib/mir/01_runner.rb
|
40
|
+
- lib/mir/02_viewer.rb
|
41
|
+
homepage: https://github.com/JC-LL/mir
|
42
|
+
licenses:
|
43
|
+
- MIT
|
44
|
+
metadata: {}
|
45
|
+
post_install_message: Thanks for installing ! Homepage :https://github.com/JC-LL/mir
|
46
|
+
rdoc_options: []
|
47
|
+
require_paths:
|
48
|
+
- lib
|
49
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
50
|
+
requirements:
|
51
|
+
- - ">="
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: 2.0.0
|
54
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
55
|
+
requirements:
|
56
|
+
- - ">="
|
57
|
+
- !ruby/object:Gem::Version
|
58
|
+
version: '0'
|
59
|
+
requirements: []
|
60
|
+
rubygems_version: 3.2.3
|
61
|
+
signing_key:
|
62
|
+
specification_version: 4
|
63
|
+
summary: Simple image manipulation in Ruby, for experimental purposes
|
64
|
+
test_files: []
|