Перечислить записи метафайлов в C#

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

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

// Сохранять метафайл.
private Metafile TheMetafile;

// Графический объект, используемый для рисования на текущем растровом изображении.
private Graphics TheGraphics;

// Индекс последней записи, которую мы нарисовали.
private int LastRecord;

private void Form1_Load(object sender, EventArgs e)
{
    clbRecords.CheckOnClick = true;
    picResult.SizeMode = PictureBoxSizeMode.Zoom;

    // Загрузим метафайл.
    TheMetafile = (Metafile)Metafile.FromFile("Volleyball.wmf");
    
    // Использовать любой объект Graphics для перечисления записей метафайла.
    using (Graphics gr = this.CreateGraphics())
    {
        gr.EnumerateMetafile(TheMetafile,
            new PointF(0, 0), ListRecordCallback);
    }

    // Изначально проверяем все записи.
    for (int i = 0; i < clbRecords.Items.Count; i++)
        clbRecords.SetItemChecked(i, true);

    // Отображение начального результата.
    DisplayRecords();
}

// Добавить запись в запись метафайла ListBox.
private bool ListRecordCallback(EmfPlusRecordType record_type,
    int flags, int data_size, IntPtr data,
    PlayRecordCallback callback_data)
{
    clbRecords.Items.Add(record_type.ToString());
    return true;
}

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

TheGraphics - это Graphics объект, который программа будет использовать для рисования на растровом изображении. LastRecord - это индекс последней записи в метафайле, который мы нарисовали. Вы увидите, как эти переменные используются в ближайшее время.

Обработчик событий Load формы загружает метафайл. Затем он создает объект Graphics (любой объект будет делать), а затем вызывает его метод EnumerateMetafile для перечисления записей метафайла. Конечным параметром этого метода является метод обратного вызова, который EnumerateMetafile должен вызывать для каждой записи метафайла.

Обработчик событий Load завершается проверкой всех элементов в CheckedListBox, а затем вызывает DisplayRecords, чтобы показать результат.

Метод ListRecordCallback вызывается для каждой записи в метафайле. Он добавляет имя типа записи в список программы.

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

// Нарисуйте отмеченные записи метафайлов.
private void DisplayRecords()
{
    // Создаем растровое изображение для сохранения результата.
    int wid = TheMetafile.Width;
    int hgt = TheMetafile.Height;
    Bitmap bm = new Bitmap(wid, hgt);

    // Начнем с первой записи.
    LastRecord = -1;

    // Нарисуем выбранные записи в растровом изображении.
    using (TheGraphics = Graphics.FromImage(bm))
    {
        Rectangle dest = new Rectangle(0, 0, wid, hgt);
        TheGraphics.EnumerateMetafile(
            TheMetafile, dest, DrawRecordCallback);
    }

    // Отображение результата.
    picResult.Image = bm;
}

Этот метод создает растровое изображение, которое имеет размер, соответствующий размеру метафайла. Обратите внимание, что разрешение растрового изображения, вероятно, не будет соответствовать разрешению метафайла. Метафайлы часто используют очень высокое разрешение, например, 1000 точек на дюйм. Напротив, растровое изображение, отображаемое на экране, обычно имеет разрешение 96 пикселей на дюйм. Возможно, вам захочется сделать растровое изображение достаточно большим, чтобы представлять каждую позицию в метафайле в виде пикселя. К сожалению, это даст вам действительно огромный растровый (это может быть миллионы пикселей в ширину и миллионы пикселей), которые вы, вероятно, не сможете создать.

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

Далее метод устанавливает LastRecord в -1, поэтому код чертежа начинается с первой записи.

Затем он создает объект Graphics, связанный с растровым изображением, и сохраняет его в переменной TheGraphics. Код создает Rectangle, чтобы представить область, в которой мы хотим, чтобы метафайл был нарисован, а затем вызывает метод EnumerateMetafile объекта Graphics для перечисления метафайла записи снова. На этот раз конечный параметр DrawRecord, поэтому метод вызывает его для каждой записи метафайла.

Метод завершается отображением растрового изображения.

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

// Нарисуем запись в TheGraphics.
private bool DrawRecordCallback(EmfPlusRecordType record_type,
    int flags, int data_size, IntPtr data,
    PlayRecordCallback callback_data)
{
    // Рассмотрим следующую запись.
    LastRecord++;

    // Если эта запись не выбрана, пропустите ее.
    if (!clbRecords.GetItemChecked(LastRecord))
    {
        Console.WriteLine("Skipping " + LastRecord +
            ": " + record_type.ToString());
        return true;
    }

    // Отобразите эту запись.
    byte[] data_array = null;
    if (!data.Equals(IntPtr.Zero))
    {
        // Копирование неуправляемых данных записи в управляемую
        // байтовый буфер, который мы можем передать в PlayRecord.
        data_array = new byte[data_size];
        Marshal.Copy(data, data_array, 0, data_size);
    }

    // Воспроизведение записи.
    TheMetafile.PlayRecord(record_type, flags,
        data_size, data_array);

    // Продолжаем перечисление.
    return true;
}

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

Если элемент отмечен, метод рисует запись. Для этого он создает массив байтов. Если запись имеет данные, код копирует ее в массив байтов. Затем метод вызывает метод PlayRecord метафайла, передавая ему информацию о записи. Это заставляет метафайл записывать запись на графический объект.

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

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