2010-10-25 6 views
0

J'ai cherché à utiliser google mais je suis complètement confus sur la façon de charger une image (PNG dans mon cas) depuis la ressource puis de la convertir en bitmap en mémoire pour une utilisation dans mon écran de démarrage. J'ai lu sur GDI + et libpng mais je ne sais pas vraiment comment faire ce que je veux. Quelqu'un pourrait-il aider?Chargement d'une image de la ressource et conversion en bitmap en mémoire

+0

Si vous pouvez utiliser JPEG à la place alors OleLoadPicture & friends devrait faire l'affaire. –

+0

Mais je ne pense pas qu'il existe un moyen de stocker un fichier JPEG sans compression ... Et je dois garder le canal alpha –

Répondre

0

J'ai fini par utiliser PicoPNG pour convertir le PNG en un vecteur bidimensionnel dont j'ai ensuite manuellement créé un bitmap. Mon code final ressemblait à ceci:

HBITMAP LoadPNGasBMP(const HMODULE hModule, const LPCTSTR lpPNGName) 
{ 
    /* First we need to get an pointer to the PNG */ 
    HRSRC found = FindResource(hModule, lpPNGName, "PNG"); 
    unsigned int size = SizeofResource(hModule, found); 
    HGLOBAL loaded = LoadResource(hModule, found); 
    void* resource_data = LockResource(loaded); 

    /* Now we decode the PNG */ 
    vector<unsigned char> raw; 
    unsigned long width, height; 
    int err = decodePNG(raw, width, height, (const unsigned char*)resource_data, size); 
    if (err != 0) 
    { 
     log_debug("Error while decoding png splash: %d", err); 
     return NULL; 
    } 

    /* Create the bitmap */ 
    BITMAPV5HEADER bmpheader = {0}; 
    bmpheader.bV5Size = sizeof(BITMAPV5HEADER); 
    bmpheader.bV5Width = width; 
    bmpheader.bV5Height = height; 
    bmpheader.bV5Planes = 1; 
    bmpheader.bV5BitCount = 32; 
    bmpheader.bV5Compression = BI_BITFIELDS; 
    bmpheader.bV5SizeImage = width*height*4; 
    bmpheader.bV5RedMask = 0x00FF0000; 
    bmpheader.bV5GreenMask = 0x0000FF00; 
    bmpheader.bV5BlueMask = 0x000000FF; 
    bmpheader.bV5AlphaMask = 0xFF000000; 
    bmpheader.bV5CSType = LCS_WINDOWS_COLOR_SPACE; 
    bmpheader.bV5Intent = LCS_GM_BUSINESS; 
    void* converted = NULL; 
    HDC screen = GetDC(NULL); 
    HBITMAP result = CreateDIBSection(screen, reinterpret_cast<BITMAPINFO*>(&bmpheader), DIB_RGB_COLORS, &converted, NULL, 0); 
    ReleaseDC(NULL, screen); 

    /* Copy the decoded image into the bitmap in the correct order */ 
    for (unsigned int y1 = height - 1, y2 = 0; y2 < height; y1--, y2++) 
     for (unsigned int x = 0; x < width; x++) 
     { 
      *((char*)converted+0+4*x+4*width*y2) = raw[2+4*x+4*width*y1]; // Blue 
      *((char*)converted+1+4*x+4*width*y2) = raw[1+4*x+4*width*y1]; // Green 
      *((char*)converted+2+4*x+4*width*y2) = raw[0+4*x+4*width*y1]; // Red 
      *((char*)converted+3+4*x+4*width*y2) = raw[3+4*x+4*width*y1]; // Alpha 
     } 

    /* Done! */ 
    return result; 
} 
1

GDI + prend directement en charge le format PNG. Voir here et here.

EDIT: Le GDI+ documentation offre des conseils sur l'utilisation de GDI + dans une DLL. Dans votre cas, la meilleure solution est probablement de définir les fonctions d'initialisation et de démontage que le code client doit appeler.

+0

Okay. Il semble que je ne peux pas utiliser GDI + pour ce que je fais, puisque tout cela est fait dans DllMain et les fonctions appelées par lui. Avez-vous d'autres suggestions? –

+0

Je l'aurais fait (je l'ai lu) si j'avais pu éditer le programme appelant la DLL, mais je ne peux pas. Donc je ne pense pas vraiment pouvoir utiliser GDI +. Je suis actuellement en train d'étudier l'utilisation de WIC pour convertir mon PNG en HBITMAP –

Questions connexes