2000 г

Динамическая графикаГрафика (греч. — письменный, от греч. — пишу)— вид изобразительного искусства, использующий в качестве основных изобразительных средств линии, штрихи, пятна и точки. (Цвет также может применяться, но, в отличие от живописи, здесь он играет вспомогательную роль. При рисовании графикой обычно используют не больше одного цвета (кроме основного черного), в редких случаях— два). Кроме контурной линии в графическом искусстве широко используются штрих и пятно, также контрастирующие с белой (а в иных случаях также цветной, чёрной, или реже— фактурной) поверхностью бумаги— главной основой для графических работ. Сочетанием тех же средств могут создаваться тональные нюансы. Наиболее общий отличительный признак графики— особое отношение изображаемого предмета к пространству, роль которого в значительной мере выполняет фон бумаги (по выражению советского мастера графики В.А.Фаворского,— «воздух белого листа»). в Java сервлетах

Кен МакКрэри,
Перевод на русский © Виктор Смирнов, 2000
Оригинал статьи опубликован на сайте Javable.com

Server-Side Java

Обзор

    Как создать графический счетчик посещений? Диаграмму, изображающую загруженность канала до провайдера или количество писем в очереди? Одним словом, как сформировать изображение динамически по запросу пользователя? В своей статье Ken McCrary предлагает вариантыВариант (фр.variante, от лат.varians, родительный падеж variantis — меняющий, изменяющийся) — одна из нескольких редакций какого-либо произведения (литературного, музыкального и т. п.) или официального документа; видоизменение какой-либо части произведения (разночтения отдельных слов, строк, строф, глав). решения этой задачи. (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Интерфейс (от англ.interface— поверхность раздела, перегородка)— совокупность средств, методов и правил взаимодействия (управления, контроля ит.д.) между элементами системы. ImageProducer {
        /**
         * MIME тип создаваемого изображения.
         *
         * @return MIME тип изображения.
         */
        public String getMIMEType();
        /**
         * Создает изображение и записывает его в указанный поток.
         *
         * @param stream Куда писать картинку.
         */
        public void createImage(OutputStream stream«Домашний Интернет и Телевидение МТС»— торговая марка, под которой компания «МТС» предоставляет в России услуги кабельного телевидения и широкополосного доступа в интернет.)
                 throws IOException;
}

ИнтерфейсИнтерфейс (от англ.interface— поверхность раздела, перегородка)— совокупность средств, методов и правил взаимодействия (управления, контроля ит.д.) между элементами системы. ImageProducer содержит метод для определения типа изображения и метод для формирования изображения. Полученная картинка отправляется клиенту.

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

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

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

Приведенный код может вызвать несколько исключений, наиболее распространенные из них: ClassNotFoundException и ClassCastException. Первое вызвано тем, что класс, имя которого передано в качестве параметра запроса, не доступен загрузчику (ClassLoader), второе же тем, что указанный класс не реализует интерфейс ImageProducer. В случае ошибки клиент, конечно же, не получает картинку, и броузерВеб-обозреватель, браузер (от англ.Web browser; вариант броузер— устаревшая форма)— программное обеспечение для просмотра веб-сайтов, то есть для запроса веб-страниц (преимущественно из Сети), их обработки, вывода и перехода от одной страницы к другой. выводит изображение, показывающее, что сервер не ответил на запрос. Программа тестировалась с использованием 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, вы можете закрыть ненужное окно на консоли сервера. Я оставлю этот эксперимент заинтересованным читателям.

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

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

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

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

        //*************************************************
        // Преобразуем угол в радианы
        // 1 градус = pi/180 радиан
        //*************************************************
        doubleЧисло двойной точности (Double precision, Double) — компьютерный формат представления чисел, занимающий в памяти две последовательных ячейки (компьютерных слова; в случае 32-битного компьютера — 64 бита или 8 байт). Как правило, обозначает формат числа с плавающей запятой стандарта IEEE 754. Числа с плавающей точкой (двойной/одинарной/четверной точности) поддерживаются сопроцессором (в 80386 выполнен как отдельный модуль, начиная с 80486 является встроенным в главный процессор. Сопроцессор, хотя он сейчас и является частью главного процессора, принято называть FPU — Floating Point Unit, буквально Модуль Плавающей Запятой).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

Ресурсы

Мы рекомендуем еще посмотреть:

Предварительный заказ телефонной станции

Поля, помеченные знаком [*], обязательны к заполнению.

 Бланк заказа 
 Станция предназначена:  для Вас
для Вашего заказчика
Количество абонентов
  Входящие линии
 Аналоговые двухпроводные линии СО: 
 E&M транки: 
  Цифровые потоки
 PRA: 
 BRA: 
 ИКМ: 
 IP-каналы: 
  Внутренние линии
 Аналоговые абоненты: 
 Цифровые абоненты: 
 IP телефоны: 
Дополнительные услуги
  DECT
 количество абонентов: 
 количество базовых станций: 
 Система тарификации, администрирования станции:  да
нет
Цифровые телефоны
  Количество функциональных кнопок
 24: 
 12: 
 8 (с дисплеем): 
 8 (без дисплея): 
  Панель расширения (только для цифровых телефонов на 24 и 12 кнопок)
 40 клавиш: 
 20 клавиш: 
 Кроссовое оборудование:  требуется
не требуется
 Бесперебойное питание:  требуется
не требуется
 Дополнительные требования: 
(выровнять
Ваши координаты
 Название компании: 
 ФИО *
 E-mail *
 Телефон (код города) *
 Факс (код города): 
Поиск:
Авторизация
Логин
Пароль
Регистрация >
  Мероприятия « 2009 »   
« август » 
Пн  310172431
Вт  4111825 
Ср  5121926 
Чт  6132027 
Пт  7142128 
Сб 18152229 
Вс 29162330 
2009 IT и оборудование для бизнеса, S-NETWORKS. Информационные технологии и Информационное оборудование