Page 1 of 1

sql server guardar y mostrar imagen

Posted: Sat Sep 19, 2020 4:16 pm
by jpcavagnaro
Hola gente, necesito ayuda como mostrar un campo "IMAGE" de una tabla sql server.

Lo guardo sin problema, pero no encuentro la forma de mostrar la imagen en jpg.

Saludos.
Jorge

Re: sql server guardar y mostrar imagen

Posted: Sat Sep 19, 2020 5:11 pm
by nageswaragunupudi
Saving:

Code: Select all

oRs:Fields( <image_fieldname> ):Value := HB_STRTOHEX( MEMOREAD( cJpgFile ) )
oRs:Update()
 
Display:

Code: Select all

cImage := oRs:Fields( <image_fieldname> ):Value

// 1
XImage( cImage )

// 2
@ r,c XIMAGE cImage SIZE w,h OF oWnd
 

Re: sql server guardar y mostrar imagen

Posted: Mon Sep 21, 2020 12:40 pm
by Rick Lipkin
George

Are you trying to save an image or file to a Sql Table ?? and trying to reconstruct it back to its original file ?? I may have interpreted your question incorrectly .. however, This is how I store and retrieve a file from Sql Server ..

1) Use VarBinary(Max) field type
2 here is the code to save your file ( any file ) to a VarBinary(max) field in your table ... this is my code .. note this line is the key to the code

oRsCh:Fields("notes"):AppendChunk( VTArrayWrapper():New( 17, cBUFFER ) )

Code: Select all

//------------------------------
Static Func _Doit( oRsTrav, oRsCh, cPROJECTEID, cPath,oDLg )

LOCAL cFILENAME, nSTRING, nLEN, nSTART, SAYING, nDATETIME
LOCAL nHANDLE, nBYTES, cEID, cFILE, dDATE

LOCAL cBUFFER          // <------- This is the actual data to be stored
LOCAL nBytesRead

cFILE := upper(ALLTRIM( cPATH ))     // C:\DBTMP\CHARTER.DOC
nLEN  := LEN( cFILE )

nSTART := RAT( "\", cFILE )

IF nSTART > 0
ELSE
   SAYING := "INVALID File name or Location .. Aborting"
   MsgInfo( SAYING )
   oDLG:END()
   RETURN(.F.)
ENDIF

// get file name //
cFILENAME := SUBSTR( cPATH, nSTART+1, nLEN-nSTART )    // CHARTER.PDF

IF LEN(cFILENAME) > 35
   SAYING := "Sorry .. the maximum length of your file"+chr(10)
   SAYING += cFILENAME+CHR(10)
   SAYING += "is longer than 35 characters. Please re-name"+chr(10)
   SAYING += "your file to meet the 35 max length"+chr(10)
   MsgInfo( saying )
   oDlg:end()
   RETURN(.F.)
ENDIF

// open file //
nHANDLE := FOpen( cFILE )
IF FERROR() <> 0
   SAYING := "Error reading file "+cFILE+CHR(10)
   SAYING += " "+STR(FERROR())+CHR(10)
   MsgInfo( SAYING )
   oDLG:END()
   RETURN(.F.)
ENDIF

// get number of bytes in file
nBYTES := FSEEK( nHANDLE, 0,2 )

// pad the buffer nBytes+1
cBUFFER := SPACE(nBYTES+1)

FSeek( nHANDLE, 0, 0 )
nBytesRead   := FRead( nHANDLE, @cBuffer, nBytes )

FClose( nHANDLE )

if nBytesRead != nBytes
   SAYING := "nBytesRead = "+str(nBYTESREAD)+CHR(10)
   SAYING += "nBytes     = "+str(nBYTES)+CHR(10)
   SAYING += "Error Reading Data"+chr(10)
   MsgInfo( saying )
   oDLG:END()
   RETURN ( .F. )
endif

cEID := _GenEid()
IF cEID = "BOGUS"
   oDlg:End()
   RETURN(.F.)
ENDIF

nDateTime := dtoc(date())//+" "+time()

oRsCh:AddNew()

oRsCh:Fields("doceid"):Value        := cEID
oRsCH:Fields("TFormEid"):Value      := cPROJECTEID
oRsCh:Fields("DImport"):Value       := nDateTime
oRsCh:Fields("importby"):Value      := xLOGIN
oRsCh:Fields("datalen"):Value       := nBYTES
oRsCh:Fields("filename"):Value      := cFILENAME
oRsCh:Fields("notes"):AppendChunk( VTArrayWrapper():New( 17, cBUFFER ) )   // <--- here is the key to store the file in binary

oRsCh:Update()

SysReFresh()

SAYING := "Bytes Read   = "+str(nBYTESREAD)+CHR(10)
SAYING += "Bytes Stored = "+str(nBYTES)+CHR(10)
SAYING += "  "+CHR(10)
SAYING += "Upload Complete for file name "+cFILENAME+chr(10)
MsgInfo( saying )

oRsCh:Sort("DImport")
oRsCh:MoveFirst()
oRsCh:Find( "doceid = '"+cEID+"'" )

oDLG:END()
RETURN(.T.)


3) To retrieve the image from a VarBinary(max) field ..

Please note this line of code
cREAD := oRsCh:Fields("NOTES"):GetChunk( oRsCh:Fields("datalen"):Value)

Code: Select all

//-------------------------------
Static Func _Viewum( oRsCh,oDLG )

LOCAL nHANDLE, cREAD, cFILENAME, saying

If oRsCH:Eof
   Saying := "Sorry .. there are no records to view"
   Msginfo( saying )
   Return(.f.)
Endif


cFILENAME := alltrim(oRsCh:Fields("filename"):Value )

cREAD := oRsCh:Fields("NOTES"):GetChunk( oRsCh:Fields("datalen"):Value)
FERASE( xVOL+"\DBTMP\"+cFILENAME )

nHANDLE := FCREATE(  xVOL+"\DBTMP\"+cFILENAME, 0 )
IF FERROR() <> 0
   SAYING := "Error Creating file "+(xVOL+"\DBTMP\"+cFILENAME)+CHR(10)
   SAYING += "Error "+STR(FERROR())+CHR(10)
   MsgInfo( SAYING )
   RETURN(.F.)
ENDIF

FWRITE( nHANDLE, cREAD )   // write out the file
FCLOSE( nHANDLE )


SysReFresh()

SHELLEXECUTE( "", "open", (xVOL+"\DBTMP\"+cFILENAME),"","",1)

SysReFresh()

RETURN(.T.)
Don't know if this is what you have in mind .. Hope this helps.

Rick Lipkin

Re: sql server guardar y mostrar imagen

Posted: Mon Sep 21, 2020 3:41 pm
by nageswaragunupudi
Anyone can build and run this sample:
Here we connect to a free MSSQL server in the cloud provided by FWH for testing purposes.

Code: Select all

function TestImageMSSQL

   local oCn, cSql, oRs, oDlg, oImage
   local cTable   := "TEST_JPG"

   oCn := FW_OpenAdoConnection( "MSSQL,208.91.198.196,gnraore3_,fwhmsdemo,fwh@2000#", .t. )

   oCn:Execute( "DROP TABLE IF EXISTS " + cTable )
   FWAdoCreateTable( cTable, { { "NAME", "C", 20, 0 }, { "PHOTO", "m", 10, 0 } }, oCn )

   oRs   := FW_OpenRecordSet( oCn, cTable )
   oRs:AddNew()
   oRs:Fields( "NAME"  ):Value := "OLGA1"
   oRs:Fields( "PHOTO" ):Value := HB_STRTOHEX( MEMOREAD( "c:\fwh\bitmaps\olga1.jpg" ) )
   oRs:Update()

   XBROWSER oRs

   oRs:MoveFirst()
   DEFINE DIALOG oDlg SIZE 400,500 PIXEL
   @ 10,10 XIMAGE oImage SOURCE oRs:Fields( "PHOTO" ):Value SIZE -10,-10 OF oDlg
   ACTIVATE DIALOG oDlg CENTERED

   oRs:Close()
   oCn:Close()

return nil
Browse:
Image

XImage:
Image

Re: sql server guardar y mostrar imagen

Posted: Mon Sep 21, 2020 3:48 pm
by nageswaragunupudi
Two ways of creating the above table
METHOD-1

Code: Select all

TEXT INTO cSql
CREATE TABLE TEST_JPG (
   ID    INT IDENTITY(1,1) PRIMARY KEY,
   NAME  VARCHAR( 20 ),
   PHOTO IMAGE
   )
ENDTEXT
   oCn:Execute( cSql )
 
METHOD-2: Simpler and recommended by FWH

Code: Select all

FWAdoCreateTable( cTable, { { "NAME", "C", 20, 0 }, { "PHOTO", "m", 10, 0 } }, oCn )
 
Note: Use small "m" for binary data

Re: sql server guardar y mostrar imagen

Posted: Mon Sep 21, 2020 4:03 pm
by nageswaragunupudi
Alternative methods for inserting image (or any binary) data:

USING RECORDSET OBJECT:

Method-1: Longer code if you have patience to write

Code: Select all

oRs   := FW_OpenRecordSet( oCn, cTable )
oRs:AddNew()
oRs:Fields( "NAME"  ):Value := "OLGA1"
oRs:Fields( "PHOTO" ):Value := HB_STRTOHEX( MEMOREAD( "c:\fwh\bitmaps\olga1.jpg" ) )
oRs:Update()
 
Method-2: Short and simpler code, for lazy people like me.

Code: Select all

oRs   := FW_OpenRecordSet( oCn, cTable )
oRs:AddNew( { "NAME", "PHOTO" }, { "OLGA1", HB_STRTOHEX( MEMOREAD( "c:\fwh\bitmaps\olga1.jpg" ) ) } )
 
WITHOUT OPENING RECORDSET:

Code: Select all

#include "adodef.ch"
...
...
cSql  := SQL INSERT INTO TEST_JPG ( NAME, PHOTO ) VALUES ( "OLGA1", MEMOREAD( "c:\fwh\bitmaps\olga1.jpg" ) )
oCn:Execute( cSql )
 

Re: sql server guardar y mostrar imagen

Posted: Tue Sep 22, 2020 10:01 pm
by jpcavagnaro
Hola, me da error HB_STRTOHEX no definida, que librería me falta?

Saludos
Jorge

Re: sql server guardar y mostrar imagen

Posted: Tue Sep 22, 2020 11:23 pm
by Cgallegoa
Jorge,

HB_STRTOHEX() es de 'Harbour'. Si estás usando 'xHarbour' la function es STRTOHEX()

O puedes hacer:

Code: Select all

#xtranslate HB_STRTOHEX([<xx,...>]) => STRTOHEX([<xx>])

Re: sql server guardar y mostrar imagen

Posted: Wed Sep 23, 2020 3:15 am
by nageswaragunupudi
jpcavagnaro wrote:Hola, me da error HB_STRTOHEX no definida, que librería me falta?

Saludos
Jorge
Use STRTOHEX(...) instead of HB_STRTOHEX(...) if you are using xHarbour.

Re: sql server guardar y mostrar imagen

Posted: Wed Sep 23, 2020 11:16 am
by jpcavagnaro
Buen día, funciono perfecto.

Muchas gracias

Saludos
Jorge.

Re: sql server guardar y mostrar imagen

Posted: Wed Sep 23, 2020 3:12 pm
by jpcavagnaro
Una pregunta que me surgió, como manejan la calidad y/o tamaño de las imágenes.

Por el espacio que ocupan.

SAludos.
Jorge