Работа с изображениями стандартными средствами Java

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

Способ 1. Добавление изображения с помощью JLabel.

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

Чтобы добавить изображение в JLabel существует метод setIcon(Icon image).

Также это можно сделать во время создания объекта JLabel с помощью конструктора JLabel(String text, Icon icon, int horizontalAlignment).

 

package javapicture1;

import javax.swing.ImageIcon;

import javax.swing.JFrame;

import javax.swing.JLabel;

 

public class JavaPicture

{

private static JLabel jLabel;

public static void main(String[] argv)

{

// Создаем новый объект JLabel.

jLabel = new JLabel();

// Выравниваем по горизонтали.

jLabel.setHorizontalAlignment(javax.swing.SwingConstants.LEFT);

// Выравниваем по вертикали

jLabel.setVerticalAlignment(javax.swing.SwingConstants.TOP);

// Указываем путь к изображению.

jLabel.setIcon(new ImageIcon(("D:\\ashesandsnow.jpg")));

// Текстовая подпись

jLabel.setText("Ваш комментарий.");

// Создаем объект главного окна приложения.

JFrame f = new JFrame("Picture");

f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

f.add(jLabel);

f.setSize(550,350);

f.setLocation(200,200);

f.setVisible(true);

}

}

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

Способ 2. Добавление изображения с помощью JPanel.

Использование этого способа заключается в создании нового класса (назовем его PicturePanel) в качестве наследника стандартного JPanel. В новом классе реализуется метод setImageFile(File imageFile), который позволяет загрузить изображение из файла и прорисовать его на фоне JPanel.

public void setImageFile(File imageFile)

{

Try

{

if (imageFile == null)

{

originalImage = null;

}

// Читаем файловый поток.

BufferedImage bi = ImageIO.read(imageFile);

originalImage = bi;

}

catch (IOException ex)

{

// В случае ошибки, выводим сообщение.

System.err.println("Не удалось загрузить изображение!");

ex.printStackTrace();

}

// Перерисовываем компонент уже с новым загруженным изображением.

repaint();

}

При изменении размера панели, размеры изображения также меняются, таким образом создается эффект «резинового» изображения, которое «подстраивается» под размеры окна.

// Реакция на изменение размеров панели - изменение размера изображения.

private void formComponentResized(java.awt.event.ComponentEvent evt)

{

int w = this.getWidth();

int h = this.getHeight();

if ((originalImage != null) && (w > 0) && (h > 0))

{

image = originalImage.getScaledInstance(w, h, Image.SCALE_DEFAULT);

this.repaint();

}

}

Ниже приведен полный листинг демо-проекта с комментариями.

package javapicture2;

import java.awt.Graphics;

import java.awt.Image;

import java.awt.image.BufferedImage;

import java.io.File;

import java.io.IOException;

import javax.imageio.ImageIO;

import javax.swing.JFrame;

import javax.swing.JLabel;

import javax.swing.JPanel;

 

public class JavaPicture

{

private static JLabel jLabel;

public static void main(String[] argv)

{

// Создаем объект класс PicturePanel.

PicturePanel picturePanel = new PicturePanel();

// Загружаем в него изображение.

picturePanel.setImageFile(new File("D:\\ashesandsnow.jpg"));

// Создаем объект главного окна приложения.

JFrame f = new JFrame("Picture");

f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

f.add(picturePanel);

f.setSize(550,350);

f.setLocation(200,200);

f.setVisible(true);

}

}

 

class PicturePanel extends JPanel

{

// В объекте класса храним 2 изображения: оригинальное и текущее.

// Оригинальное используется для получения текущего в зависимости от размеров

панели.

// Текущее рисуется на панели на панели.

private BufferedImage originalImage = null;

private Image image = null;

public PicturePanel()

{

initComponents();

}

private void initComponents()

{

addComponentListener(new java.awt.event.ComponentAdapter()

{

public void componentResized(java.awt.event.ComponentEvent evt)

{

formComponentResized(evt);

}

});

}

// Реакция на изменение размеров панели - изменение размера изображения.

private void formComponentResized(java.awt.event.ComponentEvent evt)

{

int w = this.getWidth();

int h = this.getHeight();

if ((originalImage != null) && (w > 0) && (h > 0))

{

image = originalImage.getScaledInstance(w, h, Image.SCALE_DEFAULT);

this.repaint();

}

}

 

@Override

public void paint(Graphics g)

{

super.paint(g);

/ Прорисовка изображения.

if (image != null)

{

g.drawImage(image, 0, 0, null);

}

// Прорисовка компонент.

super.paintChildren(g);

super.paintBorder(g);

}

public BufferedImage getImage()

{

return originalImage;

}

public void setImage(BufferedImage image)

{

this.image = image;

}

public void setImageFile(File imageFile)

{

try

{

if (imageFile == null)

{

originalImage = null;

}

// Читаем файловый поток.

BufferedImage bi = ImageIO.read(imageFile);

originalImage = bi;

}

catch (IOException ex)

{

// В случае ошибки, выводим сообщение.

System.err.println("Не удалось загрузить изображение!");

ex.printStackTrace();

}

// Перерисовываем компонент уже с новым загруженным изображением.

repaint();

}

}

Изменение размеров окна приводит к пропорциональному изменению размеров изображения.

Важным преимуществом приведенного метода является возможность добавлять другие контролы (элементы GUI) на созданный объект PicturePanel, т.е. использовать его в качестве компонента-контейнера, добиваясь тем самым достижения эффекта фонового изображения.

Способ 3. Добавление изображения с помощью класса Image.

Простой способ, который заключается в создании объекта Image, а затем его отрисовку с помощью метода drawImage() объекта типа Graphics в методе paint() объекта типа JFrame.

 

package javapicture3;

import java.awt.Graphics;

import java.awt.Image;

import javax.swing.JFrame;

public class JavaPicture extends JFrame

{

public static void main(String[] args)

{

JavaPicture f = new JavaPicture();

f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

f.setSize(460,370);

f.setLocation(200,100);

f.setVisible(true);

}

@Override

public void paint(Graphics gr)

{

super.paint(gr);

Image img = getToolkit().getImage("D:\\ashesandsnow.png");

gr.drawImage(img,30,50,this);

}

}

 

Данный метод хорош тем, что объекты Image можно обрабатывать с помощью фильтров:

• CropImageFilter (int x, int у, int w, int h) — выделяет фрагмент изображения, указанный в приведенном конструкторе;

• RGBimageFilter — позволяет изменять отдельные пикселы; это абстрактный класс, он требует расширения и переопределения своего метода filterRGBO;

• RepдicateScaieFilter (int w, int h) — изменяет размеры изображения на указанные в приведенном конструкторе, дублируя строки и/или столбцы при увеличении размеров или убирая некоторые из них при уменьшении;

• AreaAveragingScaleFilter (int w, int h) — расширение предыдущего класса; использует более сложный алгоритм изменения размеров изображения

Применяются классы-фильтры совместно с классом-поставщиком, реализующим интерфейс ImageProducer — классом FilteredlmageSource. Этот класс преобразует уже готовую продукцию, полученную от другого поставщика producer, используя для преобразования объект filter класса-фильтра imageFilter или его подкласса.