Giter Site home page Giter Site logo

trathborne / guillot Goto Github PK

View Code? Open in Web Editor NEW
15.0 0.0 1.0 22 KB

Fits a collection of differently-sized images on the smallest number of same-sized pages, separable by only guillotine cuts (across the paper).

License: GNU General Public License v3.0

Ruby 97.53% Shell 2.47%

guillot's Introduction

Guillot

A naive and greedy but occasionally clever algorithm for placing a collection of differently-sized images on the smallest possible number of same-sized pages, ensuring that the images can be separated by making only guillotine cuts, that is, all the way across the paper.

I found a lot of academic papers on the topic, but not very much working code. The closest I got was opcut, but it ran for over 400 hours and never terminated on my sample input.

So, I wrote my own, and it runs in much less time, giving great results. It worked great for my use case (576 images with 430 distinct sizes) so I stopped, but cleaned it up for you. If I do any more, it will be to resolve the TODO items in the code, which are points of tuning and finessing. Pull requests welcome!

License

Copyright 2020 by Tom Rathborne [email protected]. Licensed under GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007. See file LICENSE for a copy of the license.

Requirements

  • Ruby ... not sure of the minimum version, since this is my first Ruby program! I used ruby 2.7.0p0 (2019-12-25 revision 647ee6f091) [x86_64-linux-gnu] as found in Ubuntu 20.04.
  • Ruby's yaml and optparse modules which seem to be part of libruby.
  • GraphicsMagick, in particular the gm program GraphicsMagick 1.3.35 2020-02-23 Q16 as found in Ubuntu 20.04.
  • (optional) GNU parallel, in case you want to parallelize the gm work.

Caveats

  • All dimensions are in pixels.
  • If you use rotation, the image directory must be writable, and slashes in your filenames will break the temporary-rotated-image mechanism.
  • It might break if you have spaces or quotes in your filenames. Don't do that.
  • The drawing process might break if the command lines get too long, but the gm draw commands can be put into a text file, so it would be an easy fix.

Usage

There are 3 basic steps:

  1. Generate a YAML description of the dimensions of each input file. This is a simple shell wrapper around gm identify. The input files are structured just like input to opcut, but guillot-calc only pays attention to the items section.
    $ guillot-prep.sh *.png > input.yaml
  1. Fit these images into some fixed page size. Could take a very long time. The verbose output is mostly useful for knowing that it is still working and making a guess as to when it will finish.
    $ guillot-calc.rb --help
    Usage: guillot-calc.rb [options]
        -i, --input FILE                 [Mandatory] YAML input filename
        -g, --geometry WxH               [Mandatory] Page geometry in pixels
        -v, --[no-]verbose               [default: false] Verbose output
        -r, --[no-]rotate                [default: false] Also try rotating each image 90'
        -s, --spacing PIXELS             [default: 0] Space between images
        -m, --margin PIXELS              [default: 0] Page margin
        -e, --enough FRACTION            [default: 1.0] (0.5 to 1.0) Stop searching whenever this fraction of target area is covered

    $ guillot-calc.rb -i input.yaml -g 8000x6000 -v > layout.yaml
  1. Render the images on top of a template page. guillot-draw outputs command lines which you can run with e.g. GNU parallel.
    $ guillot-draw.rb --help
    Usage: guillot-draw.rb [options] | parallel -j <CORES>
        -l, --layout FILE                [Mandatory] YAML layout filename
        -t, --template TEMPLATE          [Mandatory] Page template image or gm expression
        -i, --[no-]image                 [default: true] Draw image
        -b, --border PIXELS              [default: 0] Width of black border around images
        -n, --[no-]filename              [default: false] Draw filename over each image
        -f, --fontsize PIXELS            [default: 120] Font size; implies -n

    $ guillot-draw.rb -l layout.yaml -t base_8000x6000.png | parallel -j 4

That's it! The output will be in page_*.png

Instead of a template filename, you could theoretically use a GraphicsMagick xc: input, e.g. -t '-size 8000x6000 -type Grayscale xc:white', but my GraphicsMagick doesn't seem to support xc:.

guillot's People

Contributors

trathborne avatar

Stargazers

Bhargav Tarpara avatar  avatar  avatar Joseph Curtis avatar Bryant Gillespie avatar Sebastian Wittenkamp avatar  avatar Cal Bryant avatar Patrick Davies avatar Rafael Ristovski avatar Armando Neto avatar Caio Begotti avatar  avatar  avatar Jayson Rhynas avatar

Forkers

krackers

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.