http://weblogs.foxite.com/vfpimaging/archive/2007/05/28/3862.aspx
Autor: Cesar Ch.
Traducido por: Ana María Bisbé York
Una de las preguntas más comunes que he visto en los foros de VFP relacionadas con imágenes es "¿Cómo puedo obtener las dimensiones de un archivo de imagen?"
Afortunadamente, esto es muy fácil de obtener.
A continuación muestro varias técnicas que podemos utilizar, con una breve explicación. cada desarrollador puede escoger cuál de ellas es mejor para sus necesidades. Todas las técnicas son muy sencillas de utilizar. Para usuarios GDI+, lo muestro empleando 3 bibliotecas con las que ya he trabajado. Como bono, la última muestra cómo obtenerlo con GDI+ utilizando llamadas directas a API, para los que no quieren utilizar una clase envoltorio GDI+.
Todos los ejemplos a continuación son libres. Estoy seguro de que hay otras formas de hacerlo. Señalo solamente aquellas que conozco y he probado.
1.- Cargar la imagen en un objeto Image VFP
Esta técnica trabaja con cualquier versión VFP. Cuando asociamos un archivo a la propiedad PicturuFile de un objeto Image, va a guardar las dimensiones en las propiedades Width y Height.
* Técnica 1 * Obtener las dimensiones del objeto Image LOCAL lcPictureFile lcPictureFile = GETPICT() LOCAL lnWidth, lnHeight LOCAL loVFPImg as Image loVFPImg = CREATEOBJECT("Image") loVFPImg.Picture = lcPictureFile lnWidth = loVFPImg.Width lnHeight = loVFPImg.Height loVFPImg = NULL MESSAGEBOX("Objeto Image VFP " + CHR(13) + ; "Dimensiones: " + TRANSFORM(lnWIdth) + " x " + TRANSFORM(lnHeight))
2.- Utilizar la función LOADPICTURE()
El objeto devuelto por LOADPICTURE() es una instancia de la clase StdPicture. Los valores de altura y ancho son unidades HiMetric (1 HiMetric = 0.01 milímetro).
No estoy realmente seguro de cuál es la forma correcta para utilizar esta función para obtener las dimensiones de una imagen.
Lisa Slater Nicholls publicó hace mucho tiempo una función para obtener las dimensiones; pero a mí no me ha funcionado: http://www.spacefold.com/lisa/lisa_fx4.htm#loadpicture
En una discusión en Foxite, entre Eric den Doop y Boudewijn Lutgerik: http://www.foxite.com/archives/what-mysterious-calculation-is-behind-this-0000067503.htm, Boudewijn obtuvo las dimensiones utilizando un factor diferente.
En mi caso, escogí la técnica que encontré en http://www.xtremevbtalk.com/archive/index.php/t-13097.html
¡ Pero no confío en este proceder porque parece que depende de la resolución de la pantalla !
* Técnica 2 * Obtener las dimensiones del objeto Imagen utilizando la función LOADPICT() * Código de Lisa Slater Nicholls * El objeto devuelto por LOADPIC() es una instancia de la clase StdPicture. * Los valores de altura y ancho son unidades HiMetric (1 HiMetric = 0.01 milímetro). * http://www.foxite.com/archives/what-mysterious-calculation-is-behind-this-0000067503.htm * http://www.xtremevbtalk.com/archive/index.php/t-13097.html LOCAL lcPictureFile lcPictureFile = GETPICT() LOCAL lnWidth, lnHeight LOCAL loLoadedPict loLoadedPict = LOADPICTURE(lcPictureFile) lnHeight = ROUND((loLoadedPict.Height / 26.45454545455),0) lnWidth = ROUND((loLoadedPict.Width / 26.45454545455),0) loLoadedPict = NULL MESSAGEBOX("Función VFP LOADPICTURE()" + CHR(13) + ; "Dimensiones: " + TRANSFORM(lnWidth) + " x " + TRANSFORM(lnHeight))
3.- Obtener la información de la cabecera del archivo imagen
Las dimensiones de la imagen se almacenan en sus binarios. El siguiente código utiliza FOPEN y FREAD para extraer esa información. Puede obtener las dimensiones para las imágenes tipo BMP, GIF y JPG.
* Técnica 3 * Obtener la información de la cabecera del archivo imagen * Los ejemplos se han adaptado a partir de las funciones de Thomas Gehrke en West-Wind Wiki: * http://www.west-wind.com/wiki/wc.dll?wc~JpgSizeFunction * http://www.west-wind.com/wiki/wc.dll?wc~GifSizeFunction LOCAL lcPictureFile lcPictureFile = GETPICT() LOCAL lnWidth, lnHeight, lcExt lcExt = LOWER(JUSTEXT(lcPictureFile)) DO CASE CASE lcExt = "bmp" LOCAL lnHandle, lcBytes lnHandle = FOPEN(lcPictureFile) IF m.lnHandle > -1 * Leer los primeros 27 bytes: lcBytes = FREAD( m.lnHandle, 27) = FCLOSE( m.lnHandle) lnWidth = CTOBIN(SUBSTR(lcBytes,19,4),"4RS") lnHeight = CTOBIN(SUBSTR(lcBytes,23,4),"4RS") ENDIF CASE lcExt = "gif" LOCAL lnHandle, lcBytes lnHandle = FOPEN(lcPictureFile) IF m.lnHandle > -1 * Leer los primeros 10 bytes: lcBytes = FREAD( m.lnHandle, 10) = FCLOSE( m.lnHandle) lnWidth = CTOBIN(SUBSTR( m.lcBytes, 7, 2),"2RS") lnHeight = CTOBIN(SUBSTR( m.lcBytes, 9, 2),"2RS") ENDIF CASE lcExt = "jpg" LOCAL lnHandle, lcBytes lnHandle = FOPEN(lcPictureFile) IF m.lnHandle > -1 LOCAL lnFileSize, lnCounter, lcBytes lnFileSize = FSEEK( m.lnHandle, 0, 2) lnCounter = 0 = FSEEK( m.lnHandle, 0, 0) FOR lnCounter = 1 TO m.lnFileSize - 2 lcBytes = FREAD( m.lnHandle, 3) IF m.lcBytes = CHR(0) + CHR(17) + CHR(8) OR ; m.lcBytes = CHR(0) + CHR(11) + CHR(8) * ¡Encontrar las marcas de bloque para las dimensiones! lcBytes = FREAD( m.lnHandle, 4) EXIT ELSE = FSEEK( m.lnHandle, -2, 1) ENDIF ENDFOR = FCLOSE( m.lnHandle) lnWidth = CTOBIN(SUBSTR( m.lcBytes, 3, 2),"2S") lnHeight = CTOBIN(SUBSTR( m.lcBytes, 1, 2),"2S") ENDIF ENDCASE MESSAGEBOX("Información desde la cabecera de imagen" + CHR(13) + ; "Dimensiones: " + TRANSFORM(lnWIdth) + " x " + TRANSFORM(lnHeight))
4.- Utilizar GDIPlusX
GDI+ puede brindar esta información y muchas otras, fácilmente.
El ejemplo que muestro a continuación utiliza la biblioteca GdiPlusX de VFPX.
http://www.codeplex.com/VFPX/Wiki/View.aspx?title=GDIPlusX&referringTitle=Home
* Técnica 4 * Obtener la información de la imagen utilizando GDI+, con GdiPlusX * http://www.codeplex.com/VFPX/Wiki/View.aspx?title=GDIPlusX&referringTitle=Home LOCAL lcPictureFile lcPictureFile = GETPICT() LOCAL lnWidth, lnHeight _SCREEN.AddProperty("System", NEWOBJECT("xfcSystem", LOCFILE("system.vcx","vcx"))) WITH _SCREEN.System.Drawing * Crear un Bitmap nuevo LOCAL loBmp as xfcBitmap loBmp = .Bitmap.FromFile(lcPictureFile) lnWidth = loBmp.Width lnHeight = loBmp.Height loBmp = NULL MESSAGEBOX("Biblioteca GDI+ - GdiPlusX" + CHR(13) + ; "Dimensiones: " + TRANSFORM(lnWIdth) + " x " + TRANSFORM(lnHeight)) ENDWITH
5.- Utilizar GPIMAGE2
El ejemplo que se muestra a continuación utiliza la biblioteca GpImage de Alexander Golovlev. En el siguiente enlace puede encontrar la versión más reciente para esta clase que contiene algunas funciones Graphics, que he agregado: http://cchalom.sites.uol.com.br/GPIMAGE
* Técnica 5 * Obtener la información de la imagen utilizando GDI+, con GpImage2 * http://cchalom.sites.uol.com.br/GPIMAGE LOCAL lcPictureFile lcPictureFile = GETPICT() LOCAL lnWidth, lnHeight IF Not "gpImage" $ SET("Procedure") SET PROCEDURE TO gpImage ADDITIVE ENDIF loGdip = CREATEOBJECT("gpInit") loBmp = CREATEOBJECT("gpImage") loBmp.Load(lcPictureFile) lnWidth = loBmp.ImageWidth lnHeight = loBmp.ImageHeight loBmp = NULL loGdip = NULL MESSAGEBOX("GDI+ library - GpImage2" + CHR(13) + ; "Dimensiones: " + TRANSFORM(lnWIdth) + " x " + TRANSFORM(lnHeight))
6.- Utilizar _GDIPLUS.VCX
El siguiente ejemplo utiliza la biblioteca de clases Foundations (FCC) _GdiPlus.vcx de Walter Nicholls, liberada con VFP9.
* Técnica 6 * Obtener la información de la imagen utilizando GDI+, con _GdiPlus.vcx, de Walter Nicholls LOCAL lcPictureFile lcPictureFile = GETPICT() LOCAL lnWidth, lnHeight LOCAL loBitmap as GpBitmap OF HOME() + "/FFC/_GdiPlus.vcx" loBitmap = NEWOBJECT("GpBitmap", HOME() + "/FFC/_GdiPlus.vcx") loBitmap.CreateFromFile(lcPictureFile) lnWidth = loBitmap.ImageWidth lnHeight = loBitmap.ImageHeight loBitmap = NULL MESSAGEBOX("Biblioteca GDI+ - FFC _GdiPlus.vcx" + CHR(13) + ; "Dimensiones: " + TRANSFORM(lnWIdth) + " x " + TRANSFORM(lnHeight))
7.- Utilizar GDIPLUS con llamadas directas a API
Si no desea utilizar ninguna clase envoltorio GDI+, he aquí un código que obtiene las dimensiones de la imagen utilizando llamadas directas de API a gdiplus.dll. Asegúrese de tener gdiplus.dll en su sistema.
Gdiplus.dll está disponible gratis y se puede instalar con Win98 y superior. Si no tiene instalado WinXP or .NET runtime entonces debe bajar esta DLL desde http://www.microsoft.com/downloads/details.aspx?FamilyID=6a63ab9c-df12-4d41-933c-be590feaa05a&DisplayLang=en o directamente desde http://download.microsoft.com/download/platformsdk/redist/3097/W98NT42KMeXP/EN-US/gdiplus_dnld.exe
Puede obtener información valiosa sobre GDIPlus en el sitio oficial de Microsoft
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/gdicpp/GDIPlus/GDIPlusreference/flatgraphics.asp
* Técnica 7 * Obtener información de la imagen utilizando GDI+, con lamadas directas de API LOCAL lcPictureFile lcPictureFile = GETPICT() * API Declarations for GDI+ DECLARE LONG GdiplusStartup IN GDIPLUS.DLL ; LONG @ token, STRING @ INPUT, LONG @ OUTPUT DECLARE LONG GdiplusShutdown IN GDIPLUS.DLL LONG token DECLARE INTEGER GdipLoadImageFromFile IN GDIPLUS.DLL ; STRING wFilename, INTEGER @ nImage DECLARE INTEGER GdipDisposeImage IN GDIPLUS.DLL INTEGER nImage DECLARE INTEGER GdipGetImageWidth IN GDIPLUS.DLL ; INTEGER nImage, INTEGER @ nWidth DECLARE INTEGER GdipGetImageHeight IN GDIPLUS.DLL ; INTEGER nImage, INTEGER @ nHeight * Inicializar GDI+. LOCAL gdiplusStartupInput, lhGdiPlusToken gdiplusStartupInput = CHR(1) + REPLICATE(CHR(0), 15) lhGdiPlusToken = 0 IF GdiplusStartup(@lhGdiPlusToken, @gdiplusStartupInput, 0) != 0 RETURN .F. ENDIF * Cargar el objeto Picture LOCAL lnPictHandle lnPictHandle = 0 = GdipLoadImageFromFile( STRCONV(lcPictureFile + CHR(0),5), @lnPictHandle) * Obtener las dimensiones de la imagen LOCAL lnWidth, lnHeight STORE 0 TO lnWidth, lnHeight = GdipGetImageWidth(lnPictHandle, @lnWidth) = GdipGetImageHeight(lnPictHandle, @lnHeight) * Limpiar el controlador principal GDI+ = GdiplusShutdown(lhGdiPlusToken) MESSAGEBOX("GDI+ con llamadas API" + CHR(13) + ; "Dimensiones: " + TRANSFORM(lnWidth) + " x " + TRANSFORM(lnHeight))
Espero que esto ayude
¡ Que lo disfruten !
No hay comentarios. :
Publicar un comentario
Los comentarios son moderados, por lo que pueden demorar varias horas para su publicación.