The way I did it is to start with an array of boolean values the size of the picture above all set to true. Then make a list of every [x,y] value for all the pixels, and scramble the order of them. Then go through this scrambled list of values and look in the array of booleans at the truth value of any cell within a distance 5 of the pixel in question. A sum is kept of the inverses of the distances^2 of all the cells that are true out of those. The maximum this could come out to is 12.76. So the ratio of what the sum comes out to divided by 12.76 is compared to the ratio of the brightness of the grayscale image at that pixel divided by 255 (the maximum brightness). If the first ratio is greater than the second the array of booleans is set to False at that [x,y]. Then the array is converted to an image with True values making a pixel white and false black.
**Python Source Code**
from PIL import Image
import random
def main():
im = Image.open("lion.png")
map=[]
for i in range(0, im.size[1]):
row = []
for j in range(0, im.size[0]):
row.append(True)
map.append(row)
pixels = []
for i in range(0, im.size[0]):
for j in range(0, im.size[1]):
pixels.append([j,i])
random.shuffle(pixels)
for p in pixels:
sumbright = 0
for x in range(-5, 6):
for y in range(-5, 6):
if x!=0 or y !=0:
if p[0] +x >= 0 and p[0]+x < len(map):
if p[1]+y >=0 and p[1]+y < len(map[0]):
d = (x**2.0 + y**2.0)
if d**.5 <= 5:
if map[p[0]+x][p[1]+y] == True:
sumbright +=1.0/d
if 1.0*sumbright /12.78 > 1.0*im.getpixel((p[1],p[0])) / 255:
map[p[0]][p[1]] = False
im2 = Image.new("RGB", (im.size[0], im.size[1]))
for i in range(0, im.size[0]):
for j in range(0, im.size[1]):
if map[j][i] == True:
im2.putpixel((i,j), (255,255,255))
im2.save("lion2a.png")
main()
def main():
im = Image.open("lion.png")
map=[]
for i in range(0, im.size[1]):
row = []
for j in range(0, im.size[0]):
row.append(True)
map.append(row)
pixels = []
for i in range(0, im.size[0]):
for j in range(0, im.size[1]):
pixels.append([j,i])
random.shuffle(pixels)
for p in pixels:
sumbright = 0
for x in range(-5, 6):
for y in range(-5, 6):
if x!=0 or y !=0:
if p[0] +x >= 0 and p[0]+x < len(map):
if p[1]+y >=0 and p[1]+y < len(map[0]):
d = (x**2.0 + y**2.0)
if d**.5 <= 5:
if map[p[0]+x][p[1]+y] == True:
sumbright +=1.0/d
if 1.0*sumbright /12.78 > 1.0*im.getpixel((p[1],p[0])) / 255:
map[p[0]][p[1]] = False
im2 = Image.new("RGB", (im.size[0], im.size[1]))
for i in range(0, im.size[0]):
for j in range(0, im.size[1]):
if map[j][i] == True:
im2.putpixel((i,j), (255,255,255))
im2.save("lion2a.png")
main()
Also modified the code for doing 8 color or 3 bit dithered images, full or no red, full or no green, full or no blue...
Extreme close up:
For comparison, the state of the art is Floyd Steinberg dithering which for 8 colors produces images like this:
I think this way I'm doing it is a big improvement...
**Python Source Code**
from PIL import Image
import random
def main():
im = Image.open("parrot.png")
map=[]
for i in range(0, im.size[1]):
row = []
for j in range(0, im.size[0]):
row.append([True, True, True])
map.append(row)
pixels = []
for i in range(0, im.size[0]):
for j in range(0, im.size[1]):
pixels.append([j,i])
random.shuffle(pixels)
print(len(map[0]), len(map))
print(im.size[0], im.size[1])
for p in pixels:
sumbrightred = 0
sumbrightgreen = 0
sumbrightblue = 0
for x in range(-5, 6):
for y in range(-5, 6):
if x!=0 or y !=0:
if p[0] +x >= 0 and p[0]+x < len(map):
if p[1]+y >=0 and p[1]+y < len(map[0]):
d = (x**2.0 + y**2.0)
if d**.5 <= 5:
try:
if map[p[0]+x][p[1]+y][0] == True:
sumbrightred +=1.0/d
if map[p[0]+x][p[1]+y][1] == True:
sumbrightgreen +=1.0/d
if map[p[0]+x][p[1]+y][2] == True:
sumbrightblue +=1.0/d
except:
print(p[0]+x, p[1]+y)
if 1.0*sumbrightred /12.78 > 1.0*im.getpixel((p[1],p[0]))[0] / 255:
map[p[0]][p[1]][0] = False
if 1.0*sumbrightgreen /12.78 > 1.0*im.getpixel((p[1],p[0]))[1] / 255:
map[p[0]][p[1]][1] = False
if 1.0*sumbrightblue /12.78 > 1.0*im.getpixel((p[1],p[0]))[2] / 255:
map[p[0]][p[1]][2] = False
im2 = Image.new("RGB", (im.size[0], im.size[1]))
for i in range(0, im.size[0]):
for j in range(0, im.size[1]):
color = [0,0,0]
if map[j][i][0] == True:
color[0] = 255
if map[j][i][1] == True:
color[1] = 255
if map[j][i][2] == True:
color[2] = 255
im2.putpixel((i,j), tuple(color))
im2.save("parrot2.png")
main()