Как сделать рисунок в java

Обновлено: 04.07.2024

Java работает с наиболее популярными во Всемирной паутинеформатами изображений — JPEG и GIF. JPEG лучше подходит для естественных цветныхизображений, таких, как фотографии, а формат GIF является наилучшими дляграфических эмблем, изображений кнопок, и т.п.

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

Простой загрузчик изображений

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

public class SimpleImageLoad extends Applet

public void init()

public void paint(Graphics g)

g.drawImage(art, 0, 0, this)-

Метод paint использует drawlmage с четырьмя аргументами: этоссылка на изображение art, координаты левого верхнего угла рисунка х, у и объекттипа ImageObserver. Мы поговорим подробнее об ImageObserver в следующемпараграфе- здесь мы использовали this в качестве имени ImageObserver, поскольку он встроен вапплет. Когда этот апплет запускается, он в методе init начинает загрузку art.Процесс загрузки изображения по сети хорошо заметен – SimpleImageLoad.html , поскольку встроенный интерфейс ImageObserver вызываетпроцедуру paint при каждом поступлении новой порции данных из сети. Вы можетеиспользовать ImageObserver для отслеживания загрузки изображения, а в это времявыводить на экран другую информацию.

public class MyApplet extends Applet implement ImageObserver

Затем вам придется вставить в свой класс метод imageUpdate для интерфейсаImageObserver, как показано в следующем фрагменте :

public boolean imageUpdate(Image img, int status,

int x, int у int width, int height)

if((status &- ALLBITS) != 1)

Метод imageUpdate вызывается с изображением Image, котороенаходится в процессе изменения, целым параметром status, отражающим состояниеизменения, и с координатами прямоугольника (x, у, width, height), которыесоответствуют различным величинам в зависимости от информационных флагов,перечисленных ниже. ImageUpdate должен возвращать false по окончании загрузкиизображения и true — если изображение еще обрабатывается.

Целая переменная status поразрядно проверяется на наличиеодного или нескольких флагов. Возможные флаги и информация, которую они несут,перечислены ниже:

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

Здесь str — строковая переменная, а x, у — координаты первого символа строки. Достаточно часто, однако, возникает необходимость выполнить вывод строки или нарисовать фигуру не в методе paint о, а в любом другом методе. В этом случае нужно создать объектную графическую переменную и затем использовать ее методы рисования. Для создания объектной графической переменной z используем команду следующего вида:

Graphics z = getGraphics();

Приведем пример, в котором на форме выполняется вывод строки при нажатии на программную кнопку (листинг 1.10).

Листинг 1.10. Графический вывод вне метода paint ()

import java.awt.*; import java.awt.event.*;

public class painting extends Frame implements ActionListener private String strl;

Button print=new Button("Print"); // Кнопка для вывода строки Button clear=new Button("Clear"); // Кнопка для очистки

// области экрана Button exit=new Button("Exit"); // Кнопка для выхода из

// приложения painting() // Конструктор класса painting

setLayout(null); // Размещение элементов выполняется вручную

strl="Hello from Frame !";

add(print); // Добавление кнопки

print.addActionListener(this); // Добавление прослушивателя

public void actionPerformed(ActionEvent e) // Обработчик

// событий // от кнопок

System.exit(0); //Завершение приложения else

Graphics z=getGraphics(); // Создаем объектную

// графическую переменную z z.drawString(strl,10,120); // Вывод строки strl

z.clearRect(8,110,110,35); // Очистка и заливка цветом

// фона прямоугольной области

painting pt= new painting(); // Создаем форму pt.resize(400,400); // Задаем размеры формы pt.setBackground(newColor(120,100,180)); // Устанавливаем

В этом примере используем графическую объектную переменную для вывода строки, очистки прямоугольной области экрана и заливки ее цветом фона:

z.clearRect(8,110,110,35); // Очистка и заливка цветом фона

В цикле практических занятий будем рассматривать различные графические методы класса Graphics. Заметим, что класс Graphics не позволяет "удерживать" изображение (например, рисунок). Полезен и другой класс — canvas. Объект этого класса можно перемещать по форме (апплету) или панели (panei). Можно управлять его размерами, создавать на его основе дочерние классы и пр. Предыдущее приложение незначительно изменено (листинг 1.11) таким образом, что по нажатию на кнопку Print строка выводилась в случайной позиции экрана.

Листинг 1.11. Графический вывод на основе класса Canvas

import java.awt.*; import java.awt.event.*;

public class painting extends Frame implements ActionListener

private String strl;

// Построена классовая переменная на базе Canvas: private Canvas cs=new Canvas();

Button print=new Button("Print");

Button clear=new Button("Clear");

Button exit=new Button("Exit");

strl="Hello from Frame !";

print.addActionListener(this); clear.addActionListener(this) ; exit.addActionListener(this); print.setBounds(10,20,100, 20) ; clear.setBounds(10,50,100, 20); exit.setBounds(10,80,100, 20) ; cs.setBounds(10,110,180,150);

// Объект Canvas можно размещать в произвольном месте формы cs.setBackground(Color.yellow); // Объект Canvas можно

public void actionPerformed(ActionEvent e)

int x=(int) Math.round(( Math.random()*20+10));

//x,y — случайные координаты для вывода объекта Canvas int y=(int) Math.round((Math.random()*100+110)); cs.move(x,y); // Перемещаем объект Canvas в новую позицию // Выводим строку в объекте Canvas: cs.getGraphics().drawString(strl,10,10);

// область // объекта Canvas

public static void main(String[] args)

painting pt= new painting(); pt. resize (400, 400) ;

pt.setBackground(new Color(120,100,180)); pt.show();

Рассмотрим теперь, как получить картинку. Держателем картинки является класс image. Поэтому первоначально следует сделать объявление наподобие следующего:

Затем в строковой переменной следует указать адрес картинки:

Java не всегда отображает файлы с расширением .bmp (используем при работе с графикой файлы .jpg и .jpg). После этого нужно инициализировать переменную img:

И, наконец, рисуем картинку:

Graphics g= getGraphics(); g.drawImage(img,20,150,this);

Заметим, что рисование картинки следует предварить операцией ее подготовки:

поскольку в противном случае картинка может не отобразиться.

Следующее небольшое приложение (листинг 1.12) объединяет все сказанное ранее.

Листинг1.12. Рисование картинки на форме

import java.awt.*; import java.awt.event.*;

class Pic extends Frame implements ActionListener // Приложение создается на основе Frame

private Image img; // Объявляем картинку Button exit=new Button("Exit");

Button pict=new Button("Picture"); // По нажатию на эту

// кнопку картинка // отображается на форме

setLayout(null) ; add(exit); add(pict);

exit.addActionListener(this) ; pict.addActionListener(this); exit.setBounds(10,20,100, 20) ; pict.setBounds(10,50,100,20);

String s="C:/work/l.jpg"; // Формируем строку с адресом

img= getToolkit().getImage(s); // Создаем переменную класса

// Image для хранения // картинки

prepareImage(img,this); // Переменная img заранее

// инициализируется, но еще не // отображается

public void actionPerformed(ActionEvent e)

System.exit(0); // выход из приложения else

Graphics g =getGraphics(); // Создаем переменную

// графического контекста // для рисования картинки g.drawImage(img,10,80,this); // Рисуемкартинку

g. drawLine(10,200,200,200); // Рисуем линию

g. setColor(Color.blue); // Изменяем цвет пера

g. drawLine(10,210,200,210); // Рисуем линию голубым

public static void main(String[] args)

Pic fr=new Pic(); // Создаем объект класса приложения fr.resize(400,400); // Устанавливаем размеры формы // в пикселах

fr.setVisible(true); // делаем форму приложения видимой

В приведенном листинге следует обратить внимание на оператор:

который присваивает переменной img битовый образ, хранимый в файле с адресом s.

Отметим, что в апплете для этих целей используется команда

img=getImage(URL u, "name.jpg");

Здесь первый операнд задает URL-адрес картинки в сети Интернет, второй — имя картинки.

Результат работы приложения приведен на рис. 1.10. В прилагаемом к книге CD нужно предварительно подготовить файл с картинкой с именем l.jpg и разместить его в каталоге c:\work.


Рис. 1.10. Рисование картинки и линий

Более продвинутые возможности для рисования предоставляет пакет Graphics2D. Например, средствами этого пакета можно выполнять градиентную заливку фигур, управлять шириной пера, поворачивать фигуры и пр. В качестве иллюстрации приведем приложение, демонстрирующее некоторые возможности пакета Graphics2D (листинг 1.13).

Листинг1.13. Рисование с градиентной заливкой на базе пакета Graphics2D

import java.awt.*; import java.awt.geom.*;

public class Picl extends Frame

private Ellipse2D.Double circle= new

Ellipse2D.Double(20,30,100,100); // создаем переменную circle

public void paint(Graphics g)

Graphics2D g2=(Graphics2D) g; // Преобразуем к классу

// Graphics2D переменную // Graphics

//Устанавливаем режим градиентной заливки

g2.setPaint(Color.white); // Устанавливаем цвет пера

// в значение Color.white

g2.drawString("JAVA+",30,60); // Выводим строку

public static void main(String [] args)

Picl fr=new Picl(); fr. resize (400, 400) ;

Результат работы программы из листинга 1.13 приведен на рис. 1.11.


Рис. 1.11. Градиентная заливка Подключаем пакет Graphics2D командой:

Объявление переменной типа эллипса ясно из листинга 1.13. Важно обратить внимание на способ получения графического контекста Graphics2D, выполненный на основе преобразования типов:

Graphics2D g2=(Graphics2D) g;

Рисование окружности (эллипса) с заливкойрешизует команда:

g2 . fill (circle);

При этом заранее устанавливается режим градиентной заливки:

g2.setPaint(new GradientPaint (0,0,Color.red,110,110,Color.green,true));

В этой команде указаны два цвета — Color.red, Color.green и координаты области, в которой выполняется заливка (в той части

этой области, где содержится замкнутая часть рисуемой фигуры). Красный цвет начинается с точки с координатами (0,0), зеленый — с точки с координатами (110,110).

В этом же листинге осуществлен вывод строки с предварительной установкой цвета пера:

g2.setPaint(Color.white); // Устанавливаем цвет пера

// в значение Color.white g2.drawString("JAVA+",30,60); // Выводим строку

Более интересные подробности, касающиеся Graphics2D, можно найти в [13].

Наше предварительное введение в язык Java завершено. Основные концепции этого языка, необходимые для успешного и быстрого старта, изложены.

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


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

1- JavaFX Image

JavaFX позволяет вам работать со всеми распространенными форматами картинок. Используйте класс javafx.scene.image.Image чтобы загрузить картины из жесткого диска или из интернет ресурса. Чтобы отобразить картину на приложении JavaFX используйте класс ImageView.

Картины могут быть расположены в одном файле jar или в пакете вашего Project. И вы можете использовать конструктор Image(InputStream) чтобы скачать этот файл.


2- JavaFX ImageView

ImageView это компонент, помогающий вам отобразить картину на приложении JavaFX. Вы так же можете применить эффекты для отображения картины как например поворачивать, увеличить, уменьшить, .

На прошлом уроке разобрались, как достучаться до канвы. Теперь попробуем поработать с ней, рассмотрим методы рисования точки, линии, круга, дуги, овала, прямоугольника и текста.

Для рисования используются методы draw*. Если посмотреть их в хелпе можно обратить внимание, что одним из их параметров является объект Paint. В этом объекте задаются графические характеристики рисования. Т.е. можно считать, что это кисть, которой будут рисоваться ваши фигуры. Через него вы сообщаете канве цвет и толщину линии для рисования.

Project name: P1421_DrawingFigure
Build Target: Android 2.3.3
Application name: DrawingFigure
Package name: ru.startandroid.develop.p1421drawingfigure
Create Activity: MainActivity

Пишем MainActivity.java:

Смотрим класс DrawView. В конструкторе создаем объект Paint, которым будем рисовать фигуры, и объект Rect, который нам понадобится для рисования прямоугольника. Тут сразу обращу внимание, что создавать объекты крайне желательно за пределами метода onDraw, т.к. при частой прорисовке у вас постоянно будут создаваться новые объекты, а это является лишней нагрузкой на сборщик мусора и может замедлить работу приложения. Поэтому создаем мы объекты всего один раз, в конструкторе.

В методе onDraw мы сначала закрашиваем всю канву цветом. Есть различные реализации метода закраски:

drawRGB – на вход требует три компонента RGB (red, green, blue: смешением этих трех цветов можно получать другие цвета и их оттенки).

drawARGB – аналогичен drawRGB, но добавляет использование прозрачности (alpha). alpha + RGB = ARGB.

drawColor – на вход требует ARGB-значение в десятичной системе. Для удобства в классе Color есть несколько констант-цветов. Одну из них (Color.GREEN) мы использовали с этим методом на прошлом уроке.

Мы в нашем приложении используем метод drawARGB и передаем ему значения: прозрачность (80), уровень красного (102), уровень зеленого (204), уровень синего (255). В итоге получаем канву, закрашенную вполне себе приятным для глаз цветом.

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

Метод setColor позволяет указать цвет (аналогично методу drawColor у канвы). Кроме этого, у Paint есть метод для указания ARGB – setARGB.

Метод setStrokeWidth позволяет указать толщину линий при рисовании. Мы укажем 10.

Начинаем рисовать объекты.

drawPoint – нарисует точку с координатами (50,50)

drawLine – нарисует линию из точки (100,100) в точку (500,50)

drawCircle – нарисует круг в точке (100,200) с радиусом 50

drawRect – нарисует прямоугольник с левым верхним углом в точке (200,150) и нижним правым углом в точке (400,200)

Далее идет другая реализация метода drawRect. Он принимает на вход объект Rect, в котором ранее были указаны координаты прямоугольника методом set. В итоге метод нарисует нам прямоугольник с верхним левым углом в точке (250,300) и нижним правым в точке (350,500).

Также есть реализация drawRect, которая на вход требует объект RectF – это аналог Rect, но значения используются не int, а float.

И, как вы наверно заметили, все эти draw* методы требуют на вход объект Paint. Это логично, т.к. канва должна знать толщину и цвет линий, которыми мы собрались рисовать.

Все сохраняем и запускаем приложение.

Видим такую картину:


Нулевая точка координат расположена в левом верхнем углу экрана и от нее идет отсчет вправо по оси X и вниз по оси Y. Видим нарисованные нами точку, линию, круг и два прямоугольника.

С этим все понятно. Давайте посмотрим другие методы рисования и будем менять некоторые используемые объекты в процессе.

Перепишем класс DrawView:

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


Смотрим метод onDraw. Первые три строки не менялись, повторяться не буду.

drawPoints – рисует множество точек. Их координаты заданы в виде float массива следующим образом . Соответственно, будут нарисованы точки (x1,y1), (x2,y2), … В нашем примере мы используем массив points.

Есть также следующая реализация этого метода: drawPoints (float[] pts, int offset, int count, Paint paint). Она позволяет указать с какого (offset) по порядку значения в массиве начинать формировать точки и сколько (count) значений брать. Тут не запутайтесь, идет выборка именно значений массива, а не получившихся точек.

drawLines – рисует множество линий. Их координаты заданы в виде float массива следующим образом . Соответственно будут нарисованы линии (x1,y1)-(x2,y2), (x3,y3)-(x4,y4), … В нашем примере используем массив points1.

Аналогично точкам, у этого метода также есть реализация с отступом и количеством: drawLines (float[] pts, int offset, int count, Paint paint), где offset – это отступ, указывающий с какого значения массива брать значения для формирования точек, а count – количество значений, которое необходимо взять.

Методом setColor сменим для разнообразия цвет кисти на зеленый. Тут важно понимать, что все ранее нарисованные объекты останутся красными. А вот последующие будут нарисованы уже зеленым цветом.

drawRoundRect рисует обычный прямоугольник, но со скругленными углами. В объекте rectf мы передаем данные по расположению прямоугольника. Далее два числовых параметра позволяют нам задать радиус скругления по оси X и Y. Тут не смогу объяснить словами про эти радиусы, просто позадавайте различные значения и посмотрите на результат. Чем выше значения, тем более закруглены углы.

Далее методом offset выполняем смещение в объекте rectf. На вход передаем смещение по оси X (0) и по оси Y (150). Т.е. был RectF со значениями (700,100,800,150), а стал (700 + 0, 100 + 150, 800 + 0, 150 + 150). Т.е. просто опускаем прямоугольник вниз на 150.

Эта процедура никак не влияет на фигуры, которые уже были нарисованы с использованием этого RectF объекта. Они где были, там и остаются.

drawOval рисует овал, который занимает все пространство в переданном ему прямоугольнике (rectf).

Далее снова меняем координаты объекта rectf, только на этот раз методом offsetTo. Он не добавляет координаты к имеющимся, а устанавливает новую верхнюю левую точку прямоугольника. И прямоугольник смещается к ней, сохраняя при этом свои размеры.

Далее меняем размер прямоугольника rectf методом inset. На вход метод принимает две дельты, на которые он уменьшит прямоугольник по горизонтали (0) и вертикали (-25). Уменьшит на -25 означает, увеличение на 25.

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

Выполнив rectf.inset(0, -25) я увеличиваю размер прямоугольника rectf по вертикали на 25 и вверх и вниз. Итого, размер по вертикали увеличивается на 50. Горизонтальный не меняется.

drawArc – рисует дугу (или можно еще сказать - часть круга), которая занимает предоставленный ей прямоугольник rectf. Далее идут два угловых параметра: начало и длина, в нашем случае это 90 и 270 градусов.

Длина – это угол рисуемой дуги. Т.е. полный круг – это 360 градусов. Соответственно 270 – три четверти круга. Если мы отложим три четверти круга от 6 часов, то получим 3 часа. Такая дуга и должна получится: от шести до трех часов по часовой стрелке.

Следующий boolean параметр определяет, как будут соединены две крайние точки дуги. Т.е. если рассматривать наш пример, то это точки 6 и 3 часа. Между ними по часовой проходит дуга, но чтобы получилась замкнутая фигура, необходимо соединить между собой эти точки. Тут два варианта: от каждой точки будет проведена прямая к центру круга и в итоге через центр дуга замкнется, либо просто проводится прямая между этими точками. Соответственно если параметр true – то точки соединяются через центр, если false – то между собой. В нашем случае – это true.

Далее опускаем прямоугольник на 150 вниз. И снова рисуем такую же дугу, но теперь с параметром false. Концы дуги будут соединены между собой напрямую.

Далее устанавливаем ширину линии в 3 px. И рисуем вертикальную линию с X = 150. Она понадобится, чтобы показать выравнивание текста, который сейчас будем выводить.

Меняем цвет кисти на синий.

Методом setTextSize устанавливаем размер шрифта в 30. Т.е. данные шрифта для текста задаются в той же самой кисти, которой мы только что фигуры рисовали.

Метод setTextAlign настраивает горизонтальное выравнивание текста. По умолчанию оно равно Paint.Align.LEFT. И с ним у нас вывелся первый текст. Причем текст вывелся справа. Т.е. в данном случае LEFT означает не "текст будет слева от точки", а "точка будет слева от текста". Вполне можно и запутаться.

Мы нарисовали три текста указывая одну X-координату = 150. Но разное горизонтальное выравнивание раскидало их по разные стороны. Ранее нарисованная зеленая линия с X = 150 позволяет это четко увидеть.

И напоследок рассмотрим еще пару моментов.

Перепишем класс DrawView:

Методы getWidth и getHeight позволяют получить ширину и высоту канвы. Мы выводим эту инфу на экран методом darwText.

Далее выводим три прямоугольника с разными стилями рисования, которые указываем методом setStyle:

Paint.Style.FILL – прямоугольник закрашивается изнутри, а его грани не рисуются

Paint.Style.STROKE – рисуются только грани прямоугольника, внутри закраски нет

Paint.Style.FILL_AND_STROKE – есть и закраска внутри и грани

По умолчанию используется стиль Paint.Style.FILL.

Чтобы лучше понять все вышеизложенные аспекты, советую вам самостоятельно поэкспериментировать с ними.

На следующем уроке:

- работаем с Path

- в чатах решаем возникающие вопросы и проблемы по различным темам: Android, Kotlin, RxJava, Dagger, Тестирование

- ну и если просто хочется поговорить с коллегами по разработке, то есть чат Флудильня

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

Читайте также: