diff --git a/README.md b/README.md
index ca2a50d..9d149f1 100644
--- a/README.md
+++ b/README.md
@@ -3,7 +3,8 @@ Generate pixel art as vector image.
![Alt text](/examples/example-0.svg "example-0")
![Alt text](/examples/example-1.svg "example-1")
-![Alt text](/examples/example-2.svg "example-1")
+![Alt text](/examples/example-2.svg "example-2")
+![Alt text](/examples/example-l-tiles.svg "l-tiles")
## Usage
diff --git a/examples/example-l-tiles.svg b/examples/example-l-tiles.svg
new file mode 100644
index 0000000..77dbb72
--- /dev/null
+++ b/examples/example-l-tiles.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/pictor/core.py b/pictor/core.py
index b7385f6..f35ba29 100644
--- a/pictor/core.py
+++ b/pictor/core.py
@@ -1,6 +1,7 @@
import argparse
import helpers
import random
+from math import log2
class Pictor:
@@ -31,11 +32,15 @@ def parse_arguments():
help="Pixel corner radius.")
parser.add_argument("-rb", "--rainbow", action="store_true",
help="Use rainbow colors instead of a fixed color.")
+ parser.add_argument("-lt", "--l-tiling", action="store_true",
+ help="Generate an L-tiling.")
+ parser.add_argument("-op", "--opacity", default=0.6,
+ help="Opacity of a pixel.")
parser.add_argument("-o", "--out", type=str, default="out.svg", metavar="path",
help="The path to the output file.")
parser.add_argument("-v", "--verbose", action="store_true",
help="Print additional outputs")
- parser.add_argument("--version", action="version", version="Pictor 0.1")
+ parser.add_argument("--version", action="version", version="Pictor 0.2")
args = parser.parse_args()
@@ -64,7 +69,26 @@ def parse_arguments():
print("Contrasts need to be between 0 and 1 and min contrast needs to be smaller than max contrast.")
return False, None
- args.border[0] = int(args.border[0])
+ if args.l_tiling:
+ if args.dim[0] != args.dim[1]:
+ print("x-dim and y-dim must to be equal.")
+ return False, None
+ number_of_tiles = args.dim[0] / (2*args.scale)
+
+ if log2(number_of_tiles) != int(log2(number_of_tiles)):
+ print("The ratio dim/(2*scale) must be a power of 2.")
+ print("Now the ratio is", str(number_of_tiles))
+ return False, None
+
+ if args.dim[0] % 4 != 0:
+ print("Dimension must be a multiple of 4.")
+ return False, None
+
+ if args.scale % 4 != 0:
+ print("Scale must be a multiple of 4.")
+ return False, None
+
+ args.border[0] = float(args.border[0])
return True, args
@@ -77,7 +101,13 @@ def __init__(self):
# depending on the arguments create the right image
dims = self.get_image_dimensions()
- image = self.create_random_image(dims, self.args.color)
+
+ if self.args.l_tiling:
+ if self.args.out == "out.svg":
+ self.args.out = "{0}_{0}_s{1}.svg".format(int(self.args.dim[0] / (self.args.scale)), self.args.scale)
+ image = self.create_l_tiling(dims)
+ else:
+ image = self.create_random_image(dims, self.args.color)
self.export_svg(image, dims)
@@ -100,9 +130,96 @@ def get_contrasts(self, cmyk_color):
return [contrast_range_factor["min"] + step * contrast_step_size for step in
range(0, self.args.num_shadings)]
- def create_random_image(self, dims, rgb_color):
+ def place_l_tile_pixels(self, rotation, size, color, x, y, pixel_dict):
+
+ if rotation == 0:
+ # standard L
+ pixel_dict[(x, y)] = color
+ pixel_dict[(x, y+size//2)] = color
+ pixel_dict[(x+size//2, y+size//2)] = color
+
+ elif rotation == 90:
+ # _|
+ pixel_dict[(x+size//2, y)] = color
+ pixel_dict[(x+size//2, y+size//2)] = color
+ pixel_dict[(x, y+size//2)] = color
+
+ elif rotation == 180:
+ # ~|
+ pixel_dict[(x, y)] = color
+ pixel_dict[(x+size//2, y)] = color
+ pixel_dict[(x+size//2, y+size//2)] = color
+
+ elif rotation == 270:
+ # |~
+ pixel_dict[(x, y)] = color
+ pixel_dict[(x+size//2, y)] = color
+ pixel_dict[(x, y+size//2)] = color
+ else:
+ raise Exception("invalid rotation")
+
+ return
+
+ def placement(self, x_offset, y_offset, rotation, size, pixel_dict):
+ if size < self.args.scale:
+ return " "
+ if size == self.args.scale:
+ color = (random.randint(0,255), random.randint(0,255), random.randint(0,255))
+ return self.place_l_tile_pixels(rotation, size, color, x_offset, y_offset, pixel_dict)
+ else:
+ if rotation == 0:
+ x_new_m, y_new_m = x_offset+size//4, y_offset+size//4
+ x_new_lo, y_new_lo = x_offset, y_offset
+ x_new_lu, y_new_lu = x_offset, y_offset + size//2
+ x_new_ru, y_new_ru = x_offset + size//2, y_offset+ size//2
+ elif rotation == 90:
+ x_new_m, y_new_m = x_offset+size//4, y_offset+size//4
+ x_new_lo, y_new_lo = x_offset, y_offset+size//2
+ x_new_lu, y_new_lu = x_offset+size//2, y_offset+size//2
+ x_new_ru, y_new_ru = x_offset+size//2, y_offset
+ elif rotation == 180:
+ x_new_m, y_new_m = x_offset+size//4, y_offset+size//4
+ x_new_lo, y_new_lo = x_offset+size//2, y_offset+size//2
+ x_new_lu, y_new_lu = x_offset+size//2, y_offset
+ x_new_ru, y_new_ru = x_offset, y_offset
+ elif rotation == 270:
+ x_new_m, y_new_m = x_offset+size//4, y_offset+size//4
+ x_new_lo, y_new_lo = x_offset+size//2, y_offset
+ x_new_lu, y_new_lu = x_offset, y_offset
+ x_new_ru, y_new_ru = x_offset, y_offset + size//2
+
+ new_rotation_m = rotation
+ new_rotation_lo = (rotation + 270) % 360
+ new_rotation_lu = rotation
+ new_rotation_ru = (rotation + 90) % 360
+
+ middle = self.placement(x_new_m, y_new_m, new_rotation_m, size//2, pixel_dict)
+ lo = self.placement(x_new_lo, y_new_lo, new_rotation_lo, size//2, pixel_dict)
+ lu = self.placement(x_new_lu, y_new_lu, new_rotation_lu, size//2, pixel_dict)
+ ru = self.placement(x_new_ru, y_new_ru, new_rotation_ru, size//2, pixel_dict)
+
+ return
+
+
+ def create_l_tiling(self, dims):
+ """
+ :param dims : Image dimensions
+ :return:
"""
+ image = {"background": helpers.rgb_str_to_tuple(self.args.background),
+ "pixels": []}
+
+ pixel_dict = {}
+
+ self.placement(0, 0, 0, self.args.dim[0]/2, pixel_dict)
+
+ # print(pixel_dict)
+ image["pixels"] = [{"x" : x, "y" : y, "size" : self.args.scale/2, "color" : pixel_dict[(x,y)], "radius" : self.args.radius} for (x,y) in pixel_dict.keys() ]
+ return image
+
+ def create_random_image(self, dims, rgb_color):
+ """
:param dims: Image dimensions
:param rgb_color: A color in RGB format.
:return:
@@ -159,9 +276,11 @@ def export_svg(self, image, dims):
# write pixels
for pixel in image["pixels"]:
+ # print(pixel)
f.write(" 0 else "")
+ + ("fill-opacity=\"{0}\" ".format(self.args.opacity))
+ "style=\"fill: rgb({0},{1},{2});".format(*pixel["color"])
+ ("stroke-width:{0};stroke: rgb({1},{2},{3})"
.format(self.args.border[0], *helpers.rgb_str_to_tuple(self.args.border[1]))