Precompute the Fraction instances for x coordinates
@@ -127,19 +127,23 @@ def yield_fun_rows(size, bitdepth, pattern):
typecode = "B"
pfun, args = pattern_function(pattern)
+ # The coordinates are an integer + 0.5,
+ # effectively sampling each pixel at its centre.
+ # This is morally better, and produces all 256 sample values
+ # in a 256-pixel wide gradient.
+
+ # We make a list of x coordinates here and re-use it,
+ # because Fraction instances are slow to allocate.
+ xs = [Fraction(x, 2*width) for x in range(1, 2*width, 2)]
+
# The general case is a function in x and y,
# but if the function only takes one argument,
# it's handled in special cases that are a lot faster.
if args == "xy":
- # We add (0.5, 0.5) to each coordinate, effectively sampling
- # each pixel at its centre.
- # This is morally better, and produces all 256 sample values
- # in a 256-pixel wide gradient.
for y in range(height):
a = array(typecode)
fy = Fraction(Fraction(y + 0.5), height)
- for x in range(1, 2*width, 2):
- fx = Fraction(x, 2*width)
+ for fx in xs:
a.append(int(round(maxval * pfun(fx, fy))))
yield a
return
@@ -148,8 +152,7 @@ def yield_fun_rows(size, bitdepth, pattern):
# For functions in x only, it's a _lot_ faster
# to generate a single row and repeatedly yield it
a = array(typecode)
- for x in range(1, 2*width, 2):
- fx = Fraction(x, 2*width)
+ for fx in xs:
a.append(int(round(maxval * pfun(x=fx))))
for y in range(height):
yield a
