Reporte con foto de un campo BLOB de MySQL

771 views
Skip to first unread message

Arturo Ramos

unread,
Apr 8, 2016, 10:20:06 PM4/8/16
to Comunidad de Visual Foxpro en Español
Hola foro,

Tengo una tabla donde guardo fotos de socios en un campo BLOB, la tabla es de MySQL.

Necesito hacer un reporte de credenciales pero no doy con la consulta o el tipo de dato que debo obtener para el reporte o como manejar el Picture/OLE del reporte.

Estoy usando:
VFP 9.0
Reporte de VFP
MySQL

¿Alguna luz de su parte?

Muchas gracias.

Saludos.

Arturo Ramos
Cancún, México

Elides Paredes

unread,
Apr 9, 2016, 5:12:32 PM4/9/16
to Comunidad de Visual Foxpro en Español

 

Amigo Arturo

Saludos.

 

Trabajo con muchas fotos en mi sistema, porque manejo un sistema para talleres, tengo fotos de vehículos, piezas, esquemas, etc. son muuuuchas fotos, al principio me gustó mucho la idea de guardar la foto en una tabla, pero eso da muchos problemas y resultan tablas muy grandes, hice referencia a que manejo muchas fotos porque para mi eso es un gran problema, el tamaño de las tablas si contienen fotos.

Quizás en tu caso sean menos fotos y sea también factible. Sin embargo te recomiendo, por mi experiencia que no guardes las fotos en tablas, sino el nombre y luego usas controles de imágenes y allí le pones el picture según un campo que guarda el nombre del archivo foto. Y podrás ver que eso cambia todo.

 

Saludos de Elides Paredes

Barquisimeto Venezuela

Víctor Hugo Espínola Domínguez

unread,
Apr 9, 2016, 9:10:08 PM4/9/16
to publice...@googlegroups.com
Escribe una función que cree un archivo de la imagen y devuelva la ruta y el nombre de ese archivo, algo parecido a ésto:

Function FotoUsuario As String
    Lparameters tnIdUsuario As Integer

    Local lcArchFotoUsuario

    If Empty(CampoFoto) Or Isnull(CampoFoto)
        lcArchFotoUsuario = ".\Imags\SinFoto.jpg"
    Else
        lcArchFotoUsuario = Addbs(Sys(2023)) + Transform(m.tnIdUsuario) + "." + ExtFoto
        Strtofile(Cast(CampoFoto As Blob), m.lcArchFotoUsuario)
    Endif

    Return (m.lcArchFotoUsuario)

Endfunc


En el control Picture/Ole bound ...



Saludos,
Víctor.
Lambaré - Paraguay.

Arturo Ramos

unread,
Apr 12, 2016, 12:49:10 PM4/12/16
to Comunidad de Visual Foxpro en Español
Hola Elides,

Disculpa por no contestar rápido, estoy de acuerdo con tu propuesta, no se me hace muy operativo guardar las imágenes en la bd, en su momento (hace años) decidimos hacerlo de esta forma pues no se trata más que la foto del socio, creo que nuestro problema estaba en como compartir las rutas a los archivos de foto para los usuarios del sistema en la red pero bueno, te digo, de cualquier forma no son tantas fotos.

Tomaré en cuenta tu comentario a ver si en un futuro podemos mejorar esa parte para no tener que guardar las fotos en la bd.

Si guardas la ruta a una imagen, ¿cómo le haces para que todas las terminales de la red tengan acceso a ellas al momento de tener que mostrarlas?

Gracias por tus comentarios,

Saludos-

Arturo Ramos

unread,
Apr 12, 2016, 12:52:07 PM4/12/16
to Comunidad de Visual Foxpro en Español
Hola Víctor,

Disculpa la demora para contestar...

Probaré tu código, muchas gracias...

Una duda, ¿que pasa con todas las fotos "temporales" que se guardan en disco?

Saludos,

ZeRoberto

unread,
Apr 12, 2016, 12:58:26 PM4/12/16
to publicesvfoxpro
Acotando a los consejos de Elides, tambien es bueno que uses una rutina para normalizar el tamaño de los archivos, para evitar que suban archivos de 3800x3800 pixeles y pesen mas de 2mb, busca en el foro esa rutina.

Víctor Hugo Espínola Domínguez

unread,
Apr 12, 2016, 1:14:30 PM4/12/16
to publice...@googlegroups.com
>Una duda, ¿que pasa con todas las fotos "temporales" que se guardan en disco?

Puedes borrarlas al terminar el report, o si las dejas no es un problema, los discos actuales como mínimo son de 500GB y además en la siguiente ejecución del report estos archivos serán regrabados.

Si guardas la fotos en una carpeta compartida deberías buscar una forma de proteger la carpeta compartida contra sobreescrituras y borrados.


Saludos,
Víctor.
Lambaré - Paraguay.


Arturo Ramos

unread,
Apr 12, 2016, 1:16:09 PM4/12/16
to Comunidad de Visual Foxpro en Español
Gracias, lo tomaré en cuenta.

buscando la rutina...

Arturo Ramos

unread,
Apr 12, 2016, 1:24:39 PM4/12/16
to Comunidad de Visual Foxpro en Español
Gracias Víctor,

Se me ocurre crear una rutina que verifique si la foto ya se encuentra en el disco local, si no se encuentra la crea desde el campo de la bd y para la próxima vez que se requiera en esa terminal ya se le tiene de forma local.

Víctor Hugo Espínola Domínguez

unread,
Apr 12, 2016, 1:46:35 PM4/12/16
to publice...@googlegroups.com
En ese caso debes guardar la fecha y hora de grabación de la foto en la tabla, la cual debe ser menor que fecha hora de la creación del archivo temporal. No sé si amerita para pocos registros, habría que probar y comparar los tiempos.



Saludos,
Víctor.
Lambaré - Paraguay.


Arturo Ramos

unread,
Apr 12, 2016, 1:57:32 PM4/12/16
to Comunidad de Visual Foxpro en Español

Si asumimos que la foto del socio con id 590 debe se ".\Fotos\S000590.jpg", si se encuentra en la ruta, se usa, si no, se crea para la próxima vez que se necesite.

Si se usa el sistema en una terminal nueva, la primera vez que se requiera la foto de algún socio, se crea en su ruta local.

¿qué opinas?

Saludos.

Víctor Hugo Espínola Domínguez

unread,
Apr 12, 2016, 2:26:40 PM4/12/16
to publice...@googlegroups.com
Si no controlas por fecha hora corres el riesgo de mostrar una foto desactualizada.


Saludos,
Víctor.
Lambaré - Paraguay.


Antonio Meza

unread,
Apr 12, 2016, 2:28:05 PM4/12/16
to Comunidad de Visual Foxpro en Español
En mi experiencia es mejor en la DB porque te evitas problemas de todo tipo, eso si los respaldos serán mas pesados, pero ya estas respaldando la información y fotos, la seguridad estará lista no tienes que compartir carpetas en el servidor y dejar la puerta abierta a los virus.

A la hora de respaldar lo puedes hacer de muchas formas, incluso respaldar diario la información importante y las tablas de las fotos con menor frecuencia si no han tenido cambios, el guardar las fotos en la DB se requiere un poco mas de programación para el control de ella, pero una vez que las rutinas funcionen ya todo sera normal, como el recuperar una foto o varias fotos para los reportes, cuando subas el servidor a la web no tienes que hacer nada mas que cambiar la IP de conexión a la base de datos, en cambio si las fotos están en carpetas ya te veré reprogramando todo.

saludos
Antonio Meza

Arturo Ramos

unread,
Apr 12, 2016, 6:17:52 PM4/12/16
to Comunidad de Visual Foxpro en Español
O.o ya te entendí...

Esto es lo que hice:
- al dar de alta guardo la foto en la bd y un nombre de archivo temporal: "_"+SUBSTR(SYS(2015), 4)+"S"+RIGHT("0000000000" + ALLTRIM(STR(tnIdSocio)),10)+".jpg"
- ese archivo se busca en cada terminal, si no existe se crea y está disponible para las siguientes veces de forma local
- si se cambia la foto se guarda en la bd y se actualiza el nombre del archivo temporal 
- cuando se requiera no va a existir así que se crea de forma local en cada terminal

¿que opinas?, ¿le di mucha vuelta?

Gracias.

Arturo Ramos

unread,
Apr 12, 2016, 6:20:31 PM4/12/16
to Comunidad de Visual Foxpro en Español
Gracias Antonio, buen punto.

Alberto Mancuso

unread,
Apr 12, 2016, 6:25:46 PM4/12/16
to publice...@googlegroups.com

Yo lo que guardo es la ruta del archivo pero sin la unidad de disco ej \winvet\fotos así usándolo en red al sistema no tengo problemas

Víctor Hugo Espínola Domínguez

unread,
Apr 12, 2016, 6:57:25 PM4/12/16
to publice...@googlegroups.com
Me gusta la idea 👏

Saludos,
Víctor.
Lambaré - Paraguay.


Elides Paredes

unread,
Apr 12, 2016, 11:21:53 PM4/12/16
to Comunidad de Visual Foxpro en Español
Que tal amigo Arturo?

Creo que el amigo Panchimancuso dio una buena idea. Yo particularmente no  trabajo aún en red. Pero he aprendido algo que quiero re transmitir. Es un simple consejo. Que le puede servir a todos los que consultan éstas 'conversaciones'.. 

Cuando los maestros de éste foro (y no me incluyo en ese grupo) dicen que se debe hacer algo así, pues, por mi experiencia he terminado necesitando hacerlo así.. jajaja... Es un chiste cruel para mi, porque eso ha significado rehacer muchas cosas. O sea mas trabajo. Por eso me atreví a repetir lo que los expertos comentan.

No obstante ese esfuerzo ha valido la pena porque me salen las cosas mejor de lo que incluso me podría imaginar, 
Pero claro, si ya está hecho todo y no deseas rehacer las cosas, pues... es tu decisión y la respeto.

Saludos amigo
Elides Paredes
Barquisimeto Venezuela..

Arturo Ramos

unread,
Apr 12, 2016, 11:40:54 PM4/12/16
to Comunidad de Visual Foxpro en Español
No me funciona por que cada terminal de la red ejecuta su propio .exe en su propia carpeta local; hacer lo que dices de todas formas implica mover los archivos a todas las terminales para que cada una tenga su carpeta fotos con todas las fotos.

Supongo que tu lo que haces es correr el .exe desde el "servidor" en una carpeta compartida donde está la carpeta fotos.

En mi caso cada terminal, hasta el servidor, tiene su propia carpeta "sistema\fotos".

Gracias por tus comentarios.

Saludos.

elkin dario uribe torres

unread,
Apr 13, 2016, 8:37:14 AM4/13/16
to publice...@googlegroups.com
Buenos dias

Leyendo todo el hilo, recuerdo que en su tiempo por el 2010 se hablo sobre el mismo tema y las recomendaciones que dieron fue guardar las imagenes en la base de datos y lo hice para las dos opciones por la razon de que en ese momento la informacion se almacenaba en el motor de VFP y este tiene un tamaño limitado para lo que se pretendia.  Por lo tanto la solucion que encontre que no se si es la mejor pero me funciona es:

- Se guardan las imagenes en una carpeta y esta se subdivide en carpetas que cada una lo maximo que guarde son 1.000 archivos por cuestiones de limitacion del windows. Ya que al almacenar mas imagenes de esta se vuelve demasiado elnto el sistema operativo al tratar de ver la carpeta por el explorador de windows (NTFS). (Opcion Vfp)

- La carpeta del servidor donde se encuentran las imagenes estan definidas en un archivo .ini con la siguientes instrucciones (Opcion VFP)

[Default]
NROSERIAL="y:"
NROCONTRASENA="\TABLAS\"
NROSENA="bases.dbc"

PIEL='f:\aplicacion\SKINS\COMMANDER.VFS'
GUIAS="f:\guias_escaneadas"
RECIBOS="f:\recibospdf"
CONSIGNACION="f:\consignacionespdf"
CONVENIOS="f:\CONVENIOS PDF"

- Al momento de ingresar a la aplicacion (cada exe existe en cada estacion) este va y lee el archivo INI y los valores los almacena en propiedades o variables publicas.

- Se determina que tipo de motor se va a utilizar ("VFPDatabase" o "SqlDatabase")

Cada que quiero cargar una imagen esta los hago cargando la ruta almacenada en la variables/propiedades con el siguiente codigo.  (Opcion VFP)



PRIVATE lcArchivo

STORE INT(VAL(cartas1.consecutiv)/1000000) TO lccreardir1
STORE INT((VAL(cartas1.consecutiv)/1000000)*1000) TO lccreardir2 
STORE gcGuias+"\"+ALLTRIM(STR(lccreardir1))+"\"+ALLTRIM(STR(lccreardir2)) TO Lcdir
lcFile = (Lcdir)+"\"+ALLTRIM((cartas1.Consecutiv))+".tif"
STORE "TIF" TO lcExtension
IF tipoconexion = "VFPDatabase"
IF FILE(lcFile)
DO FORM ver_tif WITH lcFile, "Guia No.",ALLTRIM((cartas1.Consecutiv))
ELSE
IF !EMPTY(thisform.vfpskin1.cskinname)
thisform.vfpskin1.skinmessagebox('La Guia no esta disponible por el momento',16,"Empresa",m.duracion_mensajes)
ELSE
=MESSAGEBOX('La Guia no esta disponible por el momento',16,"Empresa",m.duracion_mensajes)
ENDIF
ENDIF
ELSE
LOCAL loFile AS "base64Helper"
loFile = CREATEOBJECT("base64Helper")
lcCodigo = ALLTRIM(cartas1.Consecutiv)

set textmerge on TO memvar lcStringSQL noshow
\SELECT codigo1,contenido,nombre, tipo_movimiento FROM Imagenes1 WHERE LTRIM(RTRIM(codigo1)) = ?lcCodigo and LTRIM(RTRIM(tipo_movimiento)) = 'GUIAS'
set textmerge to

DO conectarSql
STORE sqlexec(controlador,lcStringSQL,'QARCHIVO') TO a
sqldisconnect(0)
IF a > 0
IF !EMPTY(QARCHIVO.contenido)
LOCAL cTarget,cBase64
cTarget = "C:\temp\" + RTRIM(QARCHIVO.nombre)
cBase64 = RTRIM(QARCHIVO.contenido)
loFile.decodeFile(cBase64, cTarget)
DO FORM ver_tif WITH cTarget, "Guia No.",ALLTRIM((cartas1.Consecutiv)) TO respuesta
IF respuesta = .T.
DELETE FILE (cTarget)
ENDIF
ELSE
IF !EMPTY(thisform.vfpskin1.cskinname)
thisform.vfpskin1.skinmessagebox('La Guia no esta disponible por el momento',16,"Empresa",m.duracion_mensajes)
ELSE
=MESSAGEBOX('La Guia no esta disponible por el momento',16,"Empresa",m.duracion_mensajes)
ENDIF
ENDIF
ELSE
IF !EMPTY(thisform.vfpskin1.cskinname)
thisform.vfpskin1.skinmessagebox('La Guia no esta disponible por el momento',16,"Empresa",m.duracion_mensajes)
ELSE
=MESSAGEBOX('La Guia no esta disponible por el momento',16,"Empresa",m.duracion_mensajes)
ENDIF
ENDIF 
RELEASE loFile
ENDIF 

Espero que se entienda un poco lo expuesto, en lo que se refiere al almacenamiento en la base de datos todo el codigo que utilizo para almacenar y ver la imagen es del maestro VICTOR ESPINA.

La imagen la llevo a un archivo temporal, permito que se pueda visualizar y por cuestiones de seguridad pueden ver que la imagen se borra, no se almacena.


Saludos


Elkin Uribe
Reply all
Reply to author
Forward
0 new messages