[VFP] Recortar una imagen

934 views
Skip to first unread message

ZeRoberto

unread,
Aug 30, 2012, 3:13:07 PM8/30/12
to publicesvfoxpro
Hola a todos exite alguna forma de poder recortar y reducir una imagen?
 
Lo que quiero es que el usuario seleccione una foto en jpg y lo redusca, centre y recorte a una medida predeterminada, quiero hacerlo asi para evitar que la base de datos se llene con archivos pesados.
 
Ejemplo
Si la foto tiene 500 x 400
Que el usuario recorte de la posision 100,100 a la 300, 200 osea que ajuste la foto al rostro de la persona.
 
Saludos

Luis Maria Guayan

unread,
Aug 30, 2012, 3:25:14 PM8/30/12
to publice...@googlegroups.com
Todo eso lo puedes hacer con la clase GDIPlusX.

Busca en PortalFox que hay muchos artículos traducidos de Cesar

http://goo.gl/p8Wez

Luis María Guayán
Tucumán, Argentina
_________________________
http://www.PortalFox.com
Nada corre como un zorro
_________________________

--
 
 
 

ZeRoberto

unread,
Aug 30, 2012, 3:29:19 PM8/30/12
to publice...@googlegroups.com
Grande Luis Mari voy a buscarlos.

Saludos
--
 
 
 

Edgar Acevedo

unread,
Aug 30, 2012, 6:10:41 PM8/30/12
to publice...@googlegroups.com
Como te indica Luis, César ha compartido bastante al respecto. Creo que en Portal Fox encontré
específicamente el siguiente Procedimiento para recortar imágenes:

* OriPic = Archivo de imagen original
* M.AnchoP = Nuevo ancho a asignar
* M.AltoPi = Nuevo alto a asignar
* M.RecPic = Nuevo Archivo creado con los nuevos tamaños asignados

PROCEDURE Recortar_IMG
   PARAMETERS M.OriPic, M.AnchoP, M.AltoPi, M.RecPic
   SET CLASSLIB TO (ADDBS(XPATPR) + "_gdiplus.vcx") ADDITIVE
 * Cargar la imagen a Gdiplus
   loImage = NEWOBJECT("GpImage")
   loImage.CreateFromFile(M.OriPic)
   lnWidth = loImage.ImageWidth
   lnHeight = loImage.ImageHeight
 * Recortar imagen a los pixeles solicitados
   loCropped = Crop(loImage, 0, 0, M.Anchop, M.AltoPi)
   IF FILE(M.RecPic)
      ERASE (M.RecPic)
   ENDIF
   DO CASE
      CASE UPPER(ALLTRIM(RIGHT(M.OriPic,3))) = "BMP"
         loCropped.SavetoFile(M.RecPic,"image/bmp")
      CASE UPPER(ALLTRIM(RIGHT(M.OriPic,3))) = "PNG"
         loCropped.SavetoFile(M.RecPic,"image/png")
   ENDCASE
   RELEASE loImage, loCropped
   RELEASE CLASSLIB (ADDBS(XPATPR) + "_gdiplus.vcx")
RETURN

PROCEDURE Crop(toImage, x, Y, tnWidth, tnHeight, tnPixelFormat)
   IF VARTYPE(tnPixelFormat) = "L"
      tnPixelFormat = toImage.PixelFormat
   ENDIF
   DECLARE LONG GdipCloneBitmapAreaI IN GDIPLUS.DLL ;
      LONG x, LONG Y, LONG nWidth, LONG nHeight, ;
      LONG PixelFormat, LONG srcBitmap, LONG @dstBitmap
   LOCAL lnNewBitmap
   lnNewBitmap = 0
   = GdipCloneBitmapAreaI(x, Y, tnWidth, tnHeight, ;
      tnPixelFormat, toImage.GetHandle(), @lnNewBitmap)
   LOCAL loNewImage
   loNewImage = NEWOBJECT("GpBitmap",HOME()+"ffc/_gdiplus.vcx")
   loNewImage.SetHandle(lnNewBitmap)
   RETURN loNewImage
ENDPROC

Salu2,



Edgar Acevedo


--
 
 
 

ZeRoberto

unread,
Aug 30, 2012, 6:47:57 PM8/30/12
to publice...@googlegroups.com
excelente edgar voy a probarlo
 
saludos

--
 
 
 

Edgar Acevedo

unread,
Aug 30, 2012, 9:13:02 PM8/30/12
to publice...@googlegroups.com
Pido disculpas: 
lo copié y pegué tal y como lo uso según mi programa.  Claramente ZeRoberto lo entendió muy bien así, pero posiblemente alguien menos experto (el león juzga según su condición...) podría confundirse cuando le salga algún mensaje de error.   Por eso, lo posteo de nuevo con mayores aclaraciones:

* ADVERTENCIA:  Para que el siguiente ejemplo te funcione, debes tener incluidos en
* en la misma carpeta de tu aplicación, los archivos  _GDIPLUS.VCT  y _GDIPLUS.VCX
* Si no los tuvieras incluídos en la misma carpeta, deberás indicarle en donde ubicar
* estas librerías visuales.

* OriPic = Archivo de imagen original
* M.AnchoP = Nuevo ancho a asignar
* M.AltoPi = Nuevo alto a asignar
* M.RecPic = Nuevo Archivo creado con los nuevos tamaños asignados

PROCEDURE Recortar_IMG
   PARAMETERS M.OriPic, M.AnchoP, M.AltoPi, M.RecPic, M.PatGDI
   SET CLASSLIB TO
_gdiplus.vcx ADDITIVE

 * Cargar la imagen a Gdiplus
   loImage = NEWOBJECT("GpImage")
   loImage.CreateFromFile(M.OriPic)
   lnWidth = loImage.ImageWidth
   lnHeight = loImage.ImageHeight
 * Recortar imagen a los pixeles solicitados
   loCropped = Crop(loImage, 0, 0, M.Anchop, M.AltoPi)
   IF FILE(M.RecPic)
      ERASE (M.RecPic)
   ENDIF
   DO CASE
      CASE UPPER(ALLTRIM(RIGHT(M.OriPic,3))) = "BMP"
         loCropped.SavetoFile(M.RecPic,"image/bmp")
      CASE UPPER(ALLTRIM(RIGHT(M.OriPic,3))) = "PNG"
         loCropped.SavetoFile(M.RecPic,"image/png")
   ENDCASE
   RELEASE loImage, loCropped
   RELEASE CLASSLIB _gdiplus.vcx

RETURN

PROCEDURE Crop(toImage, x, Y, tnWidth, tnHeight, tnPixelFormat)
   IF VARTYPE(tnPixelFormat) = "L"
      tnPixelFormat = toImage.PixelFormat
   ENDIF
   DECLARE LONG GdipCloneBitmapAreaI IN GDIPLUS.DLL ;
      LONG x, LONG Y, LONG nWidth, LONG nHeight, ;
      LONG PixelFormat, LONG srcBitmap, LONG @dstBitmap
   LOCAL lnNewBitmap
   lnNewBitmap = 0
   = GdipCloneBitmapAreaI(x, Y, tnWidth, tnHeight, ;
      tnPixelFormat, toImage.GetHandle(), @lnNewBitmap)
   LOCAL loNewImage
   loNewImage = NEWOBJECT("GpBitmap", "_gdiplus.vcx")
   loNewImage.SetHandle(lnNewBitmap)
   RETURN loNewImage
ENDPROC

Podrán encontrar mas funciones para manipular imágenes compartidas generosamente por el maestro César Chalom en   www.portalfox.com

Salu2,


Edgar Acevedo


--
 
 
 

J. Enrique Ramos Menchaca

unread,
Aug 30, 2012, 9:33:40 PM8/30/12
to publice...@googlegroups.com
Yo utilizo el ImageViewer pro de viscos software trae un ejemplo en VFP y puedes bajar el trial de su pagina.

ZeRoberto

unread,
Aug 31, 2012, 12:09:54 PM8/31/12
to publice...@googlegroups.com
Edgar la rutina funciona bien, pero hay un detalle solo trabaja con bmp y png pero no con jpg.
 
Ahora me baje una funcion parecida a esta que me reduce la imagen a cierta dimension, como pudiera hacer para integrarle a esta, osea lo que quiero es que redusca la imagen y al mismo tiempo hacerle un crop.
 
Saludos

--
 
 
 

Edgar Acevedo

unread,
Aug 31, 2012, 12:45:34 PM8/31/12
to publice...@googlegroups.com
Quien realmente saca la tarea es el  PROCEDURE CROP  que como notaste solo trabaja con  'mapas de bits'.  Seguramente no te trabajará con imágenes JPG porque éstas estan comprimidas en una forma que el  PROCEDURE CROP no puede procesar. Cuando yo buscaba como recortar JPG un diseñador me dijo "No hagas eso.  Perderás mucha información valiosa sobre la calidad de la imagen.  Si quieres recortar un JPG primero pásalo a TIFF, allí lo recortas y luego lo devuelves recortado a JPG".  Seguí su consejo "por la fuerza" ya que no encontré como recortar JPG  desde  VFP.

Yo creo que para recortar un JPG si necesitarías un Activex como el que recomienda Enrique Ramos mas arriba en este hilo ya de de plano este hace el trabajo de descompresión previo a permitirte hacer el recorte (pero "tras bambalinas" de manera que vos ni lo notas cuando sucede).

Aunque también está la posiblidad que César ya haya resuelto algo al respecto y yo estoy aquí desanimándote con puras tonterías...  Habrá que buscar un poquito mas el trabajo de César...

Salu2,



Edgar

--
 
 
 

ZeRoberto

unread,
Aug 31, 2012, 12:49:41 PM8/31/12
to publice...@googlegroups.com
Edgar en si lo que quiero es que primero lo redusca y luego lo recorte, hago esto para que el usuario ajuste la foto a una dimension determinada
 
saludos

--
 
 
 

Edgar Acevedo

unread,
Aug 31, 2012, 12:52:47 PM8/31/12
to publice...@googlegroups.com
Siendo ese el caso, tal vez este link que tenía guardado por allí te ayude con tu desafío:

http://weblogs.foxite.com/vfpimaging/2006/02/06/resize-images-with-vfp9-and-gdi/

Salu2,


Edgar

--
 
 
 

Cesar VfpImaging

unread,
Aug 31, 2012, 2:21:35 PM8/31/12
to publice...@googlegroups.com
Hola Edgar,

Para eso, en este blogpost hay mas explicaciones, pero utilizando GdiPlusX:

Saludos


2012/8/31 Edgar Acevedo <aper...@gmail.com>
--
 
 
 

Reply all
Reply to author
Forward
0 new messages