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