diff options
author | Daniel Friesel <derf@finalrewind.org> | 2020-12-27 05:55:04 +0100 |
---|---|---|
committer | Daniel Friesel <derf@finalrewind.org> | 2020-12-27 05:55:04 +0100 |
commit | 13a6832bb4f9ec68d26ae59c8dd1260279e3e70a (patch) | |
tree | 1262192a82a5beeeffd287dbdf0d535fe66df974 /lib | |
parent | b12626394101807d2644b92ffb50dcae2b0febfa (diff) |
heuristics, whoop whoop
Diffstat (limited to 'lib')
-rwxr-xr-x | lib/export-carriage.py | 90 |
1 files changed, 90 insertions, 0 deletions
diff --git a/lib/export-carriage.py b/lib/export-carriage.py new file mode 100755 index 0000000..69e5133 --- /dev/null +++ b/lib/export-carriage.py @@ -0,0 +1,90 @@ +#!/usr/bin/env python3 + +import numpy as np +import subprocess +import sys + + +class SVGObject: + def __init__(self, attrlist): + self.id = attrlist[0] + self.x = float(attrlist[1]) + self.y = float(attrlist[2]) + self.w = float(attrlist[3]) + self.h = float(attrlist[4]) + self.x_ = self.x + self.w + self.y_ = self.y + self.h + + def is_path(self): + return self.id.startswith("path") + + def is_tspan(self): + return self.id.startswith("tspan") + + def __repr__(self): + return "{}<x={}, y={}, w={}, h={}>".format( + self.id, self.x, self.y, self.w, self.h + ) + + +def main(infile, outfile): + ret = subprocess.run( + ["inkscape", "--query-all", infile], capture_output=True, check=True + ) + + objects = ret.stdout.decode("ascii").split("\n") + + # remove last (empty) line + objects.pop() + + # objects = [[ID, X, Y, W, H], ... ] + objects = list(map(lambda x: x.split(","), objects)) + objects = list(map(lambda x: SVGObject(x), objects)) + + ys = list() + for o in objects: + if o.is_path() and o.h > 2 and o.h < 4 and o.w > 10: + ys.append(o.y) + bins = np.bincount(ys) + + candidates = list(filter(lambda i: bins[i] > 2, range(len(bins)))) + + crop_y_min = np.min(candidates) - 1 + crop_y_max = np.max(candidates) + 4 + + objects_to_delete = list() + x_positions = list() + + for o in objects: + if (o.is_path or o.is_tspan) and (o.y < crop_y_min or o.y_ > crop_y_max): + objects_to_delete.append(o.id) + elif o.is_path and o.y >= crop_y_min and o.y_ <= crop_y_max: + x_positions.append(o.x) + x_positions.append(o.x_) + + crop_x_min = int(np.min(x_positions)) + crop_x_max = int(np.max(x_positions)) + 1 + + objects_to_delete = ",".join(objects_to_delete) + + export_area = f"--export-area={crop_x_min}:{crop_y_min}:{crop_x_max}:{crop_y_max}" + select_objects = f"--select={objects_to_delete}" + + subprocess.run( + [ + "xvfb-run", + "inkscape", + export_area, + select_objects, + "--verb=EditDelete", + "--batch-process", + "--export-dpi=600", + "-o", + outfile, + infile, + ] + ) + + +if __name__ == "__main__": + main(*sys.argv[1:]) |