Module: Autotrace

Defined in:
lib/autotrace.rb,
lib/autotrace/ffi.rb,
lib/autotrace/version.rb

Overview

Autotrace is a Ruby gem that provides bindings to the Autotrace library, which converts raster images (like PNG) into vector graphics (like SVG).

The library supports various input and output formats, and provides extensive configuration options for controlling the tracing process.

Examples:

Converting a PNG to SVG

Autotrace.trace_image("input.png", output_suffix: "svg")

Converting with custom options

Autotrace.trace_image("input.png",
  output_suffix: "svg",
  background_color: "FFFFFF",
  error_threshold: 1.0
)

Defined Under Namespace

Modules: FFI Classes: Error

Constant Summary collapse

VERSION =
"0.1.12"

Class Attribute Summary collapse

Class Method Summary collapse

Class Attribute Details

.initializedObject

Returns the value of attribute initialized.



26
27
28
# File 'lib/autotrace.rb', line 26

def initialized
  @initialized
end

Class Method Details

.init_autotracevoid

This method returns an undefined value.

Initialize the Autotrace library. This must be called before any other operations. It sets up input handlers and other necessary components.



32
33
34
35
36
37
38
39
40
# File 'lib/autotrace.rb', line 32

def init_autotrace
  return if initialized

  FFI.autotrace_init
  FFI.at_input_init
  FFI.at_module_init

  self.initialized = true
end

.trace_image(input_image, output_suffix: "svg", output_file: nil, background_color: nil, centerline: false, charcode: 0, color_count: 0, corner_always_threshold: 60.0, corner_surround: 4, corner_threshold: 100.0, despeckle_level: 0, despeckle_tightness: 2.0, dpi: 0, error_threshold: 2.0, filter_iterations: 4, line_reversion_threshold: 0.01, line_threshold: 1.0, noise_removal: 0.99, preserve_width: false, remove_adjacent_corners: false, tangent_surround: 3, width_weight_factor: 0.0) ⇒ File

Convert a raster image to a vector graphic format.

Parameters:

  • input_image (String)

    Path to the input raster image

  • output_suffix (String) (defaults to: "svg")

    Desired output format (e.g. “svg”, “eps”)

  • output_file (String, nil) (defaults to: nil)

    Path to write the output file. If nil, the output file will be “<basename>.<output_suffix>” in the same folder as the input file.

  • background_color (String, nil) (defaults to: nil)

    Background color in hex format (e.g. “FFFFFF”)

  • centerline (Boolean) (defaults to: false)

    Whether to trace along the centerline

  • charcode (Integer) (defaults to: 0)

    Character code for text output

  • color_count (Integer) (defaults to: 0)

    Number of colors to use

  • corner_always_threshold (Float) (defaults to: 60.0)

    Threshold for corner detection

  • corner_surround (Integer) (defaults to: 4)

    Number of points to consider for corner detection

  • corner_threshold (Float) (defaults to: 100.0)

    Threshold for corner detection

  • despeckle_level (Integer) (defaults to: 0)

    Level of despeckling to apply

  • despeckle_tightness (Float) (defaults to: 2.0)

    Tightness of despeckling

  • dpi (Integer) (defaults to: 0)

    DPI setting for output (affects MIF output scaling)

  • error_threshold (Float) (defaults to: 2.0)

    Error threshold for curve fitting

  • filter_iterations (Integer) (defaults to: 4)

    Number of filter iterations

  • line_reversion_threshold (Float) (defaults to: 0.01)

    Threshold for line reversion

  • line_threshold (Float) (defaults to: 1.0)

    Threshold for line detection

  • noise_removal (Float) (defaults to: 0.99)

    Level of noise removal

  • preserve_width (Boolean) (defaults to: false)

    Whether to preserve line width

  • remove_adjacent_corners (Boolean) (defaults to: false)

    Whether to remove adjacent corners

  • tangent_surround (Integer) (defaults to: 3)

    Number of points to consider for tangent detection

  • width_weight_factor (Float) (defaults to: 0.0)

    Weight factor for width preservation

Returns:

  • (File)

    A File object pointing to the newly created vector file

Raises:

  • (Error)

    If any step in the conversion process fails



73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
# File 'lib/autotrace.rb', line 73

def trace_image(
  input_image,
  output_suffix: "svg",
  output_file: nil,
  background_color: nil,
  centerline: false,
  charcode: 0,
  color_count: 0,
  corner_always_threshold: 60.0,
  corner_surround: 4,
  corner_threshold: 100.0,
  despeckle_level: 0,
  despeckle_tightness: 2.0,
  dpi: 0,
  error_threshold: 2.0,
  filter_iterations: 4,
  line_reversion_threshold: 0.01,
  line_threshold: 1.0,
  noise_removal: 0.99,
  preserve_width: false,
  remove_adjacent_corners: false,
  tangent_surround: 3,
  width_weight_factor: 0.0
)
  init_autotrace

  # 1. Create the input & output option structs
  fitting_opts_ptr = FFI.at_fitting_opts_new
  raise Error, "Failed to allocate fitting options" if fitting_opts_ptr.null?

  output_opts_ptr = FFI.at_output_opts_new
  raise Error, "Failed to allocate output options" if output_opts_ptr.null?

  # 2. Fill in all the fields from your arguments.
  configure_fitting_opts(
    fitting_opts_ptr,
    background_color: background_color,
    centerline: centerline,
    charcode: charcode,
    color_count: color_count,
    corner_always_threshold: corner_always_threshold,
    corner_surround: corner_surround,
    corner_threshold: corner_threshold,
    despeckle_level: despeckle_level,
    despeckle_tightness: despeckle_tightness,
    error_threshold: error_threshold,
    filter_iterations: filter_iterations,
    line_reversion_threshold: line_reversion_threshold,
    line_threshold: line_threshold,
    noise_removal: noise_removal,
    preserve_width: preserve_width,
    remove_adjacent_corners: remove_adjacent_corners,
    tangent_surround: tangent_surround,
    width_weight_factor: width_weight_factor
  )

  configure_output_opts(output_opts_ptr, dpi: dpi)

  # 3. Acquire input handler & read the bitmap
  input_handler = FFI.at_input_get_handler(input_image)
  raise Error, "Failed to get input handler for #{input_image}" if input_handler.null?

  bitmap = FFI.at_bitmap_read(input_handler, input_image, nil, nil, nil)
  raise Error, "Failed to read bitmap from #{input_image}" if bitmap.null?

  # 4. Create splines
  splines = FFI.at_splines_new(bitmap, fitting_opts_ptr, nil, nil)
  raise Error, "Failed to create splines" if splines.null?

  # 5. Output handler
  output_handler = FFI.at_output_get_handler_by_suffix(output_suffix)
  raise Error, "Unknown output format: .#{output_suffix}" if output_handler.null?

  # 6. Determine output file path
  if output_file.nil? || output_file.empty?
    # default to "<basename>.<suffix>"
    output_basename = File.basename(input_image, ".*")
    output_file = "#{output_basename}.#{output_suffix}"
  end

  # 7. Write to a real file
  c_file = FFI::CStdLib.fopen(output_file, "wb")
  raise Error, "Failed to open #{output_file} with C fopen" if c_file.null?

  FFI.at_splines_write(
    output_handler,
    c_file,
    output_file,
    output_opts_ptr,
    splines,
    nil, # msg_func
    nil  # msg_data
  )

  # Close
  FFI::CStdLib.fclose(c_file)

  File.open(output_file, "rb")
end