Python PIL: лучший метод масштабирования, который сохраняет строки

У меня есть 2D-чертеж с черным фоном и белыми линиями (экспортируется из Autocad), и я хочу создать эскиз, сохраняя линии, используя библиотека Python PIL.

но то, что я получаю с помощью метода "эскиза", - это просто черная картинка, разбросанная белыми точками.

обратите внимание, что если я помещаю изображение в тег IMG с фиксированной шириной, я получаю именно то, что хочу (но изображение полностью загружено).

после ваших комментариев, Вот мой пример кода:

from PIL import Image
fn = 'filename.gif'
im = Image(fn)
im.convert('RGB')
im.thumbnail((300, 300), Image.ANTIALIAS)
im.save('newfilename.png', 'PNG')

Как я могу это сделать?

2 ответов


метод изменения размера по умолчанию используется thumbnail ближайший, что является действительно плохим выбором. Если вы изменяете размер до 1/5 от исходного размера, например, он выведет один пиксель и выбросит следующие 4-линия шириной в один пиксель имеет только 1 шанс из 5 показать на всех в результате!

удивительно то, что БИЛИНЕЙНЫЕ и БИКУБИЧЕСКИЕ не намного лучше. Они берут формулу и применяют ее к 2 или 3 ближайшим пикселям к исходной точке, но есть еще большим количеством пикселей, они не смотрят на, а формула все равно соединяются линией.

лучшим выбором является ANTIALIAS, который, по-видимому, учитывает все исходное изображение, не отбрасывая пиксели. Линии станут более тусклыми, но они не исчезнут полностью; вы можете сделать дополнительный шаг, чтобы улучшить контраст, если это необходимо.

обратите внимание, что все эти методы вернутся к ближайшему, если вы работаете с палитрой изображений, т. е. im.mode == 'P'. Вы всегда должны конвертировать в "RGB".

from PIL import Image
im = Image.open(fn)
im = im.convert('RGB')
im.thumbnail(size, Image.ANTIALIAS)

вот пример, взятый из электроники.сайт stackexchangehttps://electronics.stackexchange.com/questions/5412/easiest-and-best-poe-ethernet-chip-micro-design-for-diy-interface-with-custom-ard/5418#5418

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

NEAREST

используя ANTIALIAS алгоритм:

ANTIALIAS


по умолчанию im.resize использует NEAREST фильтр, который будет делать то, что вы видите-потерять информацию, если она не упадет на соответствующий модульный пиксель.

вместо

im.resize(size, Image.BILINEAR)

это должно сохранить ваши линии. Если нет, попробуйте Image.BICUBIC или Image.ANTIALIAS. Любой из них должен работать лучше, чем NEAREST.