¿Se puede escanear documentos desde five?

¿Se puede escanear documentos desde five?

Postby jfafive » Sat Dec 13, 2008 12:07 pm

Hola,

Quisiera saber si hay funciones o librerías en FWH para poder hacer una pequeña aplicación de escaneo. Ya sabeis, escanear un documento y guardarlo.

Saludos :wink:
jfafive
 
Posts: 396
Joined: Tue Mar 18, 2008 9:41 pm
Location: Marbella

Postby Willi Quintana » Sat Dec 13, 2008 3:46 pm

La clase TSCANNER de Rafa Carmona
Salu2
User avatar
Willi Quintana
 
Posts: 1002
Joined: Sun Oct 09, 2005 10:41 pm
Location: Cusco - Perú

Postby jfafive » Sun Dec 14, 2008 9:54 am

Willi,

¿sabes donde puedo descargar la clase TScann de R. Carmona?

Gracias,
jfafive
 
Posts: 396
Joined: Tue Mar 18, 2008 9:41 pm
Location: Marbella

Postby jfafive » Sun Dec 14, 2008 11:42 am

Hola de nuevo,

Ya he conseguido bajarme la clase TScan de Rafa Carmona.
Pero al ejecutar el TestHarbout, o un ejemplo con las líneas...

Code: Select all  Expand view
#include "FiveWin.ch"

function Main()

   local oScan

   oScan := TScan32():New( "pepe.jpg" )
   oScan:DigiToFile()

return nil


Me devuelve un mensaje de error que dice,
Image

:cry:
jfafive
 
Posts: 396
Joined: Tue Mar 18, 2008 9:41 pm
Location: Marbella

Postby George » Sun Dec 14, 2008 6:29 pm

Jfafive,

Puedes tambien utlizar la clase de L. Gadaleta, funciona perfecta.

Code: Select all  Expand view
  /*------------------------------------------------------------------------*
     ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
   Ûݳ                                                                   ³
   Ûݳ ProcName......: Scanner.prg                                       ³
   Ûݳ Pourpose......: TWAIN standard device Class interface             ³
   Ûݳ Date..........: 05-11-96                                          ³
   Ûݳ Author........: (c),L.Gadaleta                                    ³
   Ûݳ                                                                   ³
   ÛÝÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
   ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
*------------------------------------------------------------------------*/
#include "FiveWin.ch"
#include "Image.ch"

#define STAND_ALONE

#define TWAIN_DLL             "EZTw32.dll"

#define CBM_INIT 4    // for freeimage.dll

#define DIB_RGB_COLORS 0 // for freeimage.dll

STATIC oWnd, oImage
STATIC hLib              // for freeimage.dll


#ifdef STAND_ALONE

FUNCTION ScanID(cFileRes, nInt)

LOCAL cFile, nRes, n
cFile := cFileRes
nRes  := 100


if !cFileRes == NIL
   if ( n:=AT(",",cFileRes) ) > 0
      cFile := Alltrim(Substr(cFileRes,1,n-1))
      nRes  := Val(Alltrim(Substr(cFileRes,n+1)))
   end
end

CursorWait()

DEFINE WINDOW oWnd FROM 1,1 TO 1,1

ACTIVATE WINDOW oWnd ON INIT (oWnd:Hide(), ;
                              RunScan(cFile,oWnd:hWnd,nRes))

if file( cFile )
   SaveImage( cFile )
end

CursorArrow()

RETURN NIL

STATIC FUNCTION RunScan(cFile,hWnd,nRes)
LOCAL oScanner := Scanner():New(hWnd)
DEFAULT nRes := 100                                     // Scanner resolution in Dpi

nRes := 100
   oScanner:Choose()
   oScanner:Set(.T.)                                       // Set User Interface Off
   oScanner:DigiToFile(cFile,nRes)                   // Acquires
  //oScanner:DigiToClip()
 
   oScanner:End()
   oWnd:End()
RETURN NIL

#endif

CLASS Scanner
   DATA   hWnd   AS NUMERIC   // Handle of the window
   DATA   hDll   AS NUMERIC   // Handle of the DLL
   DATA   lLoad  AS LOGICAL   //   .T. DLL & Driver Loaded
   DATA   hDib   AS NUMERIC   // Current Dib handle
   *
   METHOD New()         CONSTRUCTOR
   METHOD End()
   METHOD Set()                    // Acquiring Dialog ON/OFF
   METHOD Choose()         // Select Image Device Source
   METHOD DigiToFile()      // Acquire Image and save to a file
   METHOD DigiToClip()      // Acquire Image and copy to ClipBoard
   METHOD SetResolution()          // Set Dpi for the scanner
   *
   PROTECTED :
      METHOD Free()         // Release Dib's handle
      METHOD IsActive()      // Twain Driver Loaded
      METHOD Register()      // Register my application into Twain application
                METHOD DibToFile()              // Write to file Dib's handle in BMP format
END CLASS

METHOD New(hWnd)
// Constructor
::hWnd := iif( ValType( hWnd ) == "N" , hWnd , 0 )
::lLoad := .T.
//msginfo(::hDLL)
::hDLL := LoadLibrary( TWAIN_DLL )
::hDib := 0
if ::hDll <= 21
   ::lLoad := .F.
   MsgAlert( BuildError(::hDll) , TWAIN_DLL )
   RETU Self
end
if ( ::lLoad := ::IsActive() )
   ::Register()
end
RETU Self

METHOD End()
// Destructor
if ::hDib != 0
   ::Free( ::hDib )
end
FreeLibrary( ::hDll )
RETU NIL

METHOD DigiToFile( cFile , nRes )
// Acquire Document & save to file
LOCAL nPixType := 0
LOCAL cFarProc
DEFAULT nRes := 100

nRes := 100
::SetResolution( nRes )

if ::lLoad
   cFarProc := GetProcAddress( ::hDLL, "TWAIN_AcquireNative",.T., WORD,WORD,_INT )
   ::hDib  := CallDLL( cFarProc,::hWnd,nPixType )
   if ::hDib == 0
                MsgInfo("Cannot Load Image, Scanner not found","")
   else
      ::DibToFile(::hDib,cFile)
      ::Free( ::hDib )
   end
end

RETU Self

METHOD DigiToClip()
// Acquire document & copy to ClipBoard
LOCAL nPixType := 0
LOCAL cFarProc
LOCAL nResult

nRes := 100
::SetResolution( nRes )

if ::lLoad
   cFarProc := GetProcAddress( ::hDLL, "TWAIN_AcquireToClipBoard",.T., _INT,WORD,_INT )
   nResult  := CallDLL( cFarProc,::hWnd,nPixType )
end
RETU Self

METHOD SetResolution( nDpi )
// NEW
LOCAL cFarProc
LOCAL uResult
DEFAULT nDpi := 100

nDpi := 100

if ::lLoad
   cFarProc := GetProcAddress( ::hDLL, "TWAIN_SetResolution",.T., VOID,_DOUBLE )
   uResult  := CallDLL( cFarProc,nDpi )
end
RETU Self

METHOD Set(lShow)
// Show-Hide Scanner's Dialog Box
LOCAL nHide := 0      // Default: Shows Scanner's Dialog Box
LOCAL cFarProc
LOCAL uResult
DEFAULT lShow := .T.
if ::lLoad
   nHide := iif(lShow,0,1)
   cFarProc := GetProcAddress( ::hDLL, "TWAIN_SetHideUI",.T., VOID,_INT )
   uResult  := CallDLL( cFarProc,nHide )
end
RETU Self

METHOD Choose()
// Select Image Device Source
LOCAL cFarProc
LOCAL nResult
if ::lLoad
   cFarProc := GetProcAddress( ::hDLL, "TWAIN_SelectImageSource",.T., _INT,WORD )
   nResult  := CallDLL( cFarProc,::hWnd )
end

RETU Self


//-----------------------------------------

//---------- Protected Methods

   METHOD Free(hDib)
   // Release Dib's Handle
   LOCAL cFarProc
   LOCAL uResult
   cFarProc := GetProcAddress( ::hDLL, "TWAIN_FreeNative",.T., VOID,WORD )
   uResult  := CallDLL( cFarProc,hDib )
   RETU NIL

   METHOD DibToFile(hDib,cFile)
   // Write to File From DIB's handle
   LOCAL cFarProc
   LOCAL nResult
   LOCAL lRet
   cFarProc := GetProcAddress( ::hDLL, "TWAIN_WriteNativeToFilename",.T., _INT,WORD,LPSTR)
   lRet     := ( (nResult:=CallDLL( cFarProc,hDib,cFile ))==0 )
   DO CASE
      CASE nResult == -1
         MsgInfo("Annullato dall'utente","File non registrato")
      CASE nResult == -2
         MsgInfo("Errore durante la scrittura sul file "+cFile,"File non registrato")
      CASE nResult == -3
         MsgInfo("Errore interno sul file DIB","File non registrato")
      CASE nResult == -4
         MsgInfo("Errore durante la scrittura sul file "+cFile+", probabile spazio insufficiente sul disco !","File non registrato")
   ENDCASE
   RETU lRet

   METHOD IsActive()
   // Is Twain driver loaded ?
   LOCAL cFarProc
   LOCAL nResult
   cFarProc := GetProcAddress( ::hDLL, "TWAIN_IsAvailable",.T., _INT )
   if ! (nResult    := CallDLL( cFarProc )) == 1
      MsgAlert("Nessun driver per apparecchi TWAIN compatibili risulta disponibile !","Errore hardware")
      // Messaggio inviato direttamente da TWAIN.DLL
   end
   RETU iif(nResult==1,.T.,.F.)

   METHOD Register()
   // Register my application into Twain application
   LOCAL nMaiorNum := 1
   LOCAL nMinorNum := 0   // Result -> 1.0
   LOCAL nLanguage := 0
   LOCAL nCountry  := 0
   LOCAL cVersion  := "1.0"
   LOCAL cManifact := "The Genius"
   LOCAL cFamily   := "Digitizer"
   LOCAL cProduct := StrTran(cFileName(GetModuleFileName(GetInstance())),".EXE","")
   LOCAL cFarProc
   LOCAL uResult
   cFarProc := GetProcAddress( ::hDLL, "TWAIN_RegisterApp",.T.,;
                           VOID,_INT,_INT,_INT,_INT,LPSTR,LPSTR,LPSTR,LPSTR )
   uResult  := CallDLL( cFarProc,nMaiorNum,nMinorNum,nLanguage,nCountry,cVersion,cManifact,cFamily,cProduct )
   RETU NIL

//---------- END Protected Methods

STATIC FUNCTION BuildError(nError)
LOCAL cRet := "Errore nella libreria dinamica"
DO CASE
   CASE nError == 0
         cRet := "Memoria insufficiente ad eseguire il programma"
   CASE nError == 2
         cRet := "File non trovato"
   CASE nError == 3
         cRet := "Percorso non trovato"
   CASE nError == 5
         cRet := "Tentantivo di collegarsi dinamicamente ad un task o errore di condivisione"
   CASE nError == 6
         cRet := "La libreria richiede un segemento separato per ogni task"
   CASE nError == 8
         cRet := "Memoria insufficiente ad avviare l'applicazione"
   CASE nError == 10
         cRet := "Versione di MS Windows non corretta"
   CASE nError == 11
         cRet := "Libreria non valida oppure non Š un'applicazione MS Windows"
   CASE nError == 12
         cRet := "Applicazione disegnata per un sistema operativo diverso"
   CASE nError == 13
         cRet := "Applicazione disegnata per MS-DOS 4.0"
   CASE nError == 14
         cRet := "Tipo di file eseguibile sconosciuto"
   CASE nError == 15
         cRet := "Tentativo di caricare un'applicazione disegnata per funzionare in modalit… reale"
   CASE nError == 16
         cRet := "Tentativo di caricare una seconda istanza dell'applicazione contenente segmenti di dati multipli non marcati per la sola lettura"
ENDCASE
RETU OemToAnsi( cRet + "!" )

//------------------ Freeimage.dll ------------------------//
FUNCTION SaveImage( cFile )
LOCAL nFormat, hDib, hInfoH, hInfo, hBits, hWnd, hDC, hBmp, lOk

#ifdef __CLIPPER__
    hLib = LOADLIB32( "freeimage.dll" )
#else
    hLib = LOADLIBRARY( "freeimage.dll" )
#endif

    if hLib <= 32
        MsgStop( "Cannot load FreeImage.dll" )
        return 0
    endif

    nFormat := FIGETFILETYPE( cFile, 0 )
    hDib    := FILOAD( nFormat, cFile, 0 )
    hInfoH  := FIGETINFOHEADER( hDib )
    hInfo   := FIGETINFO( hDib )
    hBits   := FIGETBITS( hDib )
    hWnd    := GETDESKTOPWINDOW()

#ifdef __CLIPPER__
    hDC = GETDC32( hWnd )
#else
    hDC = GETDC( hWnd )
#endif

lOk := fiSave( 2 , hDib, cFile )

hBmp = CREATEDIBITMAP( hDC, hInfoH, CBM_INIT, hBits, hInfo, DIB_RGB_COLORS )

#ifdef __CLIPPER__
    RELEASEDC32( hWnd, hDC )
#else
    RELEASEDC( hWnd, hDC )
#endif

FIUNLOAD( hDib )

#ifdef __CLIPPER__
    FREELIB32( hLib )
#else
    FREELIBRARY( hLib )
#endif
RETURN hBmp



DLL32 STATIC FUNCTION FIGETFILETYPE( cFileName AS LPSTR, nSize AS LONG ) AS LONG;
      PASCAL FROM "_FreeImage_GetFileType@8" LIB hLib

DLL32 STATIC FUNCTION FILOAD( nFormat AS LONG, cFileName AS LPSTR, nFlags AS LONG ) AS LONG;
      PASCAL FROM "_FreeImage_Load@12" LIB hLib

DLL32 STATIC FUNCTION FIUNLOAD( hDib AS LONG ) AS VOID;
      PASCAL FROM "_FreeImage_Unload@4" LIB hLib

DLL32 STATIC FUNCTION FIGETINFOHEADER( hDib AS LONG ) AS LONG;
      PASCAL FROM "_FreeImage_GetInfoHeader@4" LIB hLib

DLL32 STATIC FUNCTION FIGETINFO( hDib AS LONG ) AS LONG;
      PASCAL FROM "_FreeImage_GetInfo@4" LIB hLib

DLL32 STATIC FUNCTION FIGETBITS( hDib AS LONG ) AS LONG;
      PASCAL FROM "_FreeImage_GetBits@4" LIB hLib

DLL32 STATIC FUNCTION FISAVE( nFormat AS LONG, hDib AS LONG, cFileName AS LPSTR, nFlags AS LONG ) AS BOOL;
      PASCAL FROM "_FreeImage_Save@16" LIB hLib

DLL32 STATIC FUNCTION FIROTATE( hDib AS LONG, nAngle AS _DOUBLE ) AS LONG;
      PASCAL FROM "_FreeImage_RotateClassic@12" LIB hLib

DLL32 STATIC FUNCTION GETDC32( hWnd AS LONG ) AS LONG;
      PASCAL FROM "GetDC" LIB "user32.dll"

DLL32 STATIC FUNCTION RELEASEDC32( hWnd AS LONG ) AS LONG;
      PASCAL FROM "ReleaseDC" LIB "user32.dll"

DLL32 STATIC FUNCTION CREATEDIBITMAP( hDC AS LONG, hInfoH AS LONG, nFlags AS LONG, hBits AS LONG, hInfo AS LONG, nUsage AS LONG ) AS LONG;
      PASCAL FROM "CreateDIBitmap" LIB "gdi32.dll"

DLL32 FUNCTION WOWHANDLE16( nHandle AS LONG, nHandleType AS LONG ) AS LONG;
      PASCAL FROM "WOWHandle16" LIB "wow32.dll"


//Declare Function TWAIN_AcquireToClipboard Lib "EZTW32.DLL" Alias "TWAIN_AcquireToClipboard" _
//      ( ByVal hwndApp as Long, ByVal wPixTypes as Dword ) as Long

DLL32 FUNCTION TWAIN_AcquireToClipboard (hwndApp As LONG, wPixTypes as CHAR );
    AS LONG PASCAL FROM TWAIN_AcquireToClipboard Lib "EZTW32.DLL"

/*
'  Like AcquireNative, but puts the resulting image, if any, into the system
'  clipboard.  Under Windows, this will put a CF_DIB item in the clipboard
'  if successful.  If this call fails, the clipboard is either empty or
'  contains the old contents.
'  A return value of 1 indicates success, 0 indicates failure.
'
'  Useful for environments like Visual Basic where it is hard to make direct
'  use of a DIB handle.  In fact, TWAIN_AcquireToClipboard uses
'  TWAIN_AcquireNative for all the hard work.
*/
George
 
Posts: 724
Joined: Tue Oct 18, 2005 6:49 pm

Postby jfafive » Sun Dec 14, 2008 11:22 pm

Ok, voy a compilarlo y a ver que resultado me dá.

Ya te comento.

Gracias George,

:wink:
jfafive
 
Posts: 396
Joined: Tue Mar 18, 2008 9:41 pm
Location: Marbella

Postby jfafive » Mon Dec 15, 2008 12:16 pm

Hola George,

Gracias, ya probé el metodo DigiToFile(...) y funcionó bien.
Pero he visto que por defecto, invoca al software que trae instalado el scaner.

¿hay alguna forma de evitar que llame al software del escaner para mostrar el escaneado? Lo que quiero es hacerme mi propio soft de escaneo en five y así no depender del software que trae el escaner.

Un saludo
:)
jfafive
 
Posts: 396
Joined: Tue Mar 18, 2008 9:41 pm
Location: Marbella

Postby jfafive » Mon Dec 15, 2008 11:35 pm

Hola de nuevo!

Por cierto, ¿alguien sabe si se puede escanear directamente a PDF?
Estoy usando la clase TScan de L.Gadaleta.

:roll:
jfafive
 
Posts: 396
Joined: Tue Mar 18, 2008 9:41 pm
Location: Marbella

Postby JoseLuis » Tue Dec 16, 2008 8:30 am

Hola

Estoy intentando compilar la clase de L.Gadeta que habeis posteado, y me da los siguientes warnings
    C:\NUEVAS_CLASES\Tscan32\SAMPLES\Scanner\scanner.prg(149) Warning W0001 Ambiguous reference: 'NRES'
    C:\NUEVAS_CLASES\Tscan32\SAMPLES\Scanner\scanner.prg(150) Warning W0001 Ambiguous reference: 'NRES'
    C:\NUEVAS_CLASES\Tscan32\SAMPLES\Scanner\scanner.prg(380) Warning W0001 Ambiguous reference: 'TWAIN_ACQUIRETOCLIPBOARD'
    C:\NUEVAS_CLASES\Tscan32\SAMPLES\Scanner\scanner.prg(380) Warning W0001 Ambiguous reference: 'TWAIN_ACQUIRETOCLIPBOARD'


El primero, que hace referencia a nRes, supongo que es que no se ha declarado ésta variable en el método DigitoClip(), pero el segundo, el que hace referencia a 'TWAIN_ACQUIRETOCLIPBOARD' no se como se puede corregir.

Saludos

Jose Luis
JoseLuis
 
Posts: 426
Joined: Thu Oct 19, 2006 12:28 pm
Location: Toledo

Postby jfafive » Tue Dec 16, 2008 2:38 pm

Hola JoseLuis,

Lo ciertyo es que a mí tambien me da esos Warnings. Pero de momento la estoy usando sin prestarles mucha atención.

Siento no poder ayudarte.
jfafive
 
Posts: 396
Joined: Tue Mar 18, 2008 9:41 pm
Location: Marbella

Postby George » Tue Dec 16, 2008 7:05 pm

Con relacion a los "warnings" si declaran las variables no salen los warnings. De todo modos son solos "warnings" y no afectan la ejecucion de programa.

Con relacion al formato PDF, pienso se podria usar un sofware externo convertidor (BMPtoPDF) y llamarlo desde tu programa.
Otra opcion mejor, y es la yo uso ahora, es el OCX 'TwainControlX" de la empresa http://www.ciansoft.com/ este trabaja perfecto y te permite salvar los graficos en formato PDF y mas. Ademas te permite scanear multiple paginas. Si lo quieren probar tienen un demo totalmente funcional en el website mas arriba mencionado.

Saludos,


George
George
 
Posts: 724
Joined: Tue Oct 18, 2005 6:49 pm

Postby George » Tue Dec 16, 2008 7:15 pm

Jfafive,

El metodo Choose() debe presentarte una lista de todos los scanners instalados en tu computador y te permite elegir el de tu agrado con el software asociado al mismo.
En el caso de desarrollar tu propio programa (o clase) para escanear asociado a diferentes tipos de scanners, (lo cual es factible y de verdad que me gustaria verlo si tu nos lo quisiera mostrar), me supongo que deberia aparecer en la lista del metodo Choose(); pero no se como le haria para que llame tu software por "default".

George
George
 
Posts: 724
Joined: Tue Oct 18, 2005 6:49 pm

Postby jfafive » Tue Dec 16, 2008 7:43 pm

Gracias por la información George

:)
jfafive
 
Posts: 396
Joined: Tue Mar 18, 2008 9:41 pm
Location: Marbella

Postby jfafive » Tue Dec 16, 2008 9:18 pm

George,

el OCX 'TwainControlX' que usas...
¿podrias pasarme un ejemplo de como lo invocas desde FWH?
Ya que en la documentación solo hace referencia a ejemplos en VB o VBScript.

:?
jfafive
 
Posts: 396
Joined: Tue Mar 18, 2008 9:41 pm
Location: Marbella

Postby George » Tue Dec 16, 2008 10:55 pm

Code: Select all  Expand view
FUNCTION ScanOCX2(cFilename)
      oScan := TOleAuto():New("TwainControlX.Twain") // Aqui va el OCX "demo" que tu bajaste del website
      oScan:Password := "AQUI VA TU PASSWORD" // No lo necesitas en la version de evaluacion
      oScan:SelectDevice()
      oScan:Acquire()
      oScan:SaveToFile( cFileName )
RETURN (.T.)



George
George
 
Posts: 724
Joined: Tue Oct 18, 2005 6:49 pm

Next

Return to FiveWin para Harbour/xHarbour

Who is online

Users browsing this forum: Google [Bot] and 81 guests