This class represents a trace of a Potracer::Bitmap
Trace a bitmap
bmp
- mapped to a Potracer::Bitmap
either a multi-dimensional array of bits or a string of image data
width
- width of the image to be mapped if bmp
is
a string
height
- height of the image to be mapped if bmp
is a string
map
- pixel data format if bmp
is a string
block
- optional block called to report trace progress
require 'ruby-progressbar' pbar = ProgressBar.create(title: 'Tracing') Potracer::Trace.bitmap(bits) do |percent| pbar.progress = percent end pbar.finish
# File lib/potracer.rb, line 53 def self.bitmap(bmp, width = nil, height = nil, map = 'RGB', &block) trace = new params = Potracer::Params.new bits = make_bits(bmp, width, height, map) if block_given? trace.trace(bits, params, &block) else trace.trace(bits, params) end trace end
Convert the traced bitmap to an array in the form:
[ {:area=>25, :sign=>"+", :parts=> [ [:moveto, 0.0, 2.5], [:curveto, 0.0, 0.5, 0.5, 0.0, 2.5, 0.0], [:curveto, 4.5, 0.0, 5.0, 0.5, 5.0, 2.5], [:curveto, 5.0, 4.5, 4.5, 5.0, 2.5, 5.0], [:curveto, 0.5, 5.0, 0.0, 4.5, 0.0, 2.5] ]}, {:area=>9, :sign=>"-", :parts=> [ [:moveto, 4.0, 2.5], [:curveto, 4.0, 1.6749999999999998, 3.325, 1.0, 2.5, 1.0], [:curveto, 1.6749999999999998, 1.0, 1.0, 1.6749999999999998, 1.0, 2.5], [:curveto, 1.0, 3.325, 1.6749999999999998, 4.0, 2.5, 4.0], [:curveto, 3.325, 4.0, 4.0, 3.325, 4.0, 2.5] ]} ]
static VALUE trace_as_array (VALUE klass) { VALUE rpath, rparts; VALUE result = rb_ary_new(); potrace_path_t *path; int i, num_segments, *tag; potrace_dpoint_t (*c)[3]; potrace_state_t *trace = NULL; Data_Get_Struct(klass, potrace_state_t, trace); if (trace->status == POTRACE_STATUS_OK) { path = trace->plist; while (path != NULL) { rparts = rb_ary_new(); num_segments = path->curve.n; tag = path->curve.tag; c = path->curve.c; MOVE_TO(rparts, c[num_segments-1][2]); for (i = 0; i < num_segments; i++) { switch (tag[i]) { case POTRACE_CORNER: LINE_TO(rparts, c[i][1]); LINE_TO(rparts, c[i][2]); break; case POTRACE_CURVETO: CURVE_TO(rparts, c[i]); break; } } rpath = rb_hash_new(); rb_hash_aset(rpath, STRSYM("area"), rb_int_new(path->area)); rb_hash_aset(rpath, STRSYM("sign"), rb_str_new2(path->sign == '+' ? "+" : "-")); rb_hash_aset(rpath, STRSYM("parts"), rparts); rb_ary_push(result, rpath); path = path->next; } } return result; }
Render the traced bitmap as an SVG
bmp = Potracer::Bitmap.new(5, 5, [ [1, 1, 1, 1, 1], [1, 0, 0, 0, 1], [1, 0, 0, 0, 1], [1, 0, 0, 0, 1], [1, 1, 1, 1, 1] ]) params = Potracer::Params.new trace = Potracer::Trace.new trace.trace(bmp, params).to_svg # => # <svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="5" height="5"> # <path fill-rule="evenodd" fill="rgb(0,0,0)" d="M 0.000000 2.500000 C 0.000000 0.500000 0.500000 0.000000 2.500000 0.000000C 4.500000 0.000000 5.000000 0.500000 5.000000 2.500000C 5.000000 4.500000 4.500000 5.000000 2.500000 5.000000C 0.500000 5.000000 0.000000 4.500000 0.000000 2.500000M 4.000000 2.500000 C 4.000000 1.675000 3.325000 1.000000 2.500000 1.000000C 1.675000 1.000000 1.000000 1.675000 1.000000 2.500000C 1.000000 3.325000 1.675000 4.000000 2.500000 4.000000C 3.325000 4.000000 4.000000 3.325000 4.000000 2.500000" /> # </svg>"
static VALUE trace_as_svg (VALUE klass) { FILE *out = tmpfile(); char *out_buffer; long size; VALUE svg; potrace_path_t *path; int i, num_segments, *tag; potrace_dpoint_t (*c)[3]; potrace_state_t *trace = NULL; Data_Get_Struct(klass, potrace_state_t, trace); fprintf(out, "<svg xmlns=\"http://www.w3.org/2000/svg\" version=\"1.1\""); fprintf(out, " width=\"%d\" height=\"%d\">", NUM2INT(rb_iv_get(klass, "@width")), NUM2INT(rb_iv_get(klass, "@height"))); fprintf(out, "<path fill-rule=\"evenodd\" fill=\"rgb(0,0,0)\" d=\""); if (trace->status == POTRACE_STATUS_OK) { path = trace->plist; while (path != NULL) { num_segments = path->curve.n; tag = path->curve.tag; c = path->curve.c; SVG_MOVE_TO(out, c[num_segments-1][2]); for (i = 0; i < num_segments; i++) { switch (tag[i]) { case POTRACE_CORNER: SVG_LINE_TO(out, c[i][1]); SVG_LINE_TO(out, c[i][2]); break; case POTRACE_CURVETO: SVG_CURVE_TO(out, c[i]); break; } } path = path->next; } } fprintf(out, "\" /></svg>"); size = ftell(out); out_buffer = ALLOC_N(char, size); rewind(out); fread(out_buffer, 1, size, out); fclose(out); svg = rb_str_new(out_buffer, size); xfree(out_buffer); return svg; }
Trace the given bitmap
bitmap
- an instance of Potracer::Bitmap. If not given the +@bitmap+ is
used.
params
- an instance of Potracer::Params. If not given +@params+ is used.
block
- optional block called to report trace progress
# File lib/potracer.rb, line 23 def trace(bitmap = nil, params = nil, &block) if block_given? do_trace(bitmap || @bitmap, params || @params, &block) else do_trace(bitmap || @bitmap, params || @params) end end