Skip to content

Instantly share code, notes, and snippets.

@AlexMeuer
Last active August 1, 2017 08:48
Show Gist options
  • Save AlexMeuer/2f4ae42483cac6468511151ae4ec2560 to your computer and use it in GitHub Desktop.
Save AlexMeuer/2f4ae42483cac6468511151ae4ec2560 to your computer and use it in GitHub Desktop.
Converts a html image map into a json array where (optionally) each coordinate is transformed into a percentage (0.0 -> 1.0) based on the given width and height.
#!/usr/bin/env python
from __future__ import division
import sys
import argparse
import xml.etree.ElementTree as ET
import os.path
py3 = sys.version_info[0] > 2 # Check if python2 or python3
parser = argparse.ArgumentParser(description="Convert a html image map to a json equivalent. (For use with 'http://imagemap-generator.dariodomi.de/')")
parser.add_argument('width', type=int, help='Width of the image to do the mapping for.')
parser.add_argument('height', type=int, help='Height of the image to do the mapping for.')
parser.add_argument('in_path', nargs='?', default=None, type=str,
help='Relative path to a file containing only the html image map. Omit to read from STDIN instead.')
parser.add_argument('out_path', nargs='?', default=None, type=str,
help='Relative file path to write json output to. Omit to print to STDOUT instead.')
parser.add_argument('--relative', action='store_true',
help='Transform absolute pixel coords into percentages in the rang 0.0 -> 1.0')
args = parser.parse_args(sys.argv[1:])
# If the destination file exists, ask whether to overwrite.
if args.out_path is not None and os.path.isfile(args.out_path):
prompt = "{} already exists, overwrite? (Y/N): ".format(args.out_path)
if py3:
result = input(prompt)
else:
result = raw_input(prompt)
if not result.startswith('Y') and not result.startswith('y'):
print("[Aborting]")
exit(2)
# Parse the data into element tree and get the root.
if args.in_path is None:
try:
root = ET.fromstring(sys.stdin.read())
except ET.ParseError as e:
print(e)
exit(1)
else:
try:
root = ET.parse(args.in_path).getroot()
except IOError as e:
print(e)
exit(1)
# Find the map tag (check root and its children)
if root.tag == 'map':
mapElement = root
else:
mapElement = root.find('map')
if mapElement is None:
print("No map element found!")
exit(1)
# Stores and transforms rectangle areas.
class Area:
def __init__(self, tag, coord_list, precision=4):
self.tag = tag
self.precision = precision
self.startX = coord_list[0]
self.startY = coord_list[1]
self.endX = coord_list[2]
self.endY = coord_list[3]
# Changes coords from absolute pixels to percentages in the range (0.0 -> 1.0)
def transform(self, width, height):
self.startX = round(self.startX / width, self.precision)
self.startY = round(self.startY / height, self.precision)
self.endX = round(self.endX / width, self.precision)
self.endY = round(self.endY / height, self.precision)
def __str__(self):
return '{{"tag":"{}", "startX":{},"startY":{},"endX":{},"endY":{}}}'\
.format(self.tag, self.startX, self.startY, self.endX, self.endY)
def __repr__(self):
return self.__str__()
areaList = []
# Find all areas of the map.
for area in mapElement.findall('area'):
if area.attrib.get('shape') == 'rect':
a = Area(area.attrib.get('title'), map(int, area.attrib.get('coords').split(',')))
if args.relative:
a.transform(args.width, args.height) # Change absolute pixels into relative percentages
areaList.append(a)
elif args.out_path is not None: # Only output warning if not writing result to STDOUT
print("Found {} shape, only rect is supported. Skipping: {}".format(area.attrib.get('shape'), area.attrib.get('coords')))
if args.out_path is None:
print(areaList)
else:
with open(args.out_path, 'w') as file:
# Write the areas to file as a json array.
file.write("{}".format(areaList))
print("[Done]")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment