netlib.narod.ru< Назад | Оглавление | Далее >

Загрузка и вывод изображений

Класс Image является абстрактным, т.е. его экземпляр нельзя создать конструктором. Однако, как уже упоминалось, он содержит четыре статических метода, позволяющих получить объект Image, и два метода для получения объекта Bitmap.


Статические методы класса Image (выборочно)



Image Image.FromFile(string strFilename)
Image Image.FromFile(string strFilename, bool bUseImageColorManagement)
Image Image.FromStream(Stream stream)
Image Image.FromStream(Stream stream, bool bUseImageColorManagement)
Bitmap Image.FromHbitmap(IntPtr hBitmap)
Bitmap Image.FromHbitmap(IntPtr hBitmap, IntPtr hPalette)


Два последних метода обычно применяют только при взаимодействии с Win32-кодом. Однако первые два очень мощны и просты в использовании:

  Image image = Image.FromFile("CuteCat.jpg");

Одна из замечательных возможностей данного метода — то, что он определяет формат файла по его содержимому, а не по расширению. Например, если бы файл CuteCat.jpg был PNG-файлом, которому вы ошибочно присвоили неверное расширение, метод FromFile все равно бы выполнился. При невозможности найти или открыть файл, а также в случае проблем с его содержимым метод FromFile генерирует исключение.

Два других метода используют вместо имени файла объект типа Stream, однако файлы и потоки тесно связаны. Stream — это абстрактный класс пространства имен System.IO, реализующий такие методы, как Read, Write и Seek. Во многих случаях поток — это просто открытый файл. И все же объект Stream может также предоставлять последовательные данные, хранимые в блоке памяти или передаваемые по сети. Подробнее о файлах и потоках см. приложение А.

Логические аргументы методов FromFile и FromStream отвечают за управление цветом, но эта тема выходит за рамки данной книги.

Согласно документации первые четыре метода возвращают объект типа Image, однако, вызвав для возвращаемого значения метод GetType, вы обнаружите, что его тип — System.Drawing.Bitmap или System.Drawing.Imaging.Metafile в зависимости от типа загруженного файла (или потока).

В большинстве программ этой главы используется файл Apollo11FullColor.jpg, хранящийся на прилагаемом компакт-диске в каталоге Images And Bitmaps, содержащем проекты этой главы. Это знаменитый портрет космонавта Базза Олдрина снятый Нилом Армстронгом при помощи камеры Hasselblad на поверхности Луны. Как следует из имени файла, он содержит полноцветное растровое изображение с разрядностью 24 бита на пиксел. Для экспериментов в этой же папке имеются файлы Apollo11GrayScale.jpg и Apollo11Palette.png с разрядностью 8 бит на пиксел. Ширина изображения во всех трех файлах — 220, а высота — 240 пикселов. Разрешение составляет 72 dpi.

Для начала — небольшая программа, которая получает объект Image с помощью метода Image.FromFile и затем выводит его методом DrawImage объекта Graphics.

ImageFromFile.cs

  //----------------------------------------------
  // ImageFromFile.cs (C) 2001 by Charles Petzold
  //----------------------------------------------
  using System;
  using System.Drawing;
  using System.Windows.Forms;

  class ImageFromFile: PrintableForm
  {
      public new static void Main()
      {
          Application.Run(new ImageFromFile());
      }
      public ImageFromFile()
      {
          Text = «Image From File»;
      }
      protected override void DoPage(Graphics grfx, Color clr, int cx, int cy)
      {
          Image image = Image.FromFile(«..\\..\\..\\Apollo11FullColor.jpg»);

          grfx.DrawImage(image, 0, 0);
      }
  }

Аргумент метода FromFile указывает расположение JPEG-файла относительно расположения файла ImageFromFile.exe. Если вы переместили один из файлов в другую папку, метод FromFile не найдет JPEG-файл и сгенерирует исключение. Аргументы метода DrawImage определяют положение верхнего левого угла изображения относительно клиентской области. Если в качестве аргументов передана точка (0, 0), изображение будет размещено в левом верхнем углу области.


Рис. 11.2.

Можно щелкнуть по клиентской области окна и распечатать изображение (заметьте: данный класс создан на основе класса PrintableForm, обсуждавшегося в главе 5). Думаю, вам будет приятно увидеть, что при печати картинка не уменьшается до размеров почтовой марки, как часто происходит при печати растровых изображений.

Для сравнения загрузите этот же JPEG-файл в другое приложение (скажем, в программу Imaging, поставляемую с Windows 2000). Вероятно, вы заметите, что в ImageFromFile изображение чуть больше по размеру, чем в других приложениях. Скоро я объясню, почему это так.

Сейчас я хочу привлечь ваше внимание к двум недостаткам программы ImageFromFile, которые сознательно проигнорировал раньше, чтобы продемонстрировать простоту загрузки и вывода растрового изображения. На самом деле это не так просто, как показывает ImageFromFile! О первой проблеме я уже говорил: если метод FromFile не находит файл по указанному адресу, он генерирует исключение. Программа должна уметь его перехватывать. Вторая проблема — место вызова FromFile. В подобной программе вызов должен выполняться только раз, лучше всего — в ее конструкторе. Программа может сохранить объект Image в поле и обратиться к нему из метода OnPaint. Вот усовершенствованная версия ImageFromFile:

BetterImageFromFile.cs

  //----------------------------------------------------
  // BetterImageFromFile.cs (C) 2001 by Charles Petzold
  //----------------------------------------------------
  using System;
  using System.Drawing;
  using System.Windows.Forms;

  class BetterImageFromFile: PrintableForm
  {
      Image image;

      public new static void Main()
      {
          Application.Run(new BetterImageFromFile());
      }
      public BetterImageFromFile()
      {
          Text = "Better Image From File";

          string strFileName = "..\\..\\..\\Apollo11FullColor.jpg";

          try
          {
              image = Image.FromFile(strFileName);
          }
          catch
          {
              MessageBox.Show("Cannot find file " + strFileName + "!",
                        Text, MessageBoxButtons.OK, MessageBoxIcon.Hand);
          }
      }
      protected override void DoPage(Graphics grfx, Color clr, int cx, int cy)
      {
          if (image == null)
              return;

          grfx.DrawImage(image, 0, 0);
      }
  }

Тем не менее для простоты в большинстве следующих программ этой главы существование файла не проверяется.

Показанный ниже статический метод Image.FromStream полезен при наличии доступа к открытому файлу, а также при получении потока от источника, отличного от файловой системы. Например, метод FromStream позволяет загрузить изображение из Интернета. Следующая программа обращается к Web-узлу NASA и загружает файл, который я обрезал и внес еще некоторые изменения для создания демонстрируемого в этой главе файла Apollo11.

ImageFromWeb.cs

  //---------------------------------------------
  // ImageFromWeb.cs (C) 2001 by Charles Petzold
  //---------------------------------------------
  using System;
  using System.Drawing;
  using System.IO;
  using System.Net;
  using System.Windows.Forms;

  class ImageFromWeb: PrintableForm
  {
      Image image;

      public new static void Main()
      {
          Application.Run(new ImageFromWeb());
      }
      public ImageFromWeb()
      {
          Text = "Image From Web";

          string strUrl =
               "http://images.jsc.nasa.gov/lores/AS11-40-5903.jpg";

          WebRequest   webreq = WebRequest.Create(strUrl);
          WebResponse  webres = webreq.GetResponse();
          Stream       stream = webres.GetResponseStream();

          image = Image.FromStream(stream);
          stream.Close();
      }
      protected override void DoPage(Graphics grfx, Color clr, int cx, int cy)
      {
          grfx.DrawImage(image, 0, 0);
      }
  }

Инструкции, использующие классы WebRequest и WebResponse, демонстрируют стандартный подход к загрузке файлов из Web. В этой программе метод GetResponseStream класса WebResponse получает доступный для чтения поток JPEG-файла. На данном этапе поток можно просто передать методу Image.FromStream:

  image = Image.FromStream(stream);

В программе ImageFromWeb нет некоторых функций, стандартных для приложений, загружающих файлы из Интернета. Возможно, вам стоит реализовать индикатор выполнения (что легко сделать через объект типа ProgressBar) и перенести код чтения потока во второй подпроцесс.


Рис. 11.3.


netlib.narod.ru< Назад | Оглавление | Далее >

Сайт управляется системой uCoz