Как создать и использовать метафайл в C#

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

Когда программа запускается, он выполняет следующий код.

private void Form1_Load(object sender, EventArgs e)
{
    // Создаем метафайл.
    Metafile mf = MakeMetafile(100, 100, "test.emf");

    // Нарисуем метафайл.
    DrawOnMetafile(mf);

    // Преобразуем метафайл в растровое изображение.
    Bitmap bm = MetafileToBitmap(mf);

    // Отображение по-разному.
    picCanvas1.Image = bm;  // Оригинальный размер.
    picCanvas2.Image = bm;  // Растягивает пиксель.
    picCanvas3.Image = mf;  // Равномерно растягивается.
}

Этот код вызывает метод MakeMetafile (я кратко опишу все эти методы) для создания метафайла 100 × 100 пикселей, а затем вызывает DrawOnMetafile, чтобы нарисовать некоторые формы в метафайле. Затем он вызывает MetafileToBitmap, чтобы преобразовать метафайл в растровое изображение. Он отображает растровое изображение на двух элементах PictureBox и отображает сам метафайл на третьем.

Если вы посмотрите на изображение выше, вы увидите, что верхний PictureBox показывает хорошее четкое изображение. Это первый PictureBox, отображающий растровое изображение в правильном размере.

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

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

В следующем коде показан способ MakeMetafile.

// Возвращает метафайл с указанным размером.
private Metafile MakeMetafile(float width, float height,
    string filename)
{
    // Сделать ссылочное растровое изображение.
    using (Bitmap bm = new Bitmap(16, 16))
    {
        using (Graphics gr = Graphics.FromImage(bm))
        {
            RectangleF bounds =
                new RectangleF(0, 0, width, height);

            Metafile mf;
            if ((filename != null) && (filename.Length > 0))
                mf = new Metafile(filename, gr.GetHdc(),
                    bounds, MetafileFrameUnit.Pixel);
            else
                mf = new Metafile(gr.GetHdc(), bounds,
                    MetafileFrameUnit.Pixel);

            gr.ReleaseHdc();
            return mf;
        }
    }
}

Этот метод создает метафайл указанного размера, при необходимости сохраняя его в файле.

Чтобы создать новый метафайл, вам понадобится дескриптор графического устройства. Чтобы получить один, код создаст растровое изображение размером 16 × 16 пикселей. Размер растрового изображения не важен; код действительно просто должен использовать его для получения дескриптора графического устройства.

Далее код создает объект Graphics, связанный с растровым изображением. Это объект, который предоставит дескриптор устройства.

Затем код создает RectangleF, представляющий желаемый размер метафайла.

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

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

Вызов метода GetHdc объекта Graphics блокирует контекст устройства объекта, поэтому код затем вызывает его метод ReleaseHdc, чтобы он мог очистить Графика правильно.

Метод завершается возвратом метафайла.

Метод MakeMetafile, вероятно, является самой запутанной частью программы. Следующий код показывает метод DrawOnMetafile.

// Нарисуйте метафайл.
private void DrawOnMetafile(Metafile mf)
{
    using (Graphics gr = Graphics.FromImage(mf))
    {
        gr.SmoothingMode = SmoothingMode.AntiAlias;
        using (Pen pen = new Pen(Color.Red, 5))
        {
            gr.DrawEllipse(pen, 5, 5, 90, 90);
        }
        using (Brush brush = new SolidBrush(
            Color.FromArgb(255, 128, 255, 128)))
        {
            gr.FillEllipse(brush, 5, 25, 90, 50);
        }
        using (Brush brush = new SolidBrush(
            Color.FromArgb(128, 128, 128, 255)))
        {
            gr.FillEllipse(brush, 25, 5, 50, 90);
        }
        Point[] points =
        {
            new Point(50, 5),
            new Point(94, 50),
            new Point(50, 94),
            new Point(5, 50),
        };
        gr.DrawPolygon(Pens.Blue, points);
    }
}

Этот метод прост. Он просто создает объект Graphics, связанный с метафайлом, и использует его для рисования некоторых фигур так же, как если бы вы рисовали растровое изображение или в обработчике событий Paint.

Наконец, следующий код показывает метод MetafileToBitmap, который преобразует метафайл в растровое изображение.

// Нарисуем метафайл в растровое изображение.
private Bitmap MetafileToBitmap(Metafile mf)
{
    Bitmap bm = new Bitmap(mf.Width, mf.Height);
    using (Graphics gr = Graphics.FromImage(bm))
    {
        GraphicsUnit unit = GraphicsUnit.Pixel;
        RectangleF source = mf.GetBounds(ref unit);

        PointF[] dest =
        {
            new PointF(0, 0),
            new PointF(source.Width, 0),
            new PointF(0, source.Height),
        };
        gr.DrawImage(mf, dest, source, GraphicsUnit.Pixel);
    }
    return bm;
}

Этот метод создает растровое изображение того же размера, что и метафайл, и создает связанный объект Graphics. Затем он использует несколько неудобный метод GetBounds для получения границ метафайла в пикселях, делает массив точек для определения области назначения в растровом изображении, а затем рисует метафайл в растровое изображение. Он заканчивается возвратом растрового изображения.

Источник: http://csharphelper.com/blog/2016/04/make-use-metafile-c/

1 Звезда2 Звезды3 Звезды4 Звезды5 Звезд (Пока оценок нет)
Adblock
detector