Перейти к основному содержимому

ASCII-арт в Java

· 4 мин. чтения

Задача: Сумма двух чисел

Напишите функцию twoSum. Которая получает массив целых чисел nums и целую сумму target, а возвращает индексы двух чисел, сумма которых равна target. Любой набор входных данных имеет ровно одно решение, и вы не можете использовать один и тот же элемент дважды. Ответ можно возвращать в любом порядке...

ANDROMEDA

1. Обзор

В этой статье мы обсудим создание графического изображения символов ASCII или строк в Java с использованием концепций поддержки 2D-графики языка.

2. Рисование строк с помощью 2D-графики

С помощью класса Graphics2D можно рисовать строку как изображение, что достигается вызовом метода drawString() .

Поскольку Graphics2D является абстрактным, мы можем создать экземпляр, расширив его и реализовав различные методы, связанные с классом Graphics .

Хотя это утомительная задача, ее часто решают путем создания экземпляра BufferedImage в Java и извлечения из него базового экземпляра Graphics :

BufferedImage bufferedImage = new BufferedImage(
width, height,
BufferedImage.TYPE_INT_RGB);
Graphics graphics = bufferedImage.getGraphics();

2.1. Замена индексов матрицы изображения символом ASCII

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

Чтобы мы могли заменить вырезанную область желаемым символом ASCII, нам нужно определить значения вырезанной области как одну точку данных (например, целое число), а не значения цвета RGB.

Чтобы цвет RGB изображения был представлен в виде целого числа, мы устанавливаем тип изображения в целочисленный режим:

BufferedImage bufferedImage = new BufferedImage(
width, height,
BufferedImage.TYPE_INT_RGB);

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

При этом индексам матрицы, представляющим нулевое значение, будет присвоен один пробел. Нулевой эквивалент целочисленного режима равен -16777216.

3. Генератор ASCII-арта

Давайте рассмотрим случай, когда нам нужно сделать ASCII-арт строки «FOREACH».

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

Чтобы иметь возможность использовать расширенные параметры рендеринга 2D-графики в Java, мы приводим наш объект Graphics к экземпляру Graphics2D . Затем мы устанавливаем желаемые параметры рендеринга перед вызовом метода drawString() со строкой «FOREACH» :

Graphics2D graphics2D = (Graphics2D) graphics;
graphics2D.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,
RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
graphics2D.drawString("FOREACH", 12, 24);

В приведенном выше примере 12 и 24 представляют соответственно координаты x и y точки на изображении, с которой должна начинаться печать текста.

Теперь у нас есть 2D-графика, базовая матрица которой содержит два типа различаемых значений; ненулевые и нулевые индексы.

Но чтобы понять концепцию, мы пройдемся по двумерному массиву (или матрице) и заменим все значения символом ASCII «*» на:

for (int y = 0; y < settings.height; y++) {
StringBuilder stringBuilder = new StringBuilder();

for (int x = 0; x < settings.width; x++) {
stringBuilder.append("*");
}

if (stringBuilder.toString().trim().isEmpty()) {
continue;
}

System.out.println(stringBuilder);
}

Вывод приведенного выше показывает только блок звездочек (*), как показано ниже:

./6a3c4e6946c41eb49b8a54100f55e557.png

Если мы различаем замену на «», заменяя только целые значения, равные -16777216, на «», а остальные на «»:

for (int y = 0; y < settings.height; y++) {
StringBuilder stringBuilder = new StringBuilder();

for (int x = 0; x < settings.width; x++) {
stringBuilder.append(image.getRGB(x, y) == -16777216 ? "*" : " ");
}

if (stringBuilder.toString().trim().isEmpty()) {
continue;
}

System.out.println(stringBuilder);
}

Мы получаем другое изображение ASCII, которое соответствует нашей строке «FOREACH», но в перевернутом виде:

./c046477ff58333bc809269dfa4d49c26.png

Наконец, мы инвертируем дискриминацию, заменяя целочисленные значения, равные -16777216, на « », а остальные на «*»:

for (int y = 0; y < settings.height; y++) {
StringBuilder stringBuilder = new StringBuilder();

for (int x = 0; x < settings.width; x++) {
stringBuilder.append(image.getRGB(x, y) == -16777216 ? " " : "*");
}

if (stringBuilder.toString().trim().isEmpty()) {
continue;
}

System.out.println(stringBuilder);
}

Это дает нам ASCII-арт желаемой строки:

./57c394d76af70113bc85b5aa2fb9b044.png

4. Вывод

В этом кратком руководстве мы рассмотрели, как создавать рисунки ASCII на Java с использованием встроенной библиотеки 2D-графики.

Хотя мы показали специально для текста; «FOREACH», исходный код на Github, предоставляет служебную функцию, которая принимает любую строку.

Исходный код, как всегда, можно найти на GitHub .