Конвертируйте файл wmf в файл emf с помощью SetWinMetaFileBits api в c ++ - PullRequest
0 голосов
/ 30 сентября 2019

Я пытаюсь преобразовать файл wmf в файл emf. Из того, что я узнал в Интернете, лучшее решение выглядит следующим образом.

BYTE* buffer;

HDC hdc = CreateMetaFileA(filename);

HMETAFILE hmf = CloseMetaFile(hdc);

UINT metasize = GetMetaFileBitsEx(hmf, 0, NULL);

buffer = (BYTE*)malloc(metasize);

HENHMETAFILE hEMF = SetWinMetaFileBits(metasize, buffer, NULL, NULL);

Идея в том, чтобы использовать CreateMetaFileA и CloseMetaFile для получения HMETAFILE hmf. Затем я попробовал свой код, и пришла странная вещь. Ручка хмф всегда указывает ??? в памяти и метасиле всегда 24 с разными картинками. И hEMF - это всегда None.

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

Я читаю много материалов, включая

http://math2.org/luasearch-2/luadist-extract/cdlua-5.2.dist/src/win32/wmf_emf.c https://www -user.tu-chemnitz.de / ~ heha / viewzip.cgi / hs /wmfsave.zip/src/wmfsave.cpp?auto=CPP

Кто-нибудь может мне здесь помочь? Спасибо.

1 Ответ

0 голосов
/ 01 октября 2019

Вам нужно инициализировать структуру METAFILEPICT .

Минимальный пример:

if (hmf) {
            DWORD nSize = GetMetaFileBitsEx( hmf, 0, NULL );
            if (nSize) {
                BYTE *lpvData = new BYTE[nSize];
                if (lpvData) {
                    DWORD dw = GetMetaFileBitsEx( hmf, nSize, lpvData );
                    if (dw) {
                        // Fill out a METAFILEPICT structure
                        mp.mm = MM_ANISOTROPIC;
                        mp.xExt = 1000;
                        mp.yExt = 1000;
                        mp.hMF = NULL;
                        // Get a reference DC
                        hDC = GetDC( NULL );
                        // Make an enhanced metafile from the windows metafile
                        hemf = SetWinMetaFileBits( nSize, lpvData, hDC, &mp );
                        // Clean up
                        ReleaseDC( NULL, hDC );
                    }
                    delete[] lpvData;
                }
                DeleteMetaFile( hmf );
            }     

Мой тестовый код:

    hdcMeta = CreateMetaFile(NULL);
    hBrush = CreateSolidBrush(RGB(0, 0, 255));

    Rectangle(hdcMeta, 0, 0, 100, 100);

    MoveToEx(hdcMeta, 0, 0, NULL);
    LineTo(hdcMeta, 100, 100);
    MoveToEx(hdcMeta, 0, 100, NULL);
    LineTo(hdcMeta, 100, 0);

    SelectObject(hdcMeta, hBrush);
    Ellipse(hdcMeta, 20, 20, 80, 80);

    hmf = CloseMetaFile(hdcMeta);
    UINT nSize = GetMetaFileBitsEx(hmf, 0, NULL);

Отладка:

1

Вы можете увидеть nSize = 114

Я подозреваю, что вы используете CreateMetaFileA и CloseMetaFile для прямой загрузки файлаНазывать и возвращать дескриптор метафайла в формате Windows - неверный способ.

Вы можете использовать другой способ преобразования:

EmfWin32::open( Inkscape::Extension::Input *mod, const gchar *uri )
{
    EMF_CALLBACK_DATA d = {0};

    gsize bytesRead = 0;
    gsize bytesWritten = 0;
    GError* error = NULL;
    gchar *local_fn =
        g_filename_from_utf8( uri, -1,  &bytesRead,  &bytesWritten, &error );

    if (local_fn == NULL) {
        return NULL;
    }

    d.outsvg = new Glib::ustring("");
    d.path = new Glib::ustring("");

    CHAR *ansi_uri = (CHAR *) local_fn;
    gunichar2 *unicode_fn = g_utf8_to_utf16( local_fn, -1, NULL, NULL, NULL );
    WCHAR *unicode_uri = (WCHAR *) unicode_fn;

    // Try open as Enhanced Metafile
    HENHMETAFILE hemf;
    if (PrintWin32::is_os_wide())
        hemf = GetEnhMetaFileW(unicode_uri);
    else
        hemf = GetEnhMetaFileA(ansi_uri);


    METAFILEPICT mp;
    HDC hDC;

    if (hmf) {
       DWORD nSize = GetMetaFileBitsEx( hmf, 0, NULL );
       if (nSize) {
           BYTE *lpvData = new BYTE[nSize];
           if (lpvData) {
              DWORD dw = GetMetaFileBitsEx( hmf, nSize, lpvData );
              if (dw) {
              // Fill out a METAFILEPICT structure
                 mp.mm = MM_ANISOTROPIC;
                 mp.xExt = 1000;
                 mp.yExt = 1000;
                 mp.hMF = NULL;
                 // Get a reference DC
                 hDC = GetDC( NULL );
                 // Make an enhanced metafile from the windows metafile
                 hemf = SetWinMetaFileBits( nSize, lpvData, hDC, &mp );
                 // Clean up
                 ReleaseDC( NULL, hDC );
              }
            delete[] lpvData;
          }
     DeleteMetaFile( hmf );
   }
}

Для получения более подробной информации, пожалуйста, обратитесь к Эта ссылка.

...