FiveTech Support Forums

FiveWin / Harbour / xBase community
Board index FiveWin for Harbour/xHarbour Twain with TScan
Posts: 408
Joined: Sun Nov 06, 2005 03:55 PM
Twain with TScan
Posted: Tue May 29, 2012 05:23 PM

Anybody had the need to utilize the Automatic Border Detection, or Automatic DeSkew when utilizing the Twain interface. I believe my scanner is capable but I cannot find a way to set this up with the TScan32 class.
I also have found that the oScan:SetContrats(nMyValue), and oScan:SetBright(nMyOtherValue) seems to have no effect on the end result no matter what value passed, but in the program that comes with the scanner it greatly effects the image.

Thanks,

Byron ...

Thanks,

Byron Hopp

Matrix Computer Services
Posts: 990
Joined: Thu Nov 17, 2005 05:49 PM
Re: Twain with TScan
Posted: Tue May 29, 2012 10:55 PM
Byron;

Hi. Last I checked you had to purchase the professional Eztwain32 version in order to get the autocrop functions. I have some home-grown code that seems to be working, but I haven't test it well enough. Maybe you can test it, fix or enhance it and return the improvements?

The code below uses Tscan32 from Rafa. It scans and optionally auto-crops the image. It works well to scan a driver's license. Please send me back any fixes.

Thank you,


Code (fw): Select all Collapse
//------------------------------------------------------------------------------
FUNCTION scanning_x( oBmp, lAutoCrop, cFileOrg )
   LOCAL cFileDes := temp_name( "jpg" )
   LOCAL oScan
   LOCAL lResult := .F.
   LOCAL aCoor

    DEFAULT cFileOrg := temp_name( "jpg" )
   DEFAULT lAutoCrop := .T.

   TRY

      oScan := TScan32():New( cFileOrg )

      IF !oScan:lError

         oScan:SetHide( lAutoCrop )
         oScan:Acquire()
         oScan:DibToJpeg( cFileOrg )

         IF lAutoCrop .and. !EMPTY( oScan:hDib )
            aCoor := getCropArea( cFileOrg ) //nTop, nBottom, nLeft, nRight

            IF aCoor[1] = aCoor[3]
               lResult := .F.
            ELSE
               cropImage( cFileOrg, aCoor[3], aCoor[1], aCoor[4], aCoor[2], cFileDes )
               oBmp:LoadBmp( cFileDes )
               oBmp:Refresh()
               lResult := .T.
            ENDIF
         ELSEIF !EMPTY( oScan:hDib )
            oBmp:LoadBmp( cFileOrg )
            oBmp:Refresh()
            lResult := .T.
         ENDIF

      ENDIF

   CATCH

      MsgStop( "Scanner not responding" )
      cFileDes := ""
      lResult := .F.

   FINALLY 

      oScan:End()

   END

RETURN iif( lResult, cFileDes, "" )

//------------------------------------------------------------------------------
FUNCTION getCropArea( cNameIn )
   LOCAL hBmp   := FiLoadImg( cNameIn ) //oImage:hBitmap
   LOCAL hDc    := GetDc(hBmp)
   local hDCMem := CreateCompatibleDC( hDC )
   local hOldBmp:= SelectObject( hDCMem, hBmp )
   local nX     := nBmpWidth( hBmp ) //oImage:nWidth
   local nY     := nBmpHeight( hBmp ) //oImage:nHeight
   local x, y, p, n
   local nTop, nLeft, nRight, nBottom

   local maxX   := 10 //nX / 10 // 10%
   local maxY   := 10 //nY / 10  // 10%
   local nBlank
   local nStep := 5

   nBlank := getBackGround( hDcMem, nX, nY )

   // TOP
   y := 20 //0
   DO WHILE y <= nY - 1
       n := 0
       FOR x := 0 TO nX - 10 STEP nStep
           p := GetPixel(hDcMem, x, y)
           IF( p < nBlank, n++, )
       NEXT
       IF n  > maxX
          nTop := y
          y := nY
       ENDIF
       y++
   ENDDO

   IF y = nY
      MSGALERT( 'No information' )
      RETURN {0,0,0,0}
   ENDIF

   // BOTTOM
   y :=  nY - 20 //nY   - 1
   DO WHILE y >= 0
       n := 0
       FOR x := 0 TO nX - 10  STEP nStep
           p := GetPixel(hDcMem, x, y)
           IF( p < nBlank, n++, )
       NEXT
       IF n  > maxX
          nBottom := y
          y := 0
       ENDIF
       y--
   ENDDO

   // LEFT
   x := 20 //0
   DO WHILE x <= nX - 1
       n := 0
       FOR y := 0 TO nY - 10  STEP nStep
           p := GetPixel(hDcMem, x, y)
           IF( p < nBlank, n++, )
       NEXT
       IF n  > maxY
          nLeft := x
          x := nX
       ENDIF
       x++
   ENDDO

   // RIGHT
   x := nX - 10 //nX - 1
   DO WHILE x >= 0
       n := 0
       FOR y := 0 TO nY - 10   STEP nStep
           p := GetPixel(hDcMem, x, y)
           IF( p < nBlank, n++, )
       NEXT
       IF n  > maxY
          nRight := x
          x := 0
       ENDIF
       x--
   ENDDO

   /*
   oImage:line( nTop, nLeft, nTop, nRight )
   oImage:line( nTop, nRight, nBottom, nRight )
   oImage:line( nBottom, nRight, nBottom, nLeft )
   oImage:line( nBottom, nLeft, nTop, nLeft )
   */

   SelectObject( hDCMem, hOldBmp )
   DeleteDC( hDCMem )

return  { nTop - 10 , nBottom + 10, nLeft - 10, nRight + 10 }

// Finds background color to be compared with scanning area
//------------------------------------------------------------------------------
STATIC FUNCTION getBackGround( hDcMem, nX, nY )
LOCAL x,y,n, al := {} , nStep := 4

n := 0
FOR y :=  20 TO nY -20  STEP nStep
    n += GetPixel(hDcMem, 20, y)
NEXT
AADD( al, INT(n / ( nY / nStep ) ) )

n := 0
FOR y := 20 TO nY -20  STEP nStep
    n += GetPixel(hDcMem, nX-20, y)
NEXT
AADD(al,  INT(n / ( nY / nStep ) ) )

n := 0
FOR x := 20 TO nX -20  STEP nStep
    n += GetPixel(hDcMem, x, 20)
NEXT
AADD( al, INT(n / ( nX / nSTep ) ) )

n := 0
FOR x := 20 TO nX -20  STEP nStep
    n += GetPixel(hDcMem, x, nY-20)
NEXT
AADD( al, INT(n / ( nX / nStep ) ) )

al := ASORT( al )

RETURN INT( al[4] * .95 )


FUNCTION cropImage( cSrcFile, nLeft, nTop, nRight, nBottom ,cDstFile )

   hLib = LOADLIB32( "freeimage.dll" )

//nSrcFormat = FIGETFILETYPE( cSrcFile, 0 )
//hDib = FILOAD( nSrcFormat, cSrcFile, )
//hDib2 = FICOPY( hDib, nLeft, nTop, nRight, nBottom  )
//FISAVE( nSrcFormat, hDib2, cDstFile, 0 )

   FI_JPGCROP( cSrcFile, cDstFile, nLeft, nTop, nRight, nBottom )

   FREELIBRARY( hLib )

return Nil

DLL32 STATIC FUNCTION FICOPY( hDib AS LONG, nLeft AS LONG, nTop AS LONG,nRight AS LONG,nBottom AS LONG ) AS LONG;
PASCAL FROM "_FreeImage_Copy@20" 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 FUNCTION FI_JpgCrop( cSource AS LPSTR, ;
                     cDest AS LPSTR, ;
                     nLeft AS LONG, ;
                     nTop AS LONG, ;
                     nRight AS LONG, ;
                     nBottom AS LONG ) AS BOOL ;
PASCAL FROM "_FreeImage_JPEGCrop@24" LIB hLib

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


Reinaldo.

Continue the discussion