Почему библиотека PIL в Python работает некорректно?

Пишу простую программу, но получаю искажение изображения. Думаю, это связано с вычитанием 1 из ширины (w - 1); если этого не делать, появляется ошибка IndexError: image index out of range. Спасибо за помощь. Вот код: <br/> <pre><code class="python">from PIL import Image
  • 17 марта 2026 г. 9:11
Ответы на вопрос 2
Невозможно точно сказать без полного кода, но по описанию — «искажение изображения» и «если не вычитать 1 из ширины — IndexError» — вероятны классические ошибки:

1) Вы меняете изображение «на месте» (чтение и запись в один и тот же объект) и при обращении к соседним пикселям читаете уже изменённые значения — это искажает картинку. Решение: читать из оригинала, а записывать в копию.

2) Оффбай-ван: вы обращаетесь к x+1 или y+1 без проверки границ. Тогда нужно итерироваться до w-1/h-1 либо брать min/max или проверять границы.

3) Неправильный порядок координат или режим изображения (например, палитровое изображение/RGBA вместо RGB), либо работу с плоским списком пикселей (getdata/putdata) вы делаете с неверной длиной/форматом.

Ниже примеры: сначала — потенциально «вредный» вариант, затем корректный.

Плохой (может давать искажения):
```python
from PIL import Image

img = Image.open('in.jpg').convert('RGB')
w, h = img.size

for y in range(h):
    for x in range(w):
        # читаем соседний пиксель справа
        p = img.getpixel((x+1, y))    # при x == w-1 будет IndexError
        # и сразу записываем в тот же img — то, что читаем позже, уже изменится
        img.putpixel((x, y), p)
img.save('out.jpg')
```

Правильный вариант: читать из копии, писать в новую картинку; корректно обрабатывать границы:
```python
from PIL import Image

src = Image.open('in.jpg').convert('RGB')
w, h = src.size
dst = Image.new('RGB', (w, h))

for y in range(h):
    for x in range(w):
        # безопасно берём пиксель справа; при правой границе берём сам пиксель
        right_x = x + 1 if x + 1 < w else x
        p = src.getpixel((right_x, y))
        dst.putpixel((x, y), p)

dst.save('out.jpg')
```

Ещё более эффективный способ — работать с pixel access:
```python
src = Image.open('in.jpg').convert('RGB')
w, h = src.size
dst = Image.new('RGB', (w, h))
sp = src.load()
dp = dst.load()

for y in range(h):
    for x in range(w):
        rx = x+1 if x+1 < w else x
        dp[x, y] = sp[rx, y]

dst.save('out.jpg')
```

Советы для отладки:
- Выведите print(img.size), print(img.mode) и посмотрите, какой формат пикселей.
- Если используете getdata/putdata, учтите, что длина последовательности = w*h и элементы — либо числа (L), либо кортежи (RGB).
- Если хотите изменить соседние пиксели по какому-то правилу, обязательно использовать копию исходных данных.
- Для быстрых и сложных операций лучше использовать numpy (np.array(img)), там проще индексировать с граничными условиями.

Если хотите — пришлите полный код (включая открытие файла и циклы), и пример того, как именно искажается изображение (описание или мини-скриншот). Тогда подскажу конкретно, где ошибка.
<pre><code class="python">from PIL import Image

q = input("Название картинки: ")
img = Image.open(q)
img = img.convert("RGB")
(w,h) = img.size
print(w*h)
with open("img.txt","w") as file:
    for y in range(h):
        for x in range(w):
            r, g, b = img.getpixel((x,y))
            file.write("#" if (r, g, b) == (0, 0, 0) else "_")
        file.write("\n")

print(img.getpixel((0,0)))
input("Enter что-бы завершить: ")</code></pre>
Похожие вопросы