Skip to main content

Package for cropping directories of images based on a pivot.

Project description

PivotCrop

This Python script consumes a list of input directories of PNG files and crops them. The user must specify a pivot for each group of directories. This pivot location is guaranteed to be Preserved during the crop. For example, (0.5, 0.5) ensures that the pivot is centered on the image. Use config.py to edit the input config.

Email: joshikatsu@gmail.com

Instructions

Install the package using pip install pivotcrop.

Example usage:

from pivotcrop import PivotCropper

PivotCropper(
    output_dir="output",
    root_dir="testdata",
    pivot_groups={
        # All directories with images using pivot (0.5, 1) should be configured here.
        (0.5, 1): [
            # Two directories that should share the same bounding box.
            BBoxGroup("Images/A", "Images/B"),
            # Another directory using same pivot, but a different bounding box.
            BBoxGroup("Images/C")
        ],
        # Entry with a different pivot
        (0.5, 0.5): [
            BBoxGroup("Images/D"),
            # A directory where each image gets its own bounding box.
            IndependentDir("Images/E")
        ],
    }
).crop()

The config entries are meant to be relative to the current working directory. The directory structure is preserved in the output.

Pivot x y is [0, 1], with [0, 0] at the top left.

Algorithm

We simply loop over all directories and keep track of minimum and maximum points for the bounding box. The main complexity of this script comes from ensuring that the cropped image still has the same relative pivot as the original.

Consider an animation where all images can be encompassed by a bounding box $B = (\text{min}_x, \text{min}_y), (\text{max}_x, \text{max}_y)$. Our algorithm produces a new bounding box $B' = (\text{min}_x', \text{min}_y'), (\text{max}_x', \text{max}_y')$. We must adjust $B$ such that the relative position of the pivot $(P_x, P_y)$ is preserved, where $P_x, P_y \in (0.0, 1.0)$.

One way to describe this constraint is to say that on each axis, the lower bound must change proportionally to the upper bound. The ratio of this proprotion is determined by the corresponding component of the pivot.

If we define the change to our upper and lower bounds on the $x$ axis as:

$\Delta \text{min}_x = \text{min}_x - \text{min}_x'$

$\Delta \text{max}_x = \text{max}_x' - \text{max}_x$

To retain the same pivot point when cropping, we must make sure that the following ratio holds:

$$\frac{\Delta \text{min}_x}{\Delta \text{max}_x} = \frac{P_x}{(1 - P_x)}$$

For simplicity, let $Pr_x = \frac{P_x}{(1 - P_x)}$ be the pivot ratio for the $x$-axis.

If we need to reduce the minimum to maintain the ratio ($\frac{\Delta \text{min}_x}{\Delta \text{max}_x} \gt Pr_x$), we subtract an offset term to $\text{min}_x$:

$$\frac{\Delta \text{min}_x - \text{Offset}_x}{\Delta \text{max}_x} = Pr_x$$

$$\Delta \text{min}_x - \text{Offset}_x = Pr_x \times \Delta \text{max}_x$$

$$\text{Offset}_x = \Delta \text{min}_x - Pr_x \times \Delta \text{max}_x$$

If we need to increase the maximum to maintain the ratio $\frac{\Delta \text{min}_x}{\Delta \text{max}_x} \lt Pr_x$, we add an offset to $\text{max}_x$:

$$\frac{\Delta \text{min}_x}{\Delta \text{max}_x - \text{Offset}_x} = Pr_x$$

$$\Delta \text{min}_x = Pr_x \times (\Delta \text{max}_x - \text{Offset}_x)$$

$$\frac{\Delta \text{min}_x}{Pr_x} = \Delta \text{max}_x - \text{Offset}_x$$

$$\text{Offset}_x = \Delta \text{max}_x - \frac{\Delta \text{min}_x}{Pr_x}$$

Same deal for the $y$ axis.

Development

To publish to pip, use:

python setup.py sdist bdist_wheel
python -m twine check dist/*
python -m twine upload dist/*

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

pivotcrop-0.1.1.tar.gz (13.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

pivotcrop-0.1.1-py3-none-any.whl (13.7 kB view details)

Uploaded Python 3

File details

Details for the file pivotcrop-0.1.1.tar.gz.

File metadata

  • Download URL: pivotcrop-0.1.1.tar.gz
  • Upload date:
  • Size: 13.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.9

File hashes

Hashes for pivotcrop-0.1.1.tar.gz
Algorithm Hash digest
SHA256 6b375284615cacf5d7f81436be4b56fd74594b99b322542458a0bfb24b155ff6
MD5 35d3fe1da957c76fc5e59137798f6770
BLAKE2b-256 3a8c23efd80074e0e745d5c2c21162fc246120bf22b8ca1ce390b0d22a62073c

See more details on using hashes here.

File details

Details for the file pivotcrop-0.1.1-py3-none-any.whl.

File metadata

  • Download URL: pivotcrop-0.1.1-py3-none-any.whl
  • Upload date:
  • Size: 13.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.9

File hashes

Hashes for pivotcrop-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 3beb47c216cde12e3d52906a8d002a1c030c6dc239508311c30fd981937d9c51
MD5 39d06e5d037de4398f69eb1837ad60ab
BLAKE2b-256 2e5708370ee4362fb57a6993a9138eee41475e6ac92815113d57d16d0fb1a31c

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page