Создание шахматной доски в PIL - PullRequest
0 голосов
/ 29 января 2019

Фон

Я пытался создать шахматную доску в модуле PIL и получил общий шаблон для первых двух рядов, но не могу понять, как применить это ко всей доске.Как видите, я создал изображение:

from PIL import Image

img = Image.new("RGB", (15,15), "white") # create a new 15x15 image
pixels = img.load() # create the pixel map

Мое решение для первых двух строк

Примечание. Я все еще изучаю Python, поэтому этот код может показаться очень неэффективным, но я чувствую, чтосвободно предлагать улучшения.

Второй ряд:

Код:

black_2 = []
for i in range(img.size[0]):
    if i % 2 == 0:
        black_2.append(i)

Это дает мне все горизонтальные позиции указателя на том, куда поместить черный пиксель.Поэтому для созданной мной доски 15x15 возвращается [0, 2, 4, 6, 8, 10, 12, 14]

Первая строка:

Код:

Затем я использую вторую строку для определения горизонтального индексапозиции для первой строки

black_1 = [i-1 for i in black_2 if i > 0]
if img.size[0] % 2 == 0: # 'that' if statement
    black_1.append(img.size[0]-1)

Для созданной мной доски пикселей 15x15 возвращается [1, 3, 5, 7, 9, 11, 13].Я создал оператор if, потому что понял, что последний черный пиксель не отображается, если доска имеет четную длину, и это, похоже, исправило ее.

Изменение пикселей на черный:

# hardcoded to check patterns
for i in black_1:
    pixels[i,0] = (0,0,0)

for k in black_2:
    pixels[k,1] = (0,0,0)

img.show()

Как я могу применить оба шаблона к остальной части платы, независимо от ее размера?

Я подозреваю, что необходим цикл for var in range(), но я не уверен, как он изменится в зависимости от того, является ли высота (img.size[1]) платы нечетной или четной.

Общая схема на данный момент:

Chessboard

black_1 применяется к первому ряду

black_2 применяется ко второму ряду

Ответы [ 4 ]

0 голосов
/ 29 января 2019

Решение:

Используя модуль numpy, это очень быстро, и у вас есть только 11 циклов (также не циклически проходя через каждый пиксель, а скорее через шаблоны).Неважно, насколько велика шахматная доска.Обработка должна быть одинаково быстрой

синхронизация: 2400 x 2400 пикселей на шахматной доске -> 0,17 с

import numpy as np
from PIL import Image
n = 50 # size of one element, row = 8*n, chessboard = 8*n x 8*n

segment_black = np.zeros(shape = [n,n])
segment_white = np.ones(shape = [n,n])*255
chessboard = np.hstack((segment_black,segment_white))
for i in range(4):
    chessboard = np.hstack((chessboard,segment_black))
    chessboard = np.hstack((chessboard,segment_white))
temp = chessboard
for i in range(7):
    chessboard = np.concatenate((np.fliplr(chessboard),temp))
img = Image.fromarray(chessboard.astype(np.uint8))
img.save('chess.jpg')
img.show()
0 голосов
/ 29 января 2019

Шахматная доска имеет 64 квадрата вместо 256. Сначала вам нужно (8,8), а затем вы можете использовать двойной цикл для назначения цвета для всех 8 рядов.

Общий пример для любого размера

from PIL import Image

size = 16
img = Image.new("RGB", (size,size), "white") # create a new 15x15 image
pixels = img.load() # create the pixel map

black_2 = []
for i in range(img.size[0]):
    if i % 2 == 0:
        black_2.append(i)

black_1 = [i-1 for i in black_2 if i > 0]
if img.size[0] % 2 == 0: # 'that' if statement
    black_1.append(img.size[0]-1)


for i in black_1:
    for j in range(0, size, 2):
        pixels[i,j] = (0,0,0)

for k in black_2:
    for l in range(1, size+1, 2):
        pixels[k,l] = (0,0,0)

img.show()

enter image description here

0 голосов
/ 29 января 2019

Это простой способ.В случае, если вас это смущает, один пиксель на изображении соответствует целому квадрату шахматной доски, и вы можете увеличить его в конце, если хотите.

#!/usr/bin/env python3

from PIL import Image

# Create new black image of entire board
w, h = 12, 6
img = Image.new("RGB", (w,h))
pixels = img.load()

# Make pixels white where (row+col) is odd
for i in range(w):
    for j in range(h):
        if (i+j)%2:
            pixels[i,j] = (255,255,255)

img.save('result.png')

Если вы хотите, чтобы он был большеизображение, просто измените размер в конце.Итак, скажем, вы хотите, чтобы каждый квадрат на доске был 15px x 15px:

img = img.resize((15*w,15*h),PIL.Image.NEAREST)

enter image description here

0 голосов
/ 29 января 2019

Вы можете использовать PIL.Image.paste для вставки img в себя.

for n in range(15/2):
    img.paste(img, (0, n*2))

Используя весь существующий код, просто добавьте его внизу.

...