En realidad el truco ya lo he publicado como contestación a este hilo, pero aprovecho para recopilarlo en esta sección de trucos y para escribirlo también en en C.
Esta función es capaz de leer y convertir a BITMAP una página de un archivo gráfico multipágina. Una ventaja añadida es que puede extraer el Bitmap de un archivo gráfico aunque no sea multipágina, extraerá el primero que pueda. En caso de ser multipágina y nos pesemos de rango, la función lo ajusta con el resto de la división, de forma que siempre devuelve un Bitmap.
Como ya hice otras veces usaré GDI+ Flat API
Esta es la versión C:
#pragma link "gdiplus.lib" extern "C"{ DWORD __stdcall GdiplusStartup(ULONG_PTR *hToken, void *input, void *Output); void __stdcall GdiplusShutdown(ULONG_PTR token); DWORD __stdcall GdipCreateBitmapFromFile(WCHAR* filename, HANDLE* bitmap); DWORD __stdcall GdipCreateHBITMAPFromBitmap(HANDLE bitmap, HBITMAP* hBitmap, DWORD BKColor); DWORD __stdcall GdipImageGetFrameDimensionsList(HANDLE image, PGUID dimensionIDs, UINT count); DWORD __stdcall GdipImageGetFrameCount(HANDLE image, PGUID dimensionIDs, UINT *count); DWORD __stdcall GdipImageSelectActiveFrame(HANDLE image, PGUID dimensionIDs, UINT frameIndex); } HBITMAP CreateHBITMAPFromFilePage(PCHAR cFileName, UINT Index) { // Pasamos a Unicode WCHAR *FileName = new WCHAR[strlen(cFileName)+1]; int size = strlen(cFileName)*sizeof(WCHAR)+1; MultiByteToWideChar(CP_ACP, 0, cFileName, -1, FileName, size); // Inicializamos GDI+. HBITMAP hBitmap = 0; ULONG_PTR gdiplusToken; char GdiPlusStartupInput[16] = {1,0}; if(!GdiplusStartup(&gdiplusToken, GdiPlusStartupInput, NULL)){ HANDLE GBitmap = 0; GUID dimensionID; UINT Frames; GdipCreateBitmapFromFile(FileName, &GBitmap); GdipImageGetFrameDimensionsList(GBitmap, &dimensionID, 1); GdipImageGetFrameCount(GBitmap, &dimensionID, &Frames); GdipImageSelectActiveFrame(GBitmap, &dimensionID, Index % Frames); GdipCreateHBITMAPFromBitmap(GBitmap, &hBitmap, 0); // Cerramos GDI+ GdiplusShutdown(gdiplusToken); } delete FileName; return hBitmap; }
Unos ejemplos de uso:
Image1->Picture->Bitmap->Handle = CreateHBITMAPFromFilePage("Fax1.TIF", 4); Image1->Picture->Bitmap->Handle = CreateHBITMAPFromFilePage("Otro.gif", 6);
Y la versión delphi:
type function GdiplusStartup(var GdiToken: DWORD; Startup, Output: PBYTE): DWORD; stdcall external 'gdiplus'; function GdipCreateBitmapFromFile(lpFileName: PWCHAR; var GBitmap: THANDLE): DWORD; stdcall external 'gdiplus'; function GdipCreateHBITMAPFromBitmap(GBitmap: THANDLE; var hBitmap: HBITMAP; BKColor: DWORD): DWORD; stdcall external 'gdiplus'; procedure GdiplusShutdown(GdiToken: DWORD); stdcall external 'gdiplus'; function GdipImageGetFrameDimensionsList(image: THANDLE; var dimensionIDs: TGUID; count: DWORD): DWORD; stdcall external 'gdiplus'; function GdipImageGetFrameCount(image: THANDLE; var dimensionID: TGUID; var count: DWORD): DWORD; stdcall external 'gdiplus'; function GdipImageSelectActiveFrame(image: THANDLE; var dimensionID: TGUID; frameIndex: DWORD): DWORD; stdcall external 'gdiplus'; implementation function CreateHBITMAPFromFilePage(cFileName: PCHAR; Index: DWORD): HBITMAP; var FileName: array of WCHAR; size: integer; gdiplusToken: DWORD; GdiPlusStartupInput: array[0..2] of int64; GBitmap: THANDLE; DimensionID: TGUID; Frames: DWORD; begin Result:= 0; // Pasamos a Unicode SetLength(FileName, lstrlen(cFileName)+1); size:= lstrlen(cFileName)*sizeof(WCHAR)+1; MultiByteToWideChar(CP_ACP, 0, cFileName, -1, @FileName[0], size); // Inicializamos GDI+. GdiPlusStartupInput[0]:= 1; GdiPlusStartupInput[1]:= 0; if GdiplusStartup(gdiplusToken, @GdiPlusStartupInput, nil) = 0 then begin GdipCreateBitmapFromFile(PWCHAR(FileName), GBitmap); GdipImageGetFrameDimensionsList(GBitmap, dimensionID, 1); GdipImageGetFrameCount(GBitmap, dimensionID, Frames); GdipImageSelectActiveFrame(GBitmap, dimensionID, Index mod Frames); GdipCreateHBITMAPFromBitmap(GBitmap, Result, 0); // Cerramos GDI+ GdiplusShutdown(gdiplusToken); end; end;
Ejemplo de uso:
Image1.Picture.Bitmap.Handle:= CreateHBITMAPFromFilePage('Fax1.TIF', 4); Image1.Picture.Bitmap.Handle:= CreateHBITMAPFromFilePage('Otro.gif', 2);
Saludos.