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

Подгонка под прямоугольник

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


Методы DrawImage класса Graphics (выборочно)



void DrawImage(Image image, int x, int y, int cx, int cy)
void DrawImage(Image image, float x, float y, float cx, float cy)
void DrawImage(Image image, Rectangle rect)
void DrawImage(Image image, RectangleF rectf)


Эти методы подгоняют изображение под размеры прямоугольника, растягивая или сжимая его. Одно из распространенных применений данных методов — вывод изображения в пиксельном, а не метрическом размере. Если единицы измерения страницы — пикселы, просто вызовите:

  grfx.DrawImage(image, x, y, image.Width, image.Height);

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

CenterPixelSizeImage.cs

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

  class CenterPixelSizeImage: PrintableForm
  {
      Image image;

      public new static void Main()
      {
          Application.Run(new CenterPixelSizeImage());
      }
      public CenterPixelSizeImage()
      {
          Text = "Center Pixel-Size Image";

          image = Image.FromFile("..\\..\\..\\Apollo11FullColor.jpg");
      }
      protected override void DoPage(Graphics grfx, Color clr, int cx, int cy)
      {
          grfx.DrawImage(image, (cx - image.Width)  / 2,
                                (cy - image.Height) / 2,
                                image.Width, image.Height);
      }
  }

Разрешение вашего монитора скорее всего превышает 72 dpi, и поэтому картинка будет иметь меньший размер, чем при выводе методом DrawImage.


Рис. 11.4.

Если вывести растровое изображение размером 220 × 240 пикселов с помощью этой версии DrawImage на принтер с разрешением 100 dpi, размер изображения составит примерно 2,2 × 2,4 дюйма. Если в методе DoPage сделать единицей измерения страницы пиксел, печатное изображение будет гораздо меньше — скорее всего вы столкнетесь с эффектом почтовой марки, распространенным в простых средах графического программирования.

Следующая программа загружает изображение и выводит его на всю клиентскую область (или печатную область страницы принтера).

ImageScaleToRectangle.cs

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

  class ImageScaleToRectangle: PrintableForm
  {
      Image image;

      public new static void Main()
      {
          Application.Run(new ImageScaleToRectangle());
      }
      public ImageScaleToRectangle()
      {
          Text = "Image Scale To Rectangle";

          image = Image.FromFile("..\\..\\..\\Apollo11FullColor.jpg");
      }
      protected override void DoPage(Graphics grfx, Color clr, int cx, int cy)
      {
          grfx.DrawImage(image, 0, 0, cx, cy);
      }
  }

При значительном изменении ширины или высоты клиентской области изображение будет соответствующим образом искажаться.


Рис. 11.5.

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

ImageScaleIsotropic.cs

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

  class ImageScaleIsotropic: PrintableForm
  {
      Image image;

      public new static void Main()
      {
          Application.Run(new ImageScaleIsotropic());
      }
      public ImageScaleIsotropic()
      {
          Text = "Image Scale Isotropic";

          image = Image.FromFile("..\\..\\..\\Apollo11FullColor.jpg");
      }
      protected override void DoPage(Graphics grfx, Color clr, int cx, int cy)
      {
          ScaleImageIsotropically(grfx, image, new Rectangle(0, 0, cx, cy));
      }
      void ScaleImageIsotropically(Graphics grfx, Image image, Rectangle rect)
      {
          SizeF sizef = new SizeF(image.Width  / image.HorizontalResolution,
                                  image.Height / image.VerticalResolution);

          float fScale = Math.Min(rect.Width  / sizef.Width,
                                  rect.Height / sizef.Height);

          sizef.Width  *= fScale;
          sizef.Height *= fScale;

          grfx.DrawImage(image, rect.X + (rect.Width  - sizef.Width ) / 2,
                                rect.Y + (rect.Height - sizef.Height) / 2,
                                sizef.Width, sizef.Height);
      }
  }

Метод ScaleImageIsotropically работает практически всегда, кроме случаев, когда горизонтальное и вертикальное разрешения устройства различны (это встречается у некоторых принтеров) и когда параметр PageUnit имеет значение GraphicsUnit.Pixel (в принтерах по умолчанию используются другие единицы измерения).

Для начала метод ScaleImageIsotropically рассчитывает структуру SizeF, определяющую размер объекта Image в дюймах (если горизонтальное и вертикальное разрешения изображения одинаковы, данный этап не нужен). Затем вычисляется некоторый коэффициент, равный меньшему из двух значений: частному от деления высоты прямоугольника на высоту изображения и ширины прямоугольника на ширину изображения. Этот коэффициент fScale используется для изотропного масштабирования изображения в прямоугольнике. Затем метод определяет начало координат прямоугольника и передает полученную информацию методу DrawImage. Вот что получается:


Рис. 11.6.

Версии DrawImage, ориентированные на прямоугольник, могут не только масштабировать изображение, но и кое-что другое. Если указать отрицательную ширину, картинка будет повернута по вертикальной оси, и вы получите ее зеркальную копию. При отрицательной высоте метод поворачивает ее по горизонтальной оси и отображает вверх ногами. В любом случае верхний левый утол исходного, неперевернутого изображения позиционируется согласно координатам Point и PointF прямоугольника, указанными в DrawImage.

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

ImageReflection.cs

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

  class ImageReflection: PrintableForm
  {
      Image image;

      public new static void Main()
      {
          Application.Run(new ImageReflection());
      }
      public ImageReflection()
      {
          Text = "Image Reflection";

          image = Image.FromFile("..\\..\\..\\Apollo11FullColor.jpg");
      }
      protected override void DoPage(Graphics grfx, Color clr, int cx, int cy)
      {
          int cxImage = image.Width;
          int cyImage = image.Height;

          grfx.DrawImage(image, cx / 2, cy / 2,  cxImage,  cyImage);
          grfx.DrawImage(image, cx / 2, cy / 2, -cxImage,  cyImage);
          grfx.DrawImage(image, cx / 2, cy / 2,  cxImage, -cyImage);
          grfx.DrawImage(image, cx / 2, cy / 2, -cxImage, -cyImage);
      }
  }

Вот эти четыре изображения.


Рис. 11.7.

Заметьте: при масштабировании программа использует пиксельный размер изображения.


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

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