« Поставить закладку » « Сделать стартовой »

« Форумы » « Блоги » « Статьи » « Новости » « Файлы » « Realcoding IRC » « Site map » « Поиск »


Главная Главная
Анонсы Анонсы
Форумы Форумы
Каталог Каталог
Поиск Поиск
Опросы Опросы
Книжный магазин Книжный магазин
Реклама на сайте
Публикации Публикации
Партнеры Партнеры
Карта Карта сайта
Рассылки Рассылки
RSS экспорт
Настройки Настройки
О нас пишут О нас пишут
Контакты Контакты
Гостевая книга Гостевая книга


ПнВтСрЧтПтСбВс
      1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31  
    Популярное
Обзор Visual Basic 9.0

Компоненты: ListView

Объекты в Oracle

Вывод дерева в MySQL

Тестирование ПО как один из элементов системы качества

Функция RestoreDC

NAT и PAT для PIX и ASA

Функция GetNextDlgTabItem

Глава 2. Среда программирования VB .NET: Visual Studio .NET

Удаление объектов из формы




    Архив файлов



    Сообщества

    Документация

    Кто на сайте
Вы не зарегистрированы.
Имя:

Пароль:

Запомнить

Регистрация позволит Вам пользоваться дополнительными сервисами.
Сейчас на сайте:
Гостей: 168
Пользователей: 0

Статьи:: Интернет технологии :: Технология JAVA :: Динамическая графика в Java сервлетах



отправить ссылку другу версия для печати  Обсудить на форуме

Динамическая графика в Java сервлетах



Обзор

    Как создать графический счетчик посещений? Диаграмму, изображающую загруженность канала до провайдера или количество писем в очереди? Одним словом, как сформировать изображение динамически по запросу пользователя? В своей статье Ken McCrary предлагает варианты решения этой задачи. (2500 слов)

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

Чтение и запись изображений, требования к JDK

Для того чтобы сервлет - приложение, выполняемое на сервере, которое обрабатывает запросы пользователей,- мог динамически создавать изображения, прежде всего, необходим механизм чтения и записи графических файлов. Точнее, сервлет должен уметь отправить полученную картинку в ответ на запрос пользователя. Основные библиотеки (Core API) для Java не предоставляют средств, используя которые можно было бы сохранить полученное в памяти изображение в одном из графических форматов. Есть библиотеки Sun для Java 1.1 и лицензированные Sun библиотеки для Java 1.2. Поскольку, они расположены в пакете com.sun они не относятся ни к основным библиотекам, ни к стандартным расширениям (standard extension), поэтому использующие их приложения нельзя считать переносимыми (portable). Другими словами, они могут и не работать на виртуальной машине, выпущенной другой компанией. Стоит отметить, что утвержденный запрос Java Specification Request JSR-000015 на стандартное расширение Java 2 содержит описание механизма для чтения и записи графических файлов; когда он будет реализован, можно будет писать переносимые программы, осуществляющие ввод/вывод изображений.

Для этой статьи я подготовил примеры, работающие на платформах Java 1.1 и Java 1.2.

Форматы изображений

Формат GIF - самый распространенный формат графических файлов в Веб. Он широко поддерживается броузерами, в том числе и самыми первыми. К сожалению, написание программ, генерирующих изображения в этом формате, потенциально затруднено патентом на алгоритм сжатия данных. Программ, приведенные в этой статье, создают изображения в формате JPEG и PNG. Формат JPEG выбран, прежде всего, из тех соображений, что реализация Sun Java 1.2 позволяет формировать изображения этого типа без применения дополнительных библиотек. (В примере приложения для JDK 1.1 можно получить файл не только в формате PNG, но и во многих других, в том числе - JPEG и GIF - прим. переводчика)

Одно из различий между форматами JPEG и GIF состоит в том, что алгоритм сжатия данных, используемый в GIF, в отличие от алгоритма, используемого в JPEG, не искажает изображение. Обычно, артефакты в JPEG картинках не сильно заметны. (Следует отметить, что формат JPEG лучше справляется с представлением фотографий, нежели текста, диаграмм или изображений, содержащих тонкие линии и четкие границы цветовых переходов - прим. переводчика) Второй пример применяет формат PNG с алгоритмом сжатия без потери данных и, к тому же, свободный от правовых затруднений.

Архитектура сервлета

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

public interface ImageProducer {
        /**
         * MIME тип создаваемого изображения.
         *
         * @return MIME тип изображения.
         */
        public String getMIMEType();
        /**
         * Создает изображение и записывает его в указанный поток.
         *
         * @param stream Куда писать картинку.
         */
        public void createImage(OutputStream stream)
      throws IOException;
}

Интерфейс ImageProducer содержит метод для определения типа изображения и метод для формирования изображения. Полученная картинка отправляется клиенту.

Следующий код демонстрирует, как сервлет работает с классами, реализующими интерфейс ImageProducer:

ImageProducer imageProducer =
        (ImageProducer)
     Class.forName(request.getQueryString()).newInstance();
response.setContentType(imageProducer.getMIMEType());
imageProducer.createImage(response.getOutputStream());

Сервлет создает (загружается) класс с именем, указанным в параметрах запроса - части URL справа после "?". Полученный класс приводится к типу ImageProducer. Затем, обращаясь к соответствующим методам, сервлет получает тип и формирует изображение. В случае если нет ошибок, картинка пересылается клиенту.

Приведенный код может вызвать несколько исключений, наиболее распространенные из них: ClassNotFoundException и ClassCastException. Первое вызвано тем, что класс, имя которого передано в качестве параметра запроса, не доступен загрузчику (ClassLoader), второе же тем, что указанный класс не реализует интерфейс ImageProducer. В случае ошибки клиент, конечно же, не получает картинку, и броузер выводит изображение, показывающее, что сервер не ответил на запрос. Программа тестировалась с использованием Java Server Web Development Kit (JSWDK 1.0.1), но вы должны получить аналогичные результаты на большинстве других Веб серверах, поддерживающих Java.

Создание изображений в Java 1.1

Для своего первого примера я подготовил код, который будет работать на платформе Java 1.1. Хотя виртуальные машины JVM 1.2 достаточно распространены, не все могут размещать программы на этой платформе. К сожалению, провайдеры не сильно спешат обновлять виртуальные машины на своих серверах. Как следствие, приходится разрабатывать сервлеты, работающие на платформе Java 1.1. Это не сильно затруднят задачу; тем не менее, есть некоторые сложности, связанные с формированием изображений, которые мы обсудим ниже.

Будем строить круговую диаграмму (pie chart), которую мы, для полноты картины, раскрасим и подпишем. На диаграмме будут изображены напитки, употребляемые разработчиками программного обеспечения. Посмотрим, как можно это сделать.

Для операций ввода/вывода изображений в Java 1.1 Sun предлагает библиотеку Jimi. Sun приобрел ее у небольшой компании. Перед тем, как начать распространять эту библиотеку, компания Sun перенесла классы в пакет com.sun, а в остальном ничего не изменила.

Следующие шаги необходимо проделать для формирования PNG изображения с использованием Jimi.

  1. Создать окно приложения(Frame для получения изображения.
  2. Использую AWT изображение, создать реализацию класса Graphics.
  3. Нарисовать картинку с помощью объекта Graphics.
  4. Создать объект JimiWriter на основе потока данных, передаваемых клиенту.
  5. Преобразовать изображение в соответствующий формат и отправить его клиенту.

Для формирования и модификации изображений на платформе Java 1.1 необходимо использовать активную AWT компоненту. Как правило, сервлет не должен создавать AWT компоненты, которые обычно используются в приложениях с графическим интерфейсом пользователя. В этом случае, вам нужен графический (AWT) объект для того, что бы получить объект класса Graphics, с помощью которого можно рисовать новые картинки. Придется смириться с маленьким окошком на консоли Веб сервера. Если вам известны способы создания изображения в Java 1.1 без использования AWT компонент, пожалуйста, сообщите мне. Один из возможных вариантов, загрузить с диска сервера заранее подготовленный шаблон, например методом java.awt.Toolkit.createImage(). После того, как вы создали AWT изображение, вы можете получить реализацию класса Graphics и использовать ее для рисования. Имея в своем распоряжении объект Graphics, вы можете закрыть ненужное окно на консоли сервера. Я оставлю этот эксперимент заинтересованным читателям.

Напомню, что для связи с классом, рисующим круговую диаграмму, сервлет использует интерфейс ImageProducer. Поэтому наш класс JIMIProducer должен реализовывать этот интерфейс. Прежде всего, создадим AWT окно, AWT изображения и, наконец, объект Graphics:

        Frame f = new Frame();
        f.setVisible(tru;
        image = f.createImage(ImageWidth, ImageHeight);
        graphics = image.getGraphics();
        f.setVisible(false)

Ключевой метод класса JIMIProducer - drawSlice. Получая на входе метку и величину сегмента в градусах, этот метод рисует сегмент диаграммы, раскрашивает его и подписывает. Далее, я расскажу подробней, как это происходит.

Будем заполнять "внутренности" диаграммы по часовой стрелке, начиная с положения "три часа", то есть первую линию проведем из центра к окружности ограничивающей диаграмму в положении часовой стрелки в три часа дня (или ночи, как вам больше нравиться). Отступим по часовой стрелке необходимое количество градусов и нарисуем вторую линию, ограничивающую сегмент диаграммы. И так далее. Приведенный ниже код получает на входе величину сегмента в градусах и рисует границу этого сегмента. Он вызывается последовательно для всех сегментов, при этом предполагается, что в сумме угловые величины составят 360 градусов.

        //*************************************************
        // Преобразуем угол в радианы
        // 1 градус = pi/180 радиан
        //*************************************************
        double theta = degrees * (3.14/180);
        currentTheta += theta;
        //*************************************************
        // Переводим в декартовы координаты
        // x = r cos @
        // y = r sin @
        //*************************************************
        double x = Radius * Math.cos(currentTheta);
        double y = Radius * Math.sin(currentTheta);
        Point mark2 = newPoint(center);
        mark2.translate((int)x,(int)y);
        graphics.drawLine
      (center.x, center.y, mark2.x, mark2.y);

Затем, нужно раскрасить сегменты диаграммы. Для этого можно воспользоваться очень полезным методом fillArc():

        graphics.setColor(colors[colorIndex++]);
        graphics.fillArc(Inset,
  Inset,
  PieWidth,
  PieHeight,
  -1 * lastAngle,
  -1 * degrees);

Последняя задача метода drawSlice() нарисовать метки сегментов. Расположение надписи рассчитывается, основываясь на метрике используемого шрифта. Окончательный вариант диаграммы можно посмотреть на рисунке.


Рис. 1. - Окончательный вариант круговой диаграммы. (Не все броузеры показывают файлы формата PNG, поэтому здесь мы поставили GIF файл.)

Создание изображений в Java 1.2

Практически все интересуются сейчас курсами акций на бирже. Нарисуем (всем на радость) на нашей диаграмме курс акций компании Sun за одну из недель марта.

Для создания изображений в формате JPEG используется класс com.sun.image.codec.jpeg.JPEGImageEncoder. Повторюсь, что принадлежность к пакету com.sun означает, что этот класс не является частью основного API и к нему относятся все соответствующие предупреждения.

Класс JPEGImageEncoder "понимает", как перекодировать изображение java.awt.image.BufferedImage, так что его и будем использовать. Для создания класса BufferedImage нужно указать требуемые размеры изображения. После создания, класс BufferedImage предоставляет класс ava.awt.Graphics2D, который можно использовать для рисования на соответствующей классу BufferedImage картинке. Все просто? Итак, основные шаги, необходимые для формирования изображения в формате JPEG:

  1. Создаем класс JPEGImageEncoder, предоставляя ему поток OutputStream данных передаваемых клиенту.
  2. Создаем класс BufferedImage необходимых размеров.
  3. Используем реализацию класса Graphics2D, предоставляемую классом BufferedImage, для рисования диаграммы.
  4. С помощью полученного ранее класса JPEGImageEncoder перекодируем нарисованное изображение в формат JPEG и пишем его в поток, отправляемый клиенту.

Обсудим некоторые детали рисования с использованием Graphics2D.

Для создания графика курса акций нужно, собственно, нарисовать несколько линий. Пакет Java 2D, java.awt.geom, содержит все необходимые для этого классы. Абстрактный класс Line2D определяет отрезок прямой. Он имеет две реализации, отличающиеся типом используемых координат. Класс Line2D.Double применяет примитивный тип double, а класс Line2D.Float - вещественные числа с плавающей точкой. Высокая точность совершенно излишня для нашего графика, но я не буду экономить и создам отрезки прямой классом Line2D.Double.

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

        horAxis = new Line2D.Double(HorzInset,
  ImageHeight - VertInset,
  ImageWidth -  HorzInset,
  ImageHeight - VertInset);
        graphics.draw(horAxis);

Горизонтальная ось строится с небольшим отступом от границы экрана, предоставляя место для разметки. После создания вы рисуете линю, обращаясь к методу draw() объекта Graphics2D. Напомню, что вы получили его от реализации класса BufferedImage. Класс Graphics2D содержит методы для рисования графических примитивов, для наших целей более чем достаточно. На рисунке 2 приведен окончательный вариант графика.


Рис. 2. - Окончательный вариант графика курса акций.

Производительность

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

Заключение

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

Об авторе

KenMcCrary, сертифицированный Sun Java developer, живет в Нью-Йорке, Research Triangle Park. Он работал над большим количеством Java проектов. Вы можете посетить его сайт http://www.kenmccrary.com/

Ресурсы




Рубрика: Технология JAVA




HTML 5: пять вещей вызывающих особый интер....

Html

HTML 5 — это грядущее обновление гипертекстового языка разметки, основного способа создания контента для размещения его во всемирной паутине. Разработка HTML остановилась в 1999 году, на версии HTML 4.01 и с тех пор web-содержимое изменилось так, что текущие спецификации HTML перестали соответствовать сегодняшним требованиям. HTML 5 нацелен на то, чтобы увеличить функциональную совместимость HTML и соответствовать растущим требованиям разнообразного и смешанного web-контента. HTML 5 так же нацелен на устранение недостатков четвертой версии. В этой статье мы взглянем на 5 новых интересных вещей в HTML 5.


Подробнее... | Рубрика: Html | Добавлено: 22.12.2008

asp.net: ListView с разных сторон.

.NET компоненты

Элемент управления ListView был представлен в .Net Framework 3.5 как замена устаревшему GridView. Новый элемент имеет более расширенный функционал, чем его предшественник, но в тоже время лишен некоторых внутренних механизмов, что впрочем целиком следствие из расширенной универсальности ListView. Среди отличий ListView и GridView можно назвать и гибкую настройку разметки, что позволяет выводить данные не только в табличном виде, но и вообще в любом каком пожелает программист. Благодаря шаблонам ItemTemplate, EditItemTemplate, InsertItemTeplate можно настроить внешний вид при любом из состояний ListView: редактировании или выборе элемента.


Подробнее... | Рубрика: .NET компоненты | Добавлено: 22.12.2008

Создание кросс-таб отчета в Stimulsoft Rep....

.NET компоненты

Компания Стимулсофт предоставляет для разработчиков мощный набор инструментов для создания отчетов для Microsoft Visual Studio .Net 2005 и 2008; эти инструменты доступны как для Windows Forms, так и для Web Forms. Это генератор отчетов Stimulsoft Reports.Net. Генератор отчетов Stimulsoft Reports.Net имеет ряд особенностей: простая работа с дизайнером отчетов, полная поддержка экспорта в PDF, Word, Excel и многие другие форматы. Crystal Report и Microsoft Reporting Service – очень хорошие программные продукты для повседневной работы, но, если Вам необходимо создать отчеты с поддержкой кросс-табов, drill down, Ajax, штрих-кодов и возможностью подключения одновременно более одного источника данных, то Stimulsoft Reports.Net поможет Вам сэкономить массу времени. Также, данный генератор отчетов позволяет пользователям создавать свои собственные отчеты любой сложности. И все эти особенности делают Stimulsoft Reports.Net хорошим выбором в сфере программных продуктов для Business Intelligence.


Подробнее... | Рубрика: .NET компоненты | Добавлено: 22.12.2008

Остальные статьи:

VivaMP - инструмент для OpenMP
Создаем контекстно-зависимое WPF-приложени...
Windows Vista SP2: что внутри и что важно?
Вышел MySQL 5.1.30, первый стабильный рели...
Тестирование параллельных программ
Архитектура AMD64 (EM64T)
Платформа 2009. Определяя будущее
Windows Vista Bridge Sample Library - упра...
Оптимизация 64-битных программ
Подгрузка через AJAX HTML-кода, содержащег...
Обзор нового релиза самой мощной Ajax библ...
Firebug 1.3 и 1.4 alpha — что нового и инт...
Релиз Microsoft Silverlight 2.0. Что новог...
XML документация в C#
Курсоры в MySQL 5
Microsoft опубликовала подробности о сесси...
Microsoft делится подробностями о том, что...
Тестируем новый javascript от нового брауз...
MySQL Query Cache
Использование провайдеров компиляции в As...


Цитата дня (все,добавить):

Портал фрилансеров

работа на дому


    Рубрикатор

Программирование

C/С++
Обучение
Windows API
XAML
Моделирование
Паттерны
Visual Basic 7 .NET
WxWidgets
Функции WinApi
Функции С++
Разработка под Mac OS
Eiffel
Visual Studio 2008
UI дизайн
Алгоритмы
Конкурсные статьи
Turbo Pascal
Visual Studio
CASE-средства
Visual Studio 2005
Без VCL
Delphi
Тех. документация
Тестирование
Software Testing
ООП
TCP/IP
Google Android
Windows Installer
.NET Framework
Драйвера
C# C Sharp
Справка
Проектирование
Информ. системы
Visual Basic
Assembler
Оптимизация кода
Gtk+
Компоненты
Реинжиниринг
Управление проектами
Extreeme programming
Lotus Notes
Алгебраическое проектирование


Интернет технологии

PHP
Perl
ASP
WAP
Cookies
SSI
CGI
Web Servers
VB Script
DNS
CSS
XML
Html
Java Script
Java2ME
Firewall
Flash
.htaccess
Apache
VRML
Протоколы
Поисковые системы
Технология JAVA
Учебник по PHP
Учебник по JavaScript
Учебник по XML
Java Q&A
AJAX
DHTML
XHTML
Dreamweaver
Web 2.0
Python
Вебмастеру
Cisco
Ruby on Rails
Silverlight

Базы данных

Access
InterBase
MySQL
Oracle
ADO .NET
Основы SQL
Учебник по Access 2002
MS
Microsoft FoxPro
Доступ к данным
XML в MS SQL Server 2000
ODBC и MyODBC
Обучение
Caché
DB2
PostgresSQL
Sybase
Теория
Хранилища данных
Безопасность
Реляционные данные
MySQL и mSQL

Остальное:

Разное
Обзоры книг
Безопасность
Графика и дизайн
Юмор
Linux
Фракталы
Microsoft Axapta
Многоядерность
Сети
Microsoft Office
Работа
MS-DOS
Криптография
Графика и игроделание
Новости SDK
Системы защиты
Учебник по AutoCad
CVS
Windows XP
Windows Server 2003
Windows Vista
Windows 7
Мероприятия