1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 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
|
#!/usr/bin/env python3
#
# ppmrotate.py: Rotate PPM images
#
# AUTHOR: Glynn Clements (Python version)
# Vaclav Petras (separate script)
# Earlier Bourne script version by Hamish Bowman,
# https://grasswiki.osgeo.org/wiki/Talk:Color_tables
#
# (C) 2009-2017 by the GRASS Development Team
# This program is free software under the GNU General Public
# License (>=v2). Read the file COPYING that comes with GRASS
# for details.
#
import sys
import os
import atexit
import array
import grass.script as grass
tmp_img = None
height = None
width = None
def cleanup():
if tmp_img:
grass.try_remove(tmp_img)
# def rotate(src, dst):
# grass.call(["convert", "-rotate", "90", src, dst])
def read_ppm(src):
global width, height
fh = open(src, "rb")
text = fh.read()
fh.close()
i = 0
j = text.find("\n", i)
if text[i:j] != "P6":
raise OSError(text[i:j] + " != P6. Is the file PPM?")
i = j + 1
j = text.find("\n", i)
w, h = text[i:j].split()
width = int(w)
height = int(h)
i = j + 1
j = text.find("\n", i)
maxval = text[i:j]
if int(maxval) != 255:
raise OSError("Max value in image != 255")
i = j + 1
return array.array("B", text[i:])
def write_ppm(dst, data):
w = height
h = width
fh = open(dst, "wb")
fh.write("P6\n%d %d\n%d\n" % (w, h, 255))
data.tofile(fh)
fh.close()
def rotate_ppm(srcd):
dstd = array.array("B", len(srcd) * "\0")
for y in range(height):
for x in range(width):
for c in range(3):
old_pos = (y * width + x) * 3 + c
new_pos = (x * height + (height - 1 - y)) * 3 + c
dstd[new_pos] = srcd[old_pos]
return dstd
def flip_ppm(srcd):
dstd = array.array("B", len(srcd) * "\0")
stride = width * 3
for y in range(height):
dy = height - 1 - y
dstd[dy * stride : (dy + 1) * stride] = srcd[y * stride : (y + 1) * stride]
return dstd
def ppmtopng(dst, src):
if grass.find_program("g.ppmtopng", "--help"):
grass.run_command("g.ppmtopng", input=src, output=dst, quiet=True)
elif grass.find_program("pnmtopng"):
fh = open(dst, "wb")
grass.call(["pnmtopng", src], stdout=fh)
fh.close()
elif grass.find_program("convert"):
grass.call(["convert", src, dst])
else:
grass.fatal(_("Cannot find g.ppmtopng, pnmtopng or convert"))
def convert_and_rotate(src, dst, flip=False):
global tmp_img
ppm = read_ppm(src)
if flip:
ppm = flip_ppm(ppm)
ppm = rotate_ppm(ppm)
to_png = False
if dst.lower().endswith(".png"):
to_png = True
if to_png:
tmp_img = grass.tempfile() + ".ppm"
# TODO: clean up the file
else:
tmp_img = dst
write_ppm(tmp_img, ppm)
if to_png:
ppmtopng(dst, tmp_img)
def main():
os.environ["GRASS_OVERWRITE"] = "1"
infile = sys.argv[1]
outfile = sys.argv[2]
convert_and_rotate(infile, outfile, flip=False)
if __name__ == "__main__":
atexit.register(cleanup)
main()
|