# PIL in Python from easy to hard

To get to the complex processing algorithms, it is worth analyzing standard schemes, with which I suggest starting.

For processing examples, an image with different sets of colors will be used:

To start, we need two library modules:

``from PIL import Image, ImageDraw ``

Set up tools for comfortable future work:

``````image = Image.open('test.jpg')  # Открываем изображение
draw = ImageDraw.Draw(image)  # Создаем инструмент для рисования
width = image.size[0]  # Определяем ширину
height = image.size[1]  # Определяем высоту
pix = image.load()  # Выгружаем значения пикселей``````

## Let's get started

We will process images in RGB format. PIL also supports working with formats 1, L, P, RGB, RGBA, CMYK, YCbCr, LAB, HSV, I, F.

Pixel values ​​in the image are specified in the format: (x, y), (red, green, blue) , where x, y are the coordinates, and the numerical values ​​of RGB are in the range from 0 to 255. That is, we work with an 8-bit image.

### Grayscale

A gray tint appears in the case of equality of all color palettes, so we need to get the arithmetic mean value in all three points:

``````
for x in range(width):
for y in range(height):
r = pix[x, y][0] #узнаём значение красного цвета пикселя
g = pix[x, y][1] #зелёного
b = pix[x, y][2] #синего
sr = (r + g + b) // 3 #среднее значение
draw.point((x, y), (sr, sr, sr)) #рисуем пиксель
image.save("result.jpg", "JPEG") #не забываем сохранить изображение
``````

Slight nuance
The human eye perceives a different spectrum of colors in different ways. Nobody will give you the exact formula, since the perception of colors is different for everyone one way or another, but if you are interested, you can read more here and here .

### Inversion

Inversion is obtained by subtracting the current color from 255:

``````
for x in range(width):
for y in range(height):
r = pix[x, y][0]
g = pix[x, y][1]
b = pix[x, y][2]
draw.point((x, y), (255 - r, 255 - g, 255 - b))``````

### Grayscale Inversion

Combining the two previous algorithms, you can write the following code:

``````
for x in range(width):
for y in range(height):
r = pix[x, y][0]
g = pix[x, y][1]
b = pix[x, y][2]
sr = (r + g + b) // 3
draw.point((x, y), (255 - sr, 255 - sr, 255 - sr))``````

### Selective Grayscale Inversion

For this algorithm, you need to determine the threshold value, which I will take for 100:

``````for x in range(width):
for y in range(height):
r = pix[x, y][0]
g = pix[x, y][1]
b = pix[x, y][2]
if (r+g+b)>100: #если сумма значений больше 100 , то используем инверисю
sr = (r + g + b) // 3
draw.point((x, y), (255-sr, 255-sr, 255-sr))
else: #иначе обычный оттенок серого
sr = (r + g + b) // 3
draw.point((x, y), (sr, sr, sr))``````

### Conclusion

In the following articles, I would like to talk about how to more locally approach image filtering by dividing it into areas, as well as show interesting possibilities of DFS in image processing algorithms