Artículo original: Convert BMP to ICON - Part 1
http://weblogs.foxite.com/vfpimaging/archive/2007/07/13/4346.aspx
Autor: Cesar Ch.
Traducido por: Luis María Guayán
Se sabe que GDI+ no trae soporte total para los archivos de iconos. Por lo tanto, no podemos hacer ninguna conversión sencilla para crear archivos .ICO directamente.
Pero hay algunos trucos fáciles que podemos utilizar para hacer esto. El primer paso es tomar el handle del icono de nuestro BITMAP, el "hIcon".
El planteamiento más sencillo es utilizar la API OleCreatePictureIndirect para obtener una referencia al objeto OLE de la imagen. El paso siguiente es enviar este objeto a la función SAVEPICTURE() para guardarla en el disco.
Pero el problema de esta técnica es que los iconos están generados en una mala calidad, 4bpp (4 bits por pixel). Esto significa que los iconos pueden tener como máximo 2^4 = 16 colores, esto trae resultados realmente feos y de mala calidad.
Abajo está el código:
IMPORTANTE
Requiere VFP9 y GdiPlusX para funcionar.
¡Por favor asegúrese que tiene la última versión!
http://www.codeplex.com/VFPX/Wiki/View.aspx?title=GDIPlusX&referringTitle=Home
* API Declarations DECLARE SHORT DestroyIcon IN user32 INTEGER hIcon DECLARE LONG OleCreatePictureIndirect IN oleaut32 ; STRING @PictDesc , STRING @riid , LONG Own , OBJECT @Obj * Initialize GdiPlusX _SCREEN.AddProperty("System", NEWOBJECT("xfcSystem", LOCFILE("system.vcx"))) LOCAL lcPict, lcIconFile lcPict = GETPICT("bmp") lcIconFile = "c:\" + JUSTSTEM(lcPict) + ".ico" WITH _SCREEN.System.Drawing LOCAL lhIcon LOCAL loBmp as xfcBitmap loBmp = .Bitmap.FromFile(lcPict) lhIcon = loBmp.GetHicon() ENDWITH IF lhIcon # 0 *!* typedef struct tagPICTDESC *!* { *!* UINT cbSizeofstruct; *!* UINT picType; *!* HICON hicon; *!* } icon; *!* struct *!* { *!* HENHMETAFILE hemf; *!* } emf; *!* } ; *!* } PICTDESC; #DEFINE PICTYPE_ICON 3 #DEFINE GUID_Icon2 0h0004020000000000C000000000000046 && "{00020400-0000-0000-C000-000000000046}" #DEFINE GUID_Icon 0h8109F87B32BF1A108BBB00AA00300CAB && "{7BF80981-BF32-101A-8BBB-00AA00300CAB}" LOCAL lcPictDesc, lqGuid, loIconObj lcPictDesc = BINTOC(16,"4RS") + ; && Size of Structure BINTOC(PICTYPE_ICON, "4RS") + ; && Type of Image BINTOC(lhIcon, "4RS") + ; && Image Handle BINTOC(0, "4RS") lqGuid = GUID_Icon loIconObj = 0 *!* http://msdn2.microsoft.com/en-us/library/ms694511.aspx *!* STDAPI OleCreatePictureIndirect( *!* PICTDESC* pPictDesc, //Pointer to the structure of parameters for picture *!* REFIID riid, //Reference to the identifier of the interface *!* BOOL fOwn, //Whether the picture is to be destroyed *!* If TRUE, the picture object is to destroy its picture when the object is destroyed. *!* If FALSE, the caller is responsible for destroying the picture. *!* VOID** ppvObj //Address of output variable that receives the *!* // interface pointer requested in riid *!* ); * Create the picture OLE object OleCreatePictureIndirect(@lcPictDesc, @lqGuid, 1, @loIconObj) IF VARTYPE(loIconObj) = 'O' * Save the picture using VFP native function 'savepicture()' IF SAVEPICTURE(loIconObj, lcIconFile) MESSAGEBOX('Icon created successfully !', 64) ENDIF ELSE MESSAGEBOX('OleCreatePictureIndirect() Error', 16) ENDIF * Free the memory handle allocated for the hIcon = DestroyIcon(lhIcon) ENDIF RETURN
Imagen original .BMP | Imagen .ICO (16 colores) |
Puedes intentarlo sin ejecutar este código: Abrir MsPaint, y cargar una de las cuatro imágenes a la izquierda. Luego, seleccionar guardar la imagen como un bitmap de 16 colores, y obtendrás exactamente el mismo resultado que generó OLECreatePictureIndirect. Esta utilizará solamente la paleta de colores de abajo para convertir la imagen.
De manera, como el resultado no es tan bueno como deseamos, ¿por qué puse este códigos aquí?
Esto está porque la libreria original del .NET "System.Drawing" utiliza un planteamiento similar como el mostrado arriba, para crear iconos en el método Icon.Save().
En el siguiente artículo mostraré cómo podemos convertir nuestros BitMaps a iconos de alta calidad, pero utilizando algunas buenas y viejas técnicas de GDI (no Gdi+). ¡El código no será sencillo ni corto como el mostrado aquí, pero el funcionamiento será similar y la calidad será perfecta!
Hola Luis cual es el método para guardar los iconos con una mejor calidad
ResponderBorrar