Add separate left/right/top/bottom arguments to pipwindow
#!/usr/bin/env python
+import argparse
+
import png
# pipwindow
@@ -27,28 +29,42 @@ def window(tl, br, inp, out):
input file which should be a PNG image.
"""
+ left, top = tl
+ right, bottom = br
+
r = png.Reader(file=inp)
x, y, pixels, meta = r.asDirect()
- if not (0 <= tl[0] < br[0] <= x):
+
+ if top is None:
+ top = 0
+ if left is None:
+ left = 0
+ if bottom is None:
+ bottom = y
+ if right is None:
+ right = x
+
+ if not (0 <= left < right <= x):
raise NotImplementedError()
- if not (0 <= tl[1] < br[1] <= y):
+ if not (0 <= top < bottom <= y):
raise NotImplementedError()
- # Compute left and right bounds for each row
- l = tl[0] * meta["planes"]
- r = br[0] * meta["planes"]
+ # Compute left and right index bounds for each row,
+ # given that each row is a flat row of values.
+ l = left * meta["planes"]
+ r = right * meta["planes"]
def itercrop():
"""An iterator to perform the crop."""
for i, row in enumerate(pixels):
- if i < tl[1]:
+ if i < top:
continue
- if i >= br[1]:
+ if i >= bottom:
# Same as "raise StopIteration"
return
yield row[l:r]
- meta["size"] = (br[0] - tl[0], br[1] - tl[1])
+ meta["size"] = (right - left, bottom - top)
w = png.Writer(**meta)
w.write(out, itercrop())
@@ -60,17 +76,23 @@ def main(argv=None):
argv = sys.argv
argv = argv[1:]
- tl = (0, 0)
- br = tuple(map(int, argv[:2]))
- if len(argv) >= 4:
- tl = br
- br = tuple(map(int, argv[2:4]))
- if len(argv) in (2, 4):
- f = sys.stdin
- else:
- f = open(argv[-1], "rb")
-
- return window(tl, br, f, png.binary_stdout())
+ parser = argparse.ArgumentParser(description=__doc__)
+ parser.add_argument("--top", type=int)
+ parser.add_argument("--left", type=int)
+ parser.add_argument("--bottom", type=int)
+ parser.add_argument("--right", type=int)
+ parser.add_argument(
+ "input", nargs="?", default="-", type=png.cli_open, metavar="PNG"
+ )
+
+ args = parser.parse_args(argv)
+
+ return window(
+ (args.left, args.top),
+ (args.right, args.bottom),
+ args.input,
+ png.binary_stdout(),
+ )
if __name__ == "__main__":
