load_library :file_chooser attr_reader :img, :data, :skip ########### # Example file chooser (in this case as an image file chooser). # We delay setting size of sketch until we know image size, probably # would not work vanilla processing. Note we can wrap much code in the # file_chooser block, no need for reflection. As with selectInput vanilla # processing. ########### def setup color_mode(HSB, 1.0); file_chooser do |fc| fc.look_feel "Gtk+" # optional, default is "Metal" fc.set_filter "Image Files", [".png", ".jpg"] # easily customizable chooser @img = load_image(fc.display) # fc.display returns a path String size(img.width, img.height) end @skip = 5 @data = [] end def draw background img # img must be same size as sketch end def write_data name, data open("data.cfdg", "w") do |pw| pw.puts "shape #{name}{\n" data.each do |row| pw.puts " #{row[0]}[x #{row[1]} y #{row[2]} s #{row[3]} hue #{row[4]} sat #{row[5]} brightness #{row[6]}]\n" end pw.puts "}\n" end end def write_start start, data open("#{start}.cfdg", "w") do |pw| pw.puts "CF::Background = [b -1]" pw.puts "startshape #{start}\n" pw.puts "shape dot{CIRCLE[]}\n" pw.puts "import data.cfdg\n" end write_data start, data end def mouse_clicked export = Thread.new do load_pixels shp = "dot" (skip ... img.width).step(skip) do |x| (skip ... img.height).step(skip) do |y| pix = pixels[x +y * width] sat = saturation(pix) hue = hue(pix) sz = brightness(pix) * skip data << [shp, -width/2 + x, height/2 - y, sz.round(2), (hue * 360).round, sat.round(4), 1] if sz > 0.03 end end write_start "haddock", data end export.join puts "done" end
Experiments with ruby-processing (processing-2.2.1) and JRubyArt for processing-3.0
Monday, 26 August 2013
Simple pixellator using a cfdg end point
In hommage to guigui's original, the output cfdg file is called haddock.cfdg (after capt haddock "tintin"), the sketch data gets shoved into data.cfdg, that is called from haddock.cfdg by the cfdg program (requires version 3.0+). To adjust to different axis conventions I could just have made y negative. But because evolution of an non deterministic design (this isn't one) is from centre out, I adjusted x and y accordingly. Tune-able value is skip 3..10 is sensible choice, you could also add a posterize filter if needed. Nice to have would be a rectangle mask to define area to pixel-ate. Where an actual image is uses as basis you might be better doing img.load_pixels and accessing the pixel array thus img.pixels[x +y * width]. However the following sketch could be readily adapted to use processing generated images.
Labels:
cfdg,
file_chooser,
ruby-processing
Sunday, 25 August 2013
The Gtk+ look and feel using openjdk
I just did some further experiments with my ruby-processing file chooser, and now I think the "Gtk+" look and feel might be the way to go on linux:-
However it is not that you should call the "Gtk+" look and feel, you should probably call "Metal", but specify system wide that the system and default look and feel is GTK (on archlinux you can do this in /etc/jre.sh in others you might use a flag or otherwise specify an environmental variable, be sure to set GTK fonts too).
Labels:
Gtk+,
linux,
openjdk,
ruby-processing
Friday, 23 August 2013
Image Viewer Ruby Processing
Here is a little sketch, exploring the possibility of using my file_chooser to create a neat little image viewer. I does not make too much sense on its own, but we can take a look at images in ruby-processing, and then possibly do something with them along the lines of exporting to a "pixelated" sketch to cfdg for example.
load_library :file_chooser attr_reader :img ########### # Example usage of file_chooser (in this case image file chooser) # not sure this is exactly possible with vanilla processing. Here we # defer setting the size of the sketch, until we know the size of image. ########### def setup file_chooser do |fc| fc.look_feel "Nimbus" fc.set_filter "Image Files", [".png", ".jpg"] my_file = fc.display @img = load_image(my_file) size img.width, img.height end end def draw background img end
Labels:
filechooser,
image viewer,
ruby-processing
File Chooser Library For ruby-processing
Well here it is in action my ruby-processing file_chooser library, that like control panel takes a block the fc.display returns a a string that you can use in load_image etc to load a file, you can do all this in a block if you like (see below). Is a replacement for vanilla processing selectInput function that relies on reflection (and the chooser cannot be so easily customised). PS the my_file temporary variable is not required. The chooser starts in the users home folder on unix (mac/linux) or the working directory on windoes.
load_library :file_chooser attr_reader :img ########### # Example file chooser (in this case image file chooser) # the image loading and resizing is encapsulated in the block, # borrows heavily off control_panel. ########### def setup size 600, 600 file_chooser do |fc| fc.look_feel "Nimbus" fc.set_filter "Image Files", [".png", ".jpg"] my_file = fc.display @img = load_image(my_file) img.resize(width, height) end end def draw image img, 0, 0 end
The Chooser (a customised JFileChooser) |
The Sketch |
Labels:
block,
filechooser,
reflection,
ruby-processing,
select_input
Saturday, 17 August 2013
File Chooser in JRuby
Having convinced myself that the vanilla processing selectInput is a piece of crap (yet more reflection nonsense) I though I had better come up with an alternative for ruby processing, here is such an example (yielded by my good friend google and a bit of imagination, works for me):-
require 'rbconfig' require 'pathname' System = Java::JavaLang::System JFile = Java::JavaIo::File JXChooser = Java::javax::swing::JFileChooser class ImageFilter < Java::javax::swing::filechooser::FileFilter def accept fobj return [".png",".jpg"].include? File.extname(fobj.to_s).downcase return fobj.isDirectory end def getDescription "Image Files" end end # Detect OS OS = case RbConfig::CONFIG['host_os'] when /darwin/ then :mac when /mswin|mingw/ then :windows else :unix end # Asks the user to choose an editor. # Returns either a Pathname object or nil (if canceled) def pickImage # Create a FileChooser fc = JXChooser.new("Image Chooser") fc.set_dialog_title("Please select an image") fc.setFileFilter ImageFilter.new if :mac == OS fc.setCurrentDirectory(JFile.new(System.getProperty("user.home") << "/Pictures")) elsif :windows == OS fc.setCurrentDirectory(JFile.new(System.getProperty("user.dir"))) else fc.setCurrentDirectory(JFile.new(System.getProperty("user.home"))) end success = fc.show_open_dialog(nil) if success == JXChooser::APPROVE_OPTION return Pathname.new(fc.get_selected_file.get_absolute_path) else nil end end puts "The user picked: #{pickImage}" # EOFThis would be the wrapper for ruby-processing?
def select_input(*args, &block) if block_given? # code using FileChooser output? else raise ArgumentError, "select_input must be called with a block" , caller end end
Labels:
filechooser
Thursday, 15 August 2013
Ruby-processing-2.1.3 is released (features processing-2.0.2)
In recent weeks I've changed the default mode of ruby-processing from using the included jruby-complete by default to using an external (system installed) jruby. So the --jruby flag is now deprecated (it doesn't do anything) and is replaced by the --nojruby flag which causes the installed jruby-complete to be used instead of the system version. The jruby-complete is retained for the following uses:-
- To support application export
- To run certain sketches (mainly GLSL shader sketches) that wont run with installed jruby
- For people without an installed jruby (for whatever reason), make sure and use --nojruby flag.
Vect = Struct.new(:x, :y, :z) do def add v self.x += v.x self.y += v.y self.z += v.z end end
Labels:
PVector,
ruby struct,
ruby-processing
Monday, 12 August 2013
Netbeans for ruby-processing
Hey this looks pretty promising, you can now install a plugin for netbeans-7.3 (for ruby and ruby-on-rails development). I will report how I get on install seemed to go ok, Once I figured out I needed to add *.jar as well as *.nbm sub-modules.
Labels:
ide,
jruby,
netbeans,
ruby-processing
Wednesday, 7 August 2013
Avoiding classpath conflict with jruby-complete
Well the simplest thing to do, would be ditch to jruby-complete, except:-
- Shader sketches still refuse to run.
- We would lose export.
- We would lose ability to install to system without requiring an installed jruby.
For me 1. is the biggest problem, any exported sketches will probably still be unable to use gems, also installing without jruby also means no access to gems.
See this gist for work in progress https://gist.github.com/monkstone/6172815. I propose to work on this independently on my monkstone branch will need updating from master.
Motivation we could potentially use rubygems with P2D and P3D modes (even PImage sketches could not be run with rubygems). If we radically exclude jruby-complete until export gem would be much smaller.
Well it seem possible solution is to put jruby-complete.jar in its own directory, and possibly use:-
RUBY_PLATFORM == 'java'
So the solution is:-
Move ruby-complete.jar to its own folder (so we no-longer 'require jruby-complete.jar' in app.rb)
Dir["#{RP5_ROOT}/lib/core/\*.jar"].each { |jar| require jar }
Consequently we need to adjust the path jruby-complete.jar. And in the first place make sure we extract it to its new location easy. Seems to work, we retain the --jruby flag, which should be default unless we haven't installed jruby or we want to run shader sketches.
However it occurs to me this is the ideal opportunity to set using an external jruby as the default. Now all we need is a flag "--nojruby" for when we need/prefer to use the included jruby-complete (which will remain handy to support export of applications). The shader sketches are the only ones now requiring such a flag. However it will also be required if ruby-processing gets installed without using system jruby (in this case you won't be able to use gems with ruby-processing).
Well I've done it now since version 2.1.2 the default is to run ruby-processing from an external jruby, to revert to using installed jruby-complete now use the --nojruby flag (replaces the --jruby flag which had the opposite effect).
Well it seem possible solution is to put jruby-complete.jar in its own directory, and possibly use:-
RUBY_PLATFORM == 'java'
So the solution is:-
Move ruby-complete.jar to its own folder (so we no-longer 'require jruby-complete.jar' in app.rb)
Dir["#{RP5_ROOT}/lib/core/\*.jar"].each { |jar| require jar }
Consequently we need to adjust the path jruby-complete.jar. And in the first place make sure we extract it to its new location easy. Seems to work, we retain the --jruby flag, which should be default unless we haven't installed jruby or we want to run shader sketches.
However it occurs to me this is the ideal opportunity to set using an external jruby as the default. Now all we need is a flag "--nojruby" for when we need/prefer to use the included jruby-complete (which will remain handy to support export of applications). The shader sketches are the only ones now requiring such a flag. However it will also be required if ruby-processing gets installed without using system jruby (in this case you won't be able to use gems with ruby-processing).
Well I've done it now since version 2.1.2 the default is to run ruby-processing from an external jruby, to revert to using installed jruby-complete now use the --nojruby flag (replaces the --jruby flag which had the opposite effect).
Labels:
--jruby,
--nojruby,
development,
jruby,
ruby-complete,
ruby-processing
Tuesday, 6 August 2013
Conways Game of Life in ruby-processing (featuring MDArray)
# game_of_life.rb featuring MDArray in ruby-processing # A Processing implementation of Game of Life # By Joan Soler-Adillon # # Press SPACE BAR to pause and change the cell's values with the mouse # On pause, click to activate/deactivate cells # Press R to randomly reset the cells' grid # Press C to clear the cells' grid # # The original Game of Life was created by John Conway in 1970. # require 'mdarray' CELL_SIZE = 5 ALIVE = true DEAD = false ALIVE_START = 150 WIDTH = 960 HEIGHT = 640 SKIP = 10 INTERVAL = 100 attr_reader :pause, :cells, :row, :column, :last_time, :alive, :cells_buffer # signature-specific aliases for overloaded methods java_alias :my_color, :color, [Java::float, Java::float, Java::float] java_alias :my_fill, :fill, [Java::int] java_alias :my_stroke, :stroke, [Java::float, Java::float] java_alias :my_background, :background, [Java::int] def setup size WIDTH, HEIGHT @row = WIDTH / CELL_SIZE @column = HEIGHT / CELL_SIZE stroke_weight 2 @last_time = 0 @pause = false @cells = MDArray.boolean([row, column], random_data) @alive = my_color(100, 255, 100) my_stroke(48, 100) no_smooth end def draw my_background(0) #Draw live cells (0 ... row).each do |x| (0 ... column).each do |y| if (cells.get([x, y])) my_fill(alive) rect(x * CELL_SIZE, y * CELL_SIZE, CELL_SIZE, CELL_SIZE) end end end # Iterate if timer ticks if (millis - last_time > INTERVAL) if (!pause) tick! @last_time = millis end end # Create new cells manually on pause if (pause && mouse_pressed?) # # Map and avoid out of bound errors x_cell_over = (map(mouse_x, 0, width, 0, row)).to_i x_cell_over = constrain(x_cell_over, 0, row - 1) y_cell_over = (map(mouse_y, 0, height, 0, column)).to_i y_cell_over = constrain(y_cell_over, 0, column - 1) # Check against cells in buffer if (cells_buffer.get([x_cell_over, y_cell_over])) # Cell is alive cells.set([x_cell_over, y_cell_over], DEAD) # Kill my_fill(0) #reflect changed status else # Cell is dead cells.set([x_cell_over, y_cell_over], ALIVE) # Make alive my_fill(alive) # Fill alive color end elsif (pause && !mouse_pressed?) # And then save to buffer once mouse goes up # Save cells to buffer (so we operate with one array keeping the other intact) @cells_buffer = cells.copy end end def tick! # When the clock ticks # Save cells to buffer (so we operate with one array keeping the other intact) @cells_buffer = cells.copy # Visit each cell: (0 ... row).each do |x| (0 ... column).each do |y| # And visit all the neighbours of each cell neighbours = 0 # We'll count the neighbours (x - 1 .. x + 1).each do |xx| (y - 1 .. y + 1).each do |yy| # Make sure you are not out of bounds if [(xx>=0), (xx<row), (yy>=0), (yy<column)].all? {|in_bounds| in_bounds == true} # Make sure to check against self if ![(xx == x), (yy == y)].all? {|is_self| is_self == true} if (cells_buffer.get([xx, yy])) # true == ALIVE neighbours += 1 # Check alive neighbours and count them end # alive end # End of if self end # End of if grid bounds end # End of yy loop end #End of xx loop # We've checked the neighbours: apply rules in one line (only in ruby)! cells.set([x, y], (cells_buffer.get([x, y]))? ((2 .. 3) === neighbours) : (neighbours == 3)) end # End of y loop end # End of x loop end # End of function def key_pressed case key when 'r', 'R' # Restart: reinitialization of cells @cells = MDArray.boolean([row, column], random_data) when ' ' # On/off of pause @pause = !pause when 'c', 'C' # Clear all @cells = MDArray.boolean([row, column], DEAD) end end def random_data data = [] (0 ... row * column).each do data << (rand(1000) < ALIVE_START) end return data end
Labels:
boolean,
conway game of life,
copy,
gem,
MDArray,
ruby-processing
Saturday, 3 August 2013
Using MDArray in ruby-processing
Well quite excited with this jruby gets its own flavour of numpy, namely MDArray. I had to give it a go here is a simple example:-
According to the limited documentation it might be more efficient to use the accessor to "get" data rather than using bare array access see below. For actual image manipulation in ruby-processing we might be in a bind, we require external jruby to access the gem, but that appears not to work with PImage sketches?
# Demonstrates the syntax for creating a two-dimensional (2D) array, # fromfunction (actually a block) using MDArray (for jruby). # Values in a 2D array are accessed through two index values. # 2D arrays are useful for storing images. In this example, each dot # is colored in relation to its distance from the center of the image. require 'mdarray' WIDTH=640 HEIGHT=360 SKIP=10 def setup size WIDTH, HEIGHT background 0 stroke_weight 2 max_distance = ( (WIDTH / 2 - WIDTH)**2 + (HEIGHT / 2 - HEIGHT)**2 )**0.5 distances = MDArray.fromfunction("float", [WIDTH, HEIGHT]) do |x, y| 255 * ( (WIDTH / 2 - x)**2 + (HEIGHT / 2 - y)**2 )**0.5 / max_distance end (SKIP ... WIDTH).step(SKIP) do |x| (SKIP ... HEIGHT).step(SKIP) do |y| stroke distances[x, y] point x, y end end end
According to the limited documentation it might be more efficient to use the accessor to "get" data rather than using bare array access see below. For actual image manipulation in ruby-processing we might be in a bind, we require external jruby to access the gem, but that appears not to work with PImage sketches?
distances.get([x, y])
Labels:
MDArray,
Numpy,
ruby-processing,
Scipy
Subscribe to:
Posts (Atom)
Followers
Blog Archive
-
▼
2013
(94)
-
▼
August
(10)
- Simple pixellator using a cfdg end point
- The Gtk+ look and feel using openjdk
- Image Viewer Ruby Processing
- File Chooser Library For ruby-processing
- File Chooser in JRuby
- Ruby-processing-2.1.3 is released (features proces...
- Netbeans for ruby-processing
- Avoiding classpath conflict with jruby-complete
- Conways Game of Life in ruby-processing (featuring...
- Using MDArray in ruby-processing
-
▼
August
(10)
About Me
- monkstone
- I have developed JRubyArt and propane new versions of ruby-processing for JRuby-9.1.5.0 and processing-3.2.2