2011-03-17 11 views
11

El método GDI + Image::Save requiere un parámetro CLSID para especificar el codificador que se utilizará. La documentación apunta a some sample code para obtener el codificador asociado a un tipo MIME particular, como image/jpeg o image/png. Sin embargo, me estoy negando con la idea de copiar una función de media página solo para admitir una ayuda de depuración de 1 línea donde guardo un resultado intermedio en el disco.¿Tiene GDI + codificadores de imagen estándar CLSID?

¿No debería haber una lista de CLSID estándar para los codificadores estándar? ¿Dónde encontraría tal lista? No he podido encontrar uno buscando en los archivos de inclusión de Microsoft.

Respuesta

5

No hay una sola. Creo que tenían la intención de que la lista de códecs fuera extensible y soportara complementos, pero nunca llegó a hacerlo. Dado que no han realizado ningún cambio en GDI + en bastante tiempo, es probable que no lo hagan pronto. Probablemente pueda salirse con la suya generando su propia lista codificada en base a una enumeración de Gdiplus :: GetImageEncoders.

Eso es:

image/bmp : {557cf400-1a04-11d3-9a73-0000f81ef32e} 
image/jpeg : {557cf401-1a04-11d3-9a73-0000f81ef32e} 
image/gif : {557cf402-1a04-11d3-9a73-0000f81ef32e} 
image/tiff : {557cf405-1a04-11d3-9a73-0000f81ef32e} 
image/png : {557cf406-1a04-11d3-9a73-0000f81ef32e} 

Aquí es la función que rutinariamente cortar & pasta entre los proyectos para conseguir en el CLSID del codificador. Podrías modificarlo para que sea una tabla de búsqueda.

HRESULT GetGdiplusEncoderClsid(__in LPCWSTR pwszFormat, __out GUID *pGUID) 
{ 
    HRESULT hr = E_FAIL; 
    UINT nEncoders = 0;   // number of image encoders 
    UINT nSize = 0;    // size of the image encoder array in bytes 
    CAutoVectorPtr<BYTE> spData; 
    Gdiplus::ImageCodecInfo* pImageCodecInfo = NULL; 
    Gdiplus::Status status; 
    bool fFound = false; 

    // param check 

    if ((pwszFormat == NULL) || (pwszFormat[0] == 0) || (pGUID == NULL)) 
    { 
     return E_POINTER; 
    } 

    *pGUID = GUID_NULL; 

    status = Gdiplus::GetImageEncodersSize(&nEncoders, &nSize); 

    if ((status != Gdiplus::Ok) || (nSize == 0)) 
    { 
     return E_FAIL; 
    } 


    spData.Allocate(nSize); 

    if (spData == NULL) 
    { 
     return E_FAIL; 
    } 

    pImageCodecInfo = (Gdiplus::ImageCodecInfo*)(BYTE*)spData; 

    status = Gdiplus::GetImageEncoders(nEncoders, nSize, pImageCodecInfo); 

    if (status != Gdiplus::Ok) 
    { 
     return E_FAIL; 
    } 

    for(UINT j = 0; j < nEncoders; ++j) 
    { 
     if(wcscmp(pImageCodecInfo[j].MimeType, pwszFormat) == 0) 
     { 
      *pGUID = pImageCodecInfo[j].Clsid; 
      fFound = true; 
      break; 
     }  
    } 

    hr = fFound ? S_OK : E_FAIL; 

    return hr; 
} 
2

Probablemente querrá usar ImageCodecInfo con GetImageEncodersSize() y GetImageEncoders() No conozco ninguna manera más fácil.

EDIT: Si sabe específicamente lo que quiere y maldito todo el resto que puede salirse con hacer algo como esto ...

CLSID pngClsid; 
GetEncoderClsid("image/png", &pngClsid); 
image.Save("imagename.png", &pngClsid, NULL); 
+2

eso es exactamente lo que he intentado hacer, pero 'GetEncoderClsid' no es parte de GDI + - tienes que copiarlo de la documentación. –

+0

Ah, tienes razón ... wow, ¿supones que fue un descuido? – AJG85

2

Si lo que desea es escribir un archivo PNG, esto parece funcionar:

// image/png : {557cf406-1a04-11d3-9a73-0000f81ef32e} 
const CLSID pngEncoderClsId = { 0x557cf406, 0x1a04, 0x11d3,{ 0x9a,0x73,0x00,0x00,0xf8,0x1e,0xf3,0x2e } }; 
stat = image->Save(L"test.png", &pngEncoderClsId, NULL); 

Nota el cambio de formato de los valores hex.

Desde: How to initialize a constant CLSID

Cuestiones relacionadas