Статьи

Ascii Art Generator на Java — часть 2

Поскольку я получил много отзывов о моем  предыдущем посте,  где я создал очень простой генератор изображений Ascii на Java (найдите его на GitHub ), я решил продолжить работу над проектом и добавить к нему еще несколько функций, которые, надеюсь, вам понравятся еще больше. , Я переработал основную его часть и сделал ее очень расширяемой, чтобы ее было очень легко использовать для тестирования различных алгоритмов, создания различных выходных данных и т. Д. В этой статье я представлю новую архитектуру проекта, чтобы вы могли легко интегрировать его в свой собственный код и расширять его по мере необходимости.

Архитектура:

_config.yml


AsciiImgCache

Перед выполнением любого ascii art рендеринга необходимо создать экземпляр этого класса. Он берет шрифт и список символов для использования в качестве параметров и создает карту изображений для каждого символа. Существует также список символов по умолчанию, если вы не хотите беспокоиться о своих собственных.
Если вам интересно:

private static final char[] defaultCharacters = 
    "$@B%8&WM#*oahkbdpqwmZO0QLCJUYXzcvunxrjft/\\|()1{}[]?-_+~<>i!lI;:,\"^`'. "

Пример:

// use only '/' '\' and ' '
AsciiImgCache mediumBlackAndWhiteCache = AsciiImgCache.
    create(new Font("Courier", Font.BOLD, 10), new char[] {'\\', ' ', '/'});

// use default list
AsciiImgCache largeFontCache = AsciiImgCache.
    create(new Font("Courier",Font.PLAIN, 16));

BestCharacterFitStrategy

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

float calculateError(final GrayscaleMatrix character, final GrayscaleMatrix tile);

Реализация должна сравнить два изображения и вернуть ошибку с плавающей точкой. Каждый символ будет сравниваться, и будет выбран тот, который возвращает наименьшую ошибку. В настоящее время доступны две реализации: ColorSquareErrorFitStrategy и StructuralSdentifityFitStrategy.

ColorSquareErrorFitStrategy

Очень просто понять, он сравнивает каждый пиксель и вычисляет  среднеквадратичную ошибку  различий в градациях серого. Говоря математически, это: 
_config.yml
где n — количество пикселей, а C и T — пиксели от изображения символа и мозаики соответственно.

StructuralSimilarityFitStrategy

Алгоритм индекса структурного сходства (SSIM) претендует на то, чтобы воспроизводить человеческое восприятие, и его целью является улучшение традиционных методов, таких как MSE. Я не буду вдаваться в подробности о том, как это работает, вы можете прочитать больше в  Википедии,  если вы хотите узнать больше. Я немного поэкспериментировал с этим и реализовал версию, которая, казалось, давала лучшие результаты для этого случая.


AsciiConverter

Это сердце процесса, и оно содержит всю логику для мозаичного изображения исходного изображения и использования конкретных реализаций для расчета наилучшего соответствия символов. Тем не менее, он не знает, как создать конкретное искусство ascii — его нужно разделить на подклассы. В настоящее время существует две реализации: AsciiToImageConverter и AsciiToStringConverter — которые, как вы, вероятно, догадались, производят вывод изображения и строки.


Пример использования

Поскольку фрагмент кода стоит тысячи слов, я покажу вам весь процесс в действии, который должен завершить все части:

// initialize cache
AsciiImgCache cache = AsciiImgCache.create(new Font("Courier",Font.BOLD, 6));

// load image
BufferedImage portraitImage = ImageIO.read(new File("image.png"));

// initialize converters
AsciiToImageConverter imageConverter = 
    new AsciiToImageConverter(cache, new ColorSquareErrorFitStrategy());
AsciiToStringConverter stringConverter = 
    new AsciiToStringConverter(cache, new StructuralSimilarityFitStrategy());

// image output
ImageIO.write(imageConverter.convertImage(portraitImage), "png", 
    new File("ascii_art.png"));
// string converter, output to console
System.out.println(stringConverter.convertImage(portraitImage));

Вот несколько примеров изображений, созданных с различными параметрами:

Оригинальная картинка

Шрифт 16 pts, шрифт MSE
16 pts, шрифт SSIM
10 pts с 3 символами,
шрифт MSE 10 pts с 3 символами,
шрифт SSIM 6 pts, шрифт MSE
6 pts, SSIM

Дальнейшая работа

Некоторые идеи, которые я имею в виду:

  • Исследуйте и попытайтесь реализовать больше алгоритмов сравнения изображений
  • Попробуйте предварительно обработать изображение, чтобы получить лучшие результаты (улучшить контрастность, использовать обнаружение краев и т. Д.)
  • Обработка изображений может быть распараллелена для повышения производительности, попробуйте ее и измерьте усиление, чтобы увидеть, если оно того стоит.
  • Добавьте еще несколько конвертеров (т.е. вывод html)
  • Добавить поддержку для вывода с цветными символами
  • Добавить тесты в проект

Если у вас есть идеи по улучшению или вы найдете какие-либо проблемы с кодом, не стесняйтесь комментировать или вносить свой вклад в этот репозиторий через  GitHub !