GDI + / C#: Как сохранить образ как EMF?

NullPointerException s - исключения, возникающие при попытке использовать ссылку, которая указывает на отсутствие местоположения в памяти (null), как если бы она ссылалась на объект. Вызов метода по нулевой ссылке или попытка получить доступ к полю нулевой ссылки вызовет функцию NullPointerException. Они наиболее распространены, но другие способы перечислены на странице NullPointerException javadoc.

Вероятно, самый быстрый пример кода, который я мог бы придумать для иллюстрации NullPointerException, be:

public class Example {

    public static void main(String[] args) {
        Object obj = null;
        obj.hashCode();
    }

}

В первой строке внутри main я явно устанавливаю ссылку Object obj равной null. Это означает, что у меня есть ссылка, но она не указывает на какой-либо объект. После этого я пытаюсь обработать ссылку так, как если бы она указывала на объект, вызывая метод на нем. Это приводит к NullPointerException, потому что нет кода для выполнения в местоположении, на которое указывает ссылка.

(Это техничность, но я думаю, что она упоминает: ссылка, которая указывает на null, равна 't то же, что и указатель C, указывающий на недопустимую ячейку памяти. Нулевой указатель буквально не указывает на в любом месте , который отличается от указаний на местоположение, которое оказывается недопустимым.)

18
задан jnm2 2 December 2016 в 13:12
поделиться

5 ответов

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

я думаю в.NET, что необходимо создать Metafile объект, создать Graphics объект с помощью Graphics.FromImage, затем выполнить шаги рисунка. Файл автоматически обновляется, поскольку Вы привлекаете его. Можно найти небольшую выборку в документации для Графика. AddMetafileComment.

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

3
ответ дан 30 November 2019 в 06:51
поделиться

Если я правильно помню, он может быть сделано с помощью комбинации Metafile.GetHenhmetafile (), API GetEnhMetaFileBits () и Stream.Write (), что-то вроде

[DllImport("gdi32")] static extern uint GetEnhMetaFileBits(IntPtr hemf, uint cbBuffer, byte[] lpbBuffer);


IntPtr h = metafile.GetHenhMetafile();
int size = GetEnhMetaFileBits(h, 0, null);
byte[] data = new byte[size];
GetEnhMetaFileBits(h, size, data);
using (FileStream w = File.Create("out.emf")) {
    w.Write(data, 0, size);
}
// TODO: I don't remember whether the handle needs to be closed, but I guess not.

. Я думаю, что именно так я решил проблему, когда у меня это было.

12
ответ дан 30 November 2019 в 06:51
поделиться

Вопрос был: "Есть ли другой способ сохранить образ к EMF/WMF?" Не, "что такое метафайл" или, "как создать метафайл" или, "как использовать метафайл с Графикой".

Я также ищу ответ для этого вопроса, "как сохранить EMF/WMF" На самом деле, если Вы используете:

  Graphics grfx = CreateGraphics();
  MemoryStream ms = new MemoryStream();
  IntPtr ipHdc = grfx.GetHdc();

  Metafile mf = new Metafile(ms, ipHdc);

  grfx.ReleaseHdc(ipHdc);
  grfx.Dispose();
  grfx = Graphics.FromImage(mf);

  grfx.FillEllipse(Brushes.Gray, 0, 0, 100, 100);
  grfx.DrawEllipse(Pens.Black, 0, 0, 100, 100);
  grfx.DrawArc(new Pen(Color.Red, 10), 20, 20, 60, 60, 30, 120);
  grfx.Dispose();

  mf.Save(@"C:\file.emf", ImageFormat.Emf);
  mf.Save(@"C:\file.png", ImageFormat.Png);

В обоих случаях образ сохраняется как формат png. И это - проблема, которая я не могу решить:/

3
ответ дан 30 November 2019 в 06:51
поделиться

Ответ Эриккаллена правильный. Я пробовал это из VB.NET, и мне пришлось использовать 2 разных DllImports, чтобы заставить его работать:

<System.Runtime.InteropServices.DllImportAttribute("gdi32.dll", EntryPoint:="GetEnhMetaFileBits")> _
    Public Shared Function GetEnhMetaFileBits(<System.Runtime.InteropServices.InAttribute()> ByVal hEMF As System.IntPtr, ByVal nSize As UInteger, ByVal lpData As IntPtr) As UInteger
End Function

    <System.Runtime.InteropServices.DllImportAttribute("gdi32.dll", EntryPoint:="GetEnhMetaFileBits")> _
    Public Shared Function GetEnhMetaFileBits(<System.Runtime.InteropServices.InAttribute()> ByVal hEMF As System.IntPtr, ByVal nSize As UInteger, ByVal lpData() As Byte) As UInteger
End Function

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

Dim h As IntPtr = mf.GetHenhmetafile()
CopyEnhMetaFileW(h, FileName)

Это копирует биты ЭДС непосредственно в указанный файл.

2
ответ дан 30 November 2019 в 06:51
поделиться

Изображение - это абстрактный класс: то, что вы хотите do зависит от того, имеете ли вы дело с метафайлом или растровым изображением .

Создать изображение с помощью GDI + и сохранить его как EMF просто с помощью метафайла .

21
ответ дан 30 November 2019 в 06:51
поделиться
Другие вопросы по тегам:

Похожие вопросы: