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

Отсечение растровых изображений

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

KeyholeClip.cs

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

  class KeyholeClip: PrintableForm
  {
      protected Image        image;
      protected GraphicsPath path;

      public new static void Main()
      {
          Application.Run(new KeyholeClip());
      }
      public KeyholeClip()
      {
          Text = "Keyhole Clip";

          image = Image.FromFile(
               "..\\..\\..\\..\\Images and Bitmaps\\Apollo11FullColor.jpg");

          path = new GraphicsPath();
          path.AddArc(80, 0, 80, 80, 45, -270);
          path.AddLine(70, 180, 170, 180);
      }
      protected override void DoPage(Graphics grfx, Color clr, int cx, int cy)
      {
          grfx.SetClip(path);
          grfx.DrawImage(image, 0, 0, image.Width, image.Height);
      }
  }

Результат выглядит несколько нелепо (откуда на Луне замочная скважина?), но все работает:


Рис. 15.10.

Ясно, что в этой программе я определил контур на основе размеров заданного изображения (исходя из предположения, что его размер будет выражен в пикселях, а начало координат будет в точке (0, 0), расположенной в левом верхнем углу изображения).

Но допустим, что нужно нарисовать область отсечения в центре клиентской области программы. Нарисовать изображение в центре нетрудно, но как центрировать контур? Одно из решений — создать контур заново на основе размеров клиентской области. Другое решение — переместить контур или вызвать методы, перемещающие область отсечения:


Методы TranslateClip класса Graphics



void TranslateClip(int cx, int су)
void TranslateClip(float cx, float cy)


Программа KeyholeClipCentered переопределяет KeyholeClip и располагает как область отсечения, так и контур по центру клиентской области программы.

KeyholeClipCentered.cs

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

  class KeyholeClipCentered: KeyholeClip
  {
      public new static void Main()
      {
          Application.Run(new KeyholeClipCentered());
      }
      public KeyholeClipCentered()
      {
          Text += " Centered";
      }
      protected override void DoPage(Graphics grfx, Color clr, int cx, int cy)
      {
          grfx.SetClip(path);

          RectangleF rectf   = path.GetBounds();
          int        xOffset = (int)((cx - rectf.Width)  / 2 - rectf.X);
          int        yOffset = (int)((cy - rectf.Height) / 2 - rectf.Y);

          grfx.TranslateClip(xOffset, yOffset);
          grfx.DrawImage(image, xOffset, yOffset, image.Width, image.Height);
      }
  }

Кроме того, можно создать новую растровую картинку на основе размеров отсеченного изображения и применить эффект прозрачности, чтобы получить тот же результат. Эту методику демонстрирует программа KeyholeBitmap.

KeyholeBitmap.cs

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

  class KeyholeBitmap: PrintableForm
  {
      Bitmap bitmap;

      public new static void Main()
      {
          Application.Run(new KeyholeBitmap());
      }
      public KeyholeBitmap()
      {
          Text = "Keyhole Bitmap";

          // Загрузка изображения
          
          Image image = Image.FromFile(
               "..\\..\\..\\..\\Images and Bitmaps\\Apollo11FullColor.jpg");

          // Создание контура отсечения

          GraphicsPath path = new GraphicsPath();
          path.AddArc(80, 0, 80, 80, 45, -270);
          path.AddLine(70, 180, 170, 180);

          // Получение размера контура отсечения

          RectangleF rectf = path.GetBounds();
 
          // Создание нового прозрачного растра

          bitmap = new Bitmap((int) rectf.Width, (int) rectf.Height, 
                              PixelFormat.Format32bppArgb);

          // Создание объекта Graphics на основе нового растра

          Graphics grfx = Graphics.FromImage(bitmap);

          // Рисуем исходное изображение на растр с отсечением

          grfx.SetClip(path);
          grfx.TranslateClip(-rectf.X, -rectf.Y);
          grfx.DrawImage(image, (int) -rectf.X, (int) -rectf.Y,
                                 image.Width, image.Height);
          grfx.Dispose();
      }
      protected override void DoPage(Graphics grfx, Color clr, int cx, int cy)
      {
          grfx.DrawImage(bitmap, (cx - bitmap.Width) / 2, 
                                 (cy - bitmap.Height) / 2,
                                 bitmap.Width, bitmap.Height);
      }
  }

Загрузка изображения и создание контура выполняется в конструкторе также, как и в KeyholeClip. Далее программа получает размер контура и использует полученное значение для создания нового объекта Bitmap. Для пикселей растрового изображения задается формат Format32bppArgb (впрочем, это все равно значение по умолчанию). Все точки растрового изображения инициализируются нулевыми значениями. Это значит, что первоначально изображение будет прозрачным, а все, что будет на нем нарисовано, — нет.

Далее конструктор получает объект Graphics для растрового изображения и задает область отсечения при помощи контура. Проблема, однако, в том, что новая картинка меньше, чем загруженная, поэтому контур будет ориентирован неверно. Метод TranstateClip правильно располагает область отсечения, a DrawImage (вызванный с теми же коэффициентами смещения, что и TranslateClip) рисует загруженное изображение поверх нового.

Метод DoPage просто центрирует изображение в области экрана. Программа также может сохранить новое изображение в файле.


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

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