Все статьи
24 сентября 2026 г.8 мин чтения

Вырезка на один пиксель: как согласовать границы ячейки

Вырезка на один пиксель: как согласовать границы ячейки

Если вырезка буквы отличается от ожидаемой на один пиксель, причина часто не в сетке: две части конвейера могут по-разному понимать координаты правой и нижней границы прямоугольника. Задайте единое соглашение о том, где начинается ячейка и где она заканчивается, затем проверьте ширину, высоту и соседние вырезки на одной контрольной строке.

Откуда берётся сдвиг в один пиксель

Шаблон уже выровнен, метки найдены, линии ячеек размечены, а результат всё равно выглядит странно: у букв появляется тонкая полоска соседней клетки, одна сторона обрезана или соседние вырезки не стыкуются при обратной проверке. Такие симптомы легко принять за плохое выравнивание. Но прежде чем заново искать маркеры, проверьте, как программа трактует границу прямоугольника.

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

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

Три значения, которые легко перепутать

Перед извлечением полезно записать не только прямоугольник, но и смысл его чисел. В растровой обработке чаще всего встречаются три представления:

  • Индекс пикселя. Пиксели строки имеют номера 0, 1, 2 и так далее; индекс указывает на отдельную ячейку растра.
  • Граница пиксельной области. Координата ставится между пикселями; отрезок от 0 до 64 охватывает ровно 64 пикселя.
  • Размер. Ширина — это число пикселей внутри прямоугольника, а не обязательно разность между двумя включёнными индексами.

В Pillow прямоугольник crop задаётся как (left, upper, right, lower), а система координат отсчитывается от левого верхнего угла; в руководстве также поясняется, что координаты относятся к положениям между пикселями. Поэтому область (10, 20, 74, 84) имеет ширину и высоту 64 пикселя. Если же вы получили крайние индексы включённых пикселей 10 и 73, соответствующие границы области будут 10 и 74. Это два способа описать одну и ту же выборку, а не повод прибавлять единицу наугад.

Для ручной разметки иногда естественно отметить крайний пиксель, который ещё принадлежит клетке. Для API обрезки удобнее хранить границу после последнего пикселя. Оба подхода работают, если название поля и преобразование между ними задокументированы. Ошибка появляется, когда число right называют «последним пикселем», а передают туда значение, которое функция трактует как границу после области.

Сначала задайте прямоугольник, потом округляйте

Метки и линии на выровненном изображении обычно дают дробные координаты: например, граница между ячейками проходит на x = 128.6. Пока все вычисления идут в дробных координатах, не округляйте отдельные точки заранее. Сначала вычислите все границы одной строки или столбца в общей геометрической модели; лишь на последнем шаге переведите их в целые границы пиксельной области.

Округление каждой ширины отдельно создаёт накопительный дрейф. Представьте ряд из 24 ячеек, расчётная ширина каждой из которых немного больше целого числа. Если округлять ширину повторно и прибавлять её к предыдущей целой границе, ошибка может сдвигать дальний край ряда. Надёжнее вычислять каждую линию из общей модели координат: x_i = x_0 + i × шаг, а затем округлять абсолютные границы. Тогда все ячейки опираются на одну систему, и сумма локальных ошибок не переносится автоматически в следующую клетку.

Если ширина ячеек не одинакова, используйте отдельные размеченные границы, а не средний шаг. Для равномерной сетки всё равно сравните несколько точек: первую, одну в середине и последнюю. Разница между round, floor и ceil заметна именно на дробных координатах; выбор зависит от того, нужно ли полностью включить штрих или исключить линию сетки. Не выбирайте функцию округления только потому, что она дала красивый результат на одной клетке.

Практическое правило: держите разметку в вещественных координатах до финальной обрезки; выберите единый способ округления; округляйте каждую абсолютную границу одинаково; после этого проверяйте фактические размеры вырезок. Не смешивайте округлённые координаты одного этапа с дробными координатами другого.

Зафиксируйте единый формат границ

Для таблицы или sidecar-файла полезно выбрать один формат и подписать его явно. Например, для каждой клетки хранить left, top, right_exclusive, bottom_exclusive. Суффикс exclusive напоминает, что последний край не означает «включить пиксель с таким индексом». Альтернативно можно хранить начало, ширину и высоту: тогда вычисляемые края получают формулу right = left + width и bottom = top + height.

Не храните только пару верхних углов без уточнения системы: непонятно, указаны ли центры маркеров, границы печатной линии или точки между пикселями. В паспорте разметки укажите имя и размеры именно того файла, к которому относятся координаты, порядок координат (x, y), тип границ, способ округления и выполненные преобразования. Если файл был изменён или уменьшен, прежние координаты нельзя применять напрямую.

Такая запись помогает передать проект между программами. Например, одна программа может отдавать прямоугольник как левый верхний угол плюс ширина и высота, а другая принимать четыре края. Пересчёт должен быть явным: right = left + width, bottom = top + height. Если промежуточная система использует включённые конечные индексы, преобразуйте их в границы обрезки ровно один раз и подпишите это место в коде или таблице.

Проверьте размер и стык на тестовой полосе

Не запускайте весь пакет сразу. Выберите три клетки: в начале строки, в середине и у противоположного края. Для каждой запишите координаты, ожидаемую ширину и высоту, фактический размер результата и то, касаются ли края штриха или сетки.

Сделайте дополнительную визуальную проверку: временно соберите вырезки обратно на копии исходного шаблона по тем же границам. На корректно согласованных прямоугольниках границы клеток должны совпадать с выбранными областями без полосы в один пиксель и без пропуска полосы между соседями. Этот тест не заменяет проверку буквы: он обнаруживает арифметическое несоответствие прямоугольников. Затем отдельно убедитесь, что метка символа и порядок клеток верны.

Если вы используете Pillow, сохраняйте ожидаемую ширину как right - left, а высоту как lower - upper, когда хранимые края обозначают положения между пикселями. После обрезки сравните размеры результата с этими разностями. Для сканера или редактора без такого соглашения найдите в документации определение прямоугольника; не переносите правило Pillow на другую библиотеку без проверки.

При необходимости добавьте тонкую цветную рамку вокруг тестовой области на отдельной копии, а не на мастер-файле. Так видны верхний и левый край, куда чаще попадает сдвиг. Сверяйте вырезку с исходным масштабом: увеличение помогает заметить разницу, но может скрыть её сглаживанием или интерполяцией.

Контрольный список перед пакетной обрезкой

  1. Уточните, координаты относятся к пикселям или границам между ними.
  2. Зафиксируйте порядок значений и смысл правого и нижнего краёв.
  3. Оставьте дробные координаты до финального этапа обрезки.
  4. Выберите и запишите единый способ округления.
  5. Рассчитывайте границы из общей модели, а не через сумму округлённых ширин.
  6. Проверьте размеры трёх тестовых вырезок и их положение относительно штрихов.
  7. Сверьте, что разметка относится к текущему файлу и его фактическим размерам.
  8. Сохраните соглашение рядом с координатами, чтобы следующий этап не трактовал их иначе.

Ошибки, которые создают разницу в один пиксель

Прибавлять единицу ко всем правым и нижним координатам. Это исправляет только случай, когда вы храните включённые индексы, а функция ждёт границы после области. Если функция уже использует границы между пикселями, добавка расширит вырезку и захватит край соседней клетки. Сначала выясните формат исходных чисел.

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

Сравнивать только размеры файлов. Две вырезки могут иметь одинаковую ширину, но начинаться с разных пикселей. Проверяйте и размер, и положение относительно сетки, и содержимое по краям.

Переносить координаты между разными версиями изображения. Обрезка, изменение размера, поворот или коррекция перспективы меняют систему координат. Укажите версию изображения и пересоздайте либо точно преобразуйте разметку.

Проверять только центральную клетку. Ошибка округления может проявляться сильнее у начала или конца строки. Сравните минимум три позиции и пробно соберите их обратно.

Частые вопросы

Почему вырезка имеет правильное начало, но неправильную ширину?

Вероятно, начальная граница задана согласованно, а правая трактуется по другой системе: как индекс включённого пикселя или как край после области. Проверьте разность right - left и фактический размер результата. Уточните формат функции обрезки прежде, чем менять разметку.

Нужно ли прибавлять единицу к правой и нижней координате?

Не всегда. Прибавление нужно только при переводе включённого последнего индекса в исключающую конечную границу. Если координаты уже указывают границу между пикселями, добавка захватит лишнюю строку или колонку. Проверьте документацию библиотеки и тестовый прямоугольник с известным размером.

Как избежать накопления ошибки в длинной строке?

Вычисляйте каждую границу из общей модели или храните все реальные границы отдельно. Не прибавляйте к предыдущей округлённой координате очередную округлённую ширину. Сравните первую, среднюю и последнюю клетки; они покажут, накапливается ли смещение вдоль строки.

Почему одинаковое соглашение важно для разных программ?

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

Что делать, если координаты уже записаны без описания формата?

Не меняйте всю разметку прибавлением единицы. Возьмите клетку с известными границами и ожидаемым размером, сделайте одну пробную обрезку и сравните результат. Если формат не удаётся подтвердить, безопаснее заново сохранить координаты с явными именами краёв и версией изображения.

Как проверить обрезку в Pillow?

Сверьте документацию Image.crop и отрежьте небольшой тестовый прямоугольник с заранее известными размерами. Для координат границ между пикселями размер равен разности соответствующих краёв. Затем визуально сравните края вырезки с исходной сеткой, не ограничиваясь проверкой размера файла.

Вывод

Сдвиг на один пиксель часто начинается не с маркера, а с неодинакового смысла координат. Опишите, где заканчивается прямоугольник, отложите округление до финальной обрезки и проверьте тестовую тройку ячеек по размеру и положению. Документация Pillow Image.crop описывает прямоугольник как четыре координаты; руководство Pillow по обрезке поясняет систему координат и положения между пикселями. Когда вы готовы перейти от проверки координат к созданию собственного набора знаков, подготовьте шаблон на Fontgenerator.