Using EZTwain Classic (free) I made my own. I added the ability to scan to PNG and to JPG. I needed this in order to use PurePDF.
I hope someone finds it useful.
Code for Scan2PDF program
Code: Select all
;Scan2PDF
;by Harkon
;written under PureBasic 4.41
;
;requires:
; EZTW32.dll
; EZTwain.pbi ans needs EZTW32.LIB
; both are available for download at http://www.dosadi.com/
; as EZTwain Classic (this is a free download)
; PurePDF by ABBKlaus (appropriate version at http://www.purebasicpower.de/?PurePDF)
; sanner.ico for the .exe
IncludeFile "EZTwain.pbi"
EnableExplicit
;- Window Constants
;
Enumeration
#Window_Scan2PDF
EndEnumeration
;- Gadget Constants
Enumeration
#Combo_ImageType
#Combo_ImageQuality
#Text_ImageType
#Text_ImageQuality
#Text_Header
#Text_FileLocation
#Text_Location
#Button_Browse
#Button_ScanNext
#Button_Finish
#Button_Cancel
EndEnumeration
;- Fonts
Global lFontID1.l
lFontID1 = LoadFont(1, "Arial", 48, #PB_Font_Bold | #PB_Font_Italic)
;Variable defs
Define sPdfFileName.s
Define lQuality.l
Define lEvent.l
Define lWindowID.l
Define lGadgetID.l
Define lEventType.l
Procedure Open_Window_Scan2PDF()
If OpenWindow(#Window_Scan2PDF, 268, 51, 378, 431, "Scan2PDF", #PB_Window_SystemMenu | #PB_Window_SizeGadget | #PB_Window_TitleBar )
ComboBoxGadget(#Combo_ImageType, 160, 120, 110, 20)
ComboBoxGadget(#Combo_ImageQuality, 160, 150, 110, 20)
TextGadget(#Text_ImageType, 50, 120, 90, 20, "Image Type:")
TextGadget(#Text_ImageQuality, 50, 150, 90, 20, "Image Quality:")
TextGadget(#Text_Header, 20, 10, 340, 80, "Scan2PDF")
SetGadgetFont(#Text_Header, lFontID1)
TextGadget(#Text_FileLocation, 10, 230, 340, 40, "", #PB_Text_Border)
TextGadget(#Text_Location, 10, 210, 160, 20, "PDF File Destination Location:")
ButtonGadget(#Button_Browse, 350, 250, 20, 20, "...")
ButtonGadget(#Button_ScanNext, 90, 300, 90, 30, "Scan First Page")
ButtonGadget(#Button_Finish, 200, 300, 90, 30, "Finish")
ButtonGadget(#Button_Cancel, 120, 350, 150, 30, "Cancel / Close Program")
EndIf
EndProcedure
Procedure.l hkTWAIN_AquireToPDF(wPixTypes.l, dResolution.d)
Static PDFStarted.l
Static PageNumber.l
Define hDib.l
Define sTempFileName.s
If TWAIN_State()=#TWAIN_SOURCE_OPEN
TWAIN_OpenDefaultSource()
EndIf
If Not TWAIN_GetHideUI()
TWAIN_SetHideUI(1)
EndIf
TWAIN_SetCurrentResolution(dResolution)
hDib=TWAIN_AcquireNative(0, wPixTypes)
If hDib
PageNumber+1
sTempFileName=GetTemporaryDirectory() + "tempscan" + RSet(Str(PageNumber),3,"0") + ".png"
hkTWAIN_WriteNativeToPNG(hdib, sTempFileName)
TWAIN_FreeNative(hDib)
If Not PDFStarted
pdf_Create("P", "in", #PDF_PAGE_FORMAT_LETTER)
pdf_SetTitle("Scan")
PDFStarted=1
EndIf
pdf_AddPage("P", #PDF_PAGE_FORMAT_LETTER)
pdf_Image(sTempFileName, 0, 0, 8.5, 0)
DeleteFile(sTempFileName)
;- replace this code with in window code
SetGadgetText(#Button_ScanNext, "Scan Page #" + Str(PageNumber+1))
ProcedureReturn 1
EndIf
ProcedureReturn 0
EndProcedure
;before we actually do anything let's make sure the app isn't already running
If CreateMutex_(0,1,"Scan2PDF")=0 Or GetLastError_()<>0 : End : EndIf
Open_Window_Scan2PDF()
;- Startupcode
If Not TWAIN_IsAvailable()
MessageRequester("Scan2PDF", "TWAIN scanner interface is not available!")
End
EndIf
; populate combo boxes
If Not OpenPreferences("Scan2PDF.cfg")
MessageRequester("Scan2PDF", "Could not find preferences file, using default values")
EndIf
AddGadgetItem(#Combo_ImageType, -1, "Black & White")
AddGadgetItem(#Combo_ImageType, -1, "GrayScale")
AddGadgetItem(#Combo_ImageType, -1, "Color (Photo)")
AddGadgetItem(#Combo_ImageQuality,-1, " 75 dpi")
AddGadgetItem(#Combo_ImageQuality,-1, " 100 dpi")
AddGadgetItem(#Combo_ImageQuality,-1, " 150 dpi")
AddGadgetItem(#Combo_ImageQuality,-1, " 300 dpi")
AddGadgetItem(#Combo_ImageQuality,-1, " 600 dpi")
AddGadgetItem(#Combo_ImageQuality,-1, "1200 dpi")
; initialize gadgets
SetGadgetState(#Combo_ImageType, ReadPreferenceInteger("Color Index", 2))
SetGadgetState(#Combo_ImageQuality, ReadPreferenceInteger("Quality Index", 0))
SetGadgetText(#Text_FileLocation, ReadPreferenceString("Destination File",""))
; disable finish button until we actually have a page to save
DisableGadget(#Button_Finish, 1)
Repeat ; Start of the event loop
lEvent = WaitWindowEvent() ; This line waits until an event is received from Windows
lWindowID = EventWindow() ; The Window where the event is generated, can be used in the gadget procedures
lGadgetID = EventGadget() ; Is it a gadget event?
lEventType = EventType() ; The event type
If lEvent = #PB_Event_Gadget
If lGadgetID = #Combo_ImageType
ElseIf lGadgetID = #Combo_ImageQuality
ElseIf lGadgetID = #Button_Browse
;user can select default file destination here
sPdfFileName=GetGadgetText(#Text_FileLocation)
If sPdfFileName=""
sPdfFileName=SaveFileRequester("Save PDF file",GetHomeDirectory()+"My Documents\","PDF (*.pdf)|*.pdf",0)
Else
sPdfFileName=SaveFileRequester("Save PDF file",sPdfFileName,"PDF (*.pdf)|*.pdf",0)
EndIf
If LCase(GetExtensionPart(sPdfFileName))<> "pdf"
sPdfFileName + ".pdf"
EndIf
SetGadgetText(#Text_FileLocation, sPdfFileName)
ElseIf lGadgetID = #Button_ScanNext
;get dpi for page here
;color dep[th is in order of index+1
Select GetGadgetState(#Combo_ImageQuality)
Case 0
lQuality=75
Case 1
lQuality=100
Case 2
lQuality=150
Case 3
lQuality=300
Case 4
lQuality=600
Case 5
lQuality=1200
Default
lQuality=75
EndSelect
DisableGadget(#Button_ScanNext, 1)
If hkTWAIN_AquireToPDF(GetGadgetState(#Combo_ImageType) + 1, lQuality)
;we have at least one page to save so enable the finish button
DisableGadget(#Button_Finish, 0)
EndIf
DisableGadget(#Button_ScanNext, 0)
ElseIf lGadgetID = #Button_Finish
;finalize and save pdf file
sPdfFileName=GetGadgetText(#Text_FileLocation)
If sPdfFileName=""
sPdfFileName.s=SaveFileRequester("Save PDF file",GetHomeDirectory()+"My Documents\","PDF (*.pdf)|*.pdf",0)
If LCase(GetExtensionPart(sPdfFileName))<> "pdf"
sPdfFileName+".pdf"
EndIf
SetGadgetText(#Text_FileLocation, sPdfFileName)
EndIf
sPdfFileName=SaveFileRequester("Save PDF file",sPdfFileName,"PDF (*.pdf)|*.pdf",0)
If sPdfFileName
pdf_Save(GetGadgetText(#Text_FileLocation))
EndIf
ElseIf lGadgetID = #Button_Cancel
lEvent = #PB_Event_CloseWindow
EndIf
EndIf
Until lEvent = #PB_Event_CloseWindow ; End of the event loop
;save preferences on exit
If CreatePreferences("Scan2PDF.cfg")
WritePreferenceInteger("Color Index", GetGadgetState(#Combo_ImageType))
WritePreferenceInteger("Quality Index", GetGadgetState(#Combo_ImageQuality))
WritePreferenceString("Destination File", GetGadgetText(#Text_FileLocation))
ClosePreferences()
Else
MessageRequester("Scan2PDF", "Could not save program preferences")
EndIf
End
Code: Select all
EnableExplicit
; XDefs translation of \EZTwain\VC\eztwain.h
;-----------------------------------------------------------------
; EZTWAIN.H - interface to Easy TWAIN library
; (DLL=eztw32.dll)
;
; 1.15 2006.05.09 Fix: If user closed the scan dialog during an Acquire,
; the last DIB handle, if any, was returned!
; Added VB\Eztwain.bas to package.
; 1.14 2004.08.06 Set XFERMECH=NATIVE as soon as DS is opened.
; trying to deal with scanners that default to memory xfer.
; 1.13 1999.09.08 Documented correct return codes of AcquireToFilename.
; - No code changes -
; 1.12 1998.09.14 Added Fix32ToFloat, allow MSG_OPENDS triplet.
; Added SetXferMech, XferMech.
; 1.11 1998.08.17 Added ToFix32, SetContrast, SetBrightness.
; Modified TWAIN_ToFix32 to round away-from-zero.
; 1.09beta 1998.07.27 Reverted from 1.08 to 1.06 and worked forward again.
; 1.06 1997.08.21 correction to message hook, fixed 32-bit exports
; 1.05 1996.11.06 32-bit conversion
; 1.04 1995.05.03 added: WriteNativeToFile, WriteNativeToFilename,
; FreeNative, SetHideUI, GetHideUI, SetCurrentUnits,
; GetCurrentUnits, SetCurrentResolution, SetBitDepth,
; SetCurrentPixelType, SetCapOneValue.
; 1.0a 1994.06.23 first alpha version
; 0.0 1994.05.11 created
;
; EZTWAIN 1.x is not a product, and is not the work of any company involved
; in promoting or using the TWAIN standard. This code is sample code,
; provided without charge, and you use it entirely at your own risk.
; No rights or ownership is claimed by the author, or by any company
; or organization. There are no restrictions on use or (re)distribution.
;
; Download from: www.dosadi.com
;
; Support contact: support@dosadi.com
;
; PB include file for EZTwain
; Ported from VB source by Harkon
; provided by the good people at EZTwain www.dosadi.com
; Use these values for wPixTypes
#TWAIN_BW=1
#TWAIN_GRAY=2
#TWAIN_RGB=4
#TWAIN_PALETTE=8
#TWAIN_ANYTYPE=0
;Use these for TWAIN_State
#TWAIN_PRESESSION = 1
#TWAIN_SM_LOADED = 2
#TWAIN_SM_OPEN = 3
#TWAIN_SOURCE_OPEN = 4
#TWAIN_SOURCE_ENABLED = 5
#TWAIN_TRANSFER_READY = 6
#TWAIN_TRANSFERRING = 7
;use these for Xtransfer Mode
#TWAIN_XFERMECH_NATIVE = 0
#TWAIN_XFERMECH_FILE = 1
#TWAIN_XFERMECH_MEMORY = 2
Import "EZTW32.LIB"
TWAIN_AcquireNative.l(hwndApp.l, wPixTypes.l) As "_TWAIN_AcquireNative@8"
; The minimal use of EZTWAIN.DLL is to just call this routine, with 0 for
; both params. EZTWAIN creates a window if hwndApp is 0.
;
; Acquires a single image, from the currently selected Data Source, using
; Native-mode transfer. It waits until the source closes (if it's modal) Or
; forces the source closed if not. The return value is a handle to the
; acquired image. Only one image can be acquired per call.
;
; Under Windows, the return value is a global memory handle - applying
; GlobalLock to it will return a (huge) pointer to the DIB, which
; starts with a BITMAPINFOHEADER.
; NOTE: You are responsible for disposing of the returned DIB - these things
; can eat up your Windows memory fast! See TWAIN_FreeNative below.
;
; The image type can be restricted using the following masks. A mask of 0
; means 'any pixel type is welcome'.
; Caution: You should not assume that the source will honor a pixel type
; restriction! If you care, check the parameters of the DIB.
TWAIN_FreeNative(hdib.l) As "_TWAIN_FreeNative@4"
; Release the memory allocated to a native format image, as returned by
; TWAIN_AcquireNative. (If you are coding in C or C++, this is just a call
; to GlobalFree.)
; If you use TWAIN_AcquireNative and don't free the returned image handle,
; it stays around taking up Windows (virtual) memory until your application
; terminates. Memory required per square inch:
; 1 bit B&W 8-bit grayscale 24-bit color
; 100 dpi 1.25KB 10KB 30KB
; 200 dpi 5KB 40KB 120KB
; 300 dpi 11.25KB 90KB 270KB
; 400 dpi 20KB 160KB 480KB
;
TWAIN_AcquireToClipboard.l(hwndApp.l, wPixTypes.l) As "_TWAIN_AcquireToClipboard@8"
; 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.
TWAIN_AquireToFilename.l(hwndApp.l, sFile.s) As "_TWAIN_AcquireToFilename@8"
; Acquire an image and write it to a .BMP (Windows Bitmap) file.
; The file name and path in pszFile are used. If pszFile is NULL or
; points to an empty string, the user is prompted with a Save File dialog.
; Return values:
; 0 success
; -1 Acquire failed OR user cancelled File Save dialog
; -2 file open error (invalid path or name, or access denied)
; -3 (weird) unable to lock DIB - probably an invalid handle.
; -4 writing BMP data failed, possibly output device is full
TWAIN_SelectImageSource.l(hwnd.l) As "_TWAIN_SelectImageSource@4"
; This is the routine to call when the user chooses the "Select Source..."
; menu command from your application's File menu. Your app has one of
; these, right? The TWAIN spec calls for this feature to be available in
; your user interface, preferably as described.
; Note: If only one TWAIN device is installed on a system, it is selected
; automatically, so there is no need for the user to do Select Source.
; You should not require your users to do Select Source before Acquire.
; '
; This function posts the Source Manager's Select Source dialog box.
; It returns after the user either OK's Or CANCEL's that dialog.
; A return of 1 indicates OK, 0 indicates one of the following:
; a) The user cancelled the dialog
; b) The Source Manager found no data sources installed
; c) There was a failure before the Select Source dialog could be posted
; -- details --
; Only sources that can return images (that are in the DG_IMAGE group) are
; displayed. The current default source will be highlighted initially.
; In the standard implementation of "Select Source...", your application
; doesn't need To do anything except make this one call.
; '
; If you want to be meticulous, disable your "Acquire" and "Select Source"
; menu items or buttons if TWAIN_IsAvailable() returns 0 - see below.
; --- TWAIN Basic Inquiries ---
TWAIN_IsAvailable.l() As "_TWAIN_IsAvailable@0"
; Call this function any time to find out if TWAIN is installed on the
; system. It takes a little time on the first call, after that it's fast,
; just testing a flag. It returns 1 if the TWAIN Source Manager is
; installed & can be loaded, 0 otherwise.
TWAIN_EasyVersion.l() As "_TWAIN_EasyVersion@0"
; Returns the version number of EZTWAIN.DLL, multiplied by 100.
; So e.g. version 2.01 will return 201 from this call.
TWAIN_State.l() As "_TWAIN_State@0"
;Returns the TWAIN Protocol State per the spec.
; --- DIB Handling ___
TWAIN_DibDepth.l(hdib.l) As "_TWAIN_DibDepth@4"
; Depth of DIB, in bits i.e. bits per pixel.
TWAIN_DibWidth.l(hdib.l) As "_TWAIN_DibWidth@4"
; Width of DIB, in pixels (columns)
TWAIN_DibHeight.l(hdib.l) As "_TWAIN_DibHeight@4"
; Height of DIB, in lines (rows)
TWAIN_DibNumColors.l(hdib) As "_TWAIN_DibNumColors@4"
; Number of colors in color table of DIB
DIB_RowBytes.l(hdib.l) As "_DIB_RowBytes@4"
; Number of bytes consumed by one row
DIB_ReadRow(hdib.l, nRow.l, *prow) As "_DIB_ReadRow@12"
; Read row n of the given DIB into buffer at prow.
; Caller is responsible for ensuring buffer is large enough.
; Row 0 is the *top* row of the image, as it would be displayed.
TWAIN_CreateDibPalette.l(hdib.l) As "_TWAIN_CreateDibPalette@4"
; Create and return a logical palette to be used for drawing the DIB.
; For 1, 4, and 8-bit DIBs the palette contains the DIB color table.
; For 24-bit DIBs, a default halftone palette is returned.
TWAIN_DrawDibToDC(hDC.l, dx.l, dy.l, w.l, h.l, hdib.l, sx.l, sy.l) As "_TWAIN_DrawDibToDC@32"
; Draws a DIB on a device context.
; You should call CreateDibPalette, select that palette
; into the DC, and do a RealizePalette(hDC) first.
; --- BMP File Utilities ---
TWAIN_WriteNativeToFilename.l(hdib.l, sFile.s) As "_TWAIN_WriteNativeToFilename@8"
; Writes a DIB handle to a .BMP file
;
; hdib = DIB handle, as returned by TWAIN_AcquireNative
; pszFile = far pointer to NUL-terminated filename
; If pszFile is NULL or points to a null string, prompts the user
; for the filename with a standard file-save dialog.
;
; Return values:
; 0 success
; -1 user cancelled File Save dialog
; -2 file open error (invalid path or name, or access denied)
; -3 (weird) unable to lock DIB - probably an invalid handle.
; -4 writing BMP data failed, possibly output device is full
TWAIN_WriteNativeToFile.l(hdib.l, fh.l) As "_TWAIN_WriteNativeToFile@8"
; Writes a DIB to a file in .BMP format.
;
; hdib = DIB handle, as returned by TWAIN_AcquireNative
; fh = file handle, as returned by _open, _lopen or OpenFile
;
; Return value as for TWAIN_WriteNativeToFilename
TWAIN_LoadNativeFromFilename.l(sFile.s) As "_TWAIN_LoadNativeFromFilename@4"
; Load a .BMP file and return a DIB handle (as from AcquireNative.)
; Accepts a filename (including path & extension).
; If pszFile is NULL or points to a null string, the user is prompted.
; Returns a DIB handle if successful, otherwise NULL.
TWAIN_LoadNativeFromFile.l(fh.l) As "_TWAIN_LoadNativeFromFile@4"
; Like LoadNativeFromFilename, but takes an already open file handle.
TWAIN_SetHideUI(fHide.l) As "_TWAIN_SetHideUI@4"
TWAIN_GetHideUI.l() As "_TWAIN_GetHideUI@0"
; These functions control the 'hide source user Interface' flag.
; This flag is cleared initially, but if you set it non-zero, then when
; a source is enabled it will be asked to hide its user interface.
; Note that this is only a request - some sources will ignore it!
; This affects AcquireNative, AcquireToClipboard, and EnableSource.
; If the user interface is hidden, you will probably want to set at least
; some of the basic acquisition parameters yourself - see
; SetCurrentUnits, SetBitDepth, SetCurrentPixelType and
; SetCurrentResolution below.
; --- Appliucation Registration ---
TWAIN_RegisterApp(nMajorNum.l, nMinorNum.l, nLanguage.l, nCountry.l, lpszVersion.s, lpszMfg.s, lpszFamily.s, lpszProduct.s) As "_TWAIN_RegisterApp@32"
; TWAIN_RegisterApp can be called *AS THE FIRST CALL*, to register the
; application. If this function is not called, the application is given a
; 'generic' registration by EZTWAIN.
; Registration only provides this information to the Source Manager and any
; sources you may open - it is used for debugging, and (frankly) by some
; sources to give special treatment to certain applications.
; --- Error Analysis and Reporting ---
TWAIN_GetResultCode.l() As "_TWAIN_GetResultCode@0"
; Return the result code (TWRC_xxx) from the last triplet sent to TWAIN
TWAIN_GetConditionCode.l() As "_TWAIN_GetConditionCode@0"
; Return the condition code from the last triplet sent to TWAIN.
; (To be precise, from the last call to TWAIN_DS below)
TWAIN_ErrorBox(sMsg.s) As "_TWAIN_ErrorBox@4"
; Post an error message dialog with an exclamation mark, OK button,
; and the title 'TWAIN Error'.
; pszMsg points to a null-terminated message string.
TWAIN_ReportLastError(sMsg.s) As "_TWAIN_ReportLastError@4"
; Like TWAIN_ErrorBox, but if some details are available from
; TWAIN about the last failure, they are included in the message box.
; --- TWAIN State Control ---
TWAIN_LoadSourceManager.l() As "_TWAIN_LoadSourceManager@0"
; Finds and loads the Data Source Manager, TWAIN.DLL.
; If Source Manager is already loaded, does nothing and returns TRUE.
; This can fail if TWAIN.DLL is not installed (in the right place), or
; if the library cannot load for some reason (insufficient memory?) or
; if TWAIN.DLL has been corrupted.
TWAIN_OpenSourceManager.l(hwnd.l) As "_TWAIN_OpenSourceManager@4"
; Opens the Data Source Manager, if not already open.
; If the Source Manager is already open, does nothing and returns TRUE.
; This call will fail if the Source Manager is not loaded.
TWAIN_OpenDefaultSource.l() As "_TWAIN_OpenDefaultSource@0"
; This opens the source selected in the Select Source dialog.
; If a source is already open, does nothing and returns TRUE.
; Fails if the source manager is not loaded and open.
TWAIN_EnableSource.l(hwnd.l) As "_TWAIN_EnableSource@4"
; Enables the open Data Source. This posts the source's user Interface
; And allows image acquisition To begin. If the source is already enabled,
; this call does nothing And returns TRUE.
TWAIN_DisableSource .l() As "_TWAIN_DisableSource@0"
; Disables the open Data Source, if any.
; This closes the source's user Interface.
; If there is Not an enabled source, does nothing And returns TRUE.
TWAIN_CloseSource.l() As "_TWAIN_CloseSource@0"
; Closes the open Data Source, if any.
; If the source is enabled, disables it first.
; If there is Not an open source, does nothing And returns TRUE.
TWAIN_CloseSourceManager.l(hwnd.l) As "_TWAIN_CloseSourceManager@4"
; Closes the Data Source Manager, If it is open.
; If a source is open, disables And closes it As needed.
; If the Source Manager is Not open, does nothing And returns TRUE.
TWAIN_UnloadSourceManager.l() As "_TWAIN_UnloadSourceManager@0"
; Unloads the Data Source Manager i.e. TWAIN.DLL - releasing
; any associated memory Or resources.
; This call will fail If the Source Manager is open, otherwise
; it always succeeds And returns TRUE.
TWAIN_WaitForNativeXfer.l(hwnd.l) As "_TWAIN_WaitForNativeXfer@4"
TWAIN_ModalEventLoop() As "_TWAIN_ModalEventLoop@0"
; Process messages Until termination, source disable, Or image transfer.
TWAIN_EndXfer.l() As "_TWAIN_EndXfer@0"
TWAIN_AbortAllPendingXfers.l() As "_TWAIN_AbortAllPendingXfers@0"
; --- High-level Capability Negotiation Functions ---
TWAIN_NegotiateXferCount.l(nXfers.l) As "_TWAIN_NegotiateXferCount@4"
; Negotiate With open Source the number of images application will accept.
; This is only allowed in State 4 (TWAIN_SOURCE_OPEN)
; nXfers = -1 means any number
TWAIN_NegotiatePixelTypes.l(wPixTypes.l) As "_TWAIN_NegotiatePixelTypes@4"
; Negotiate with the source to restrict pixel types that can be acquired.
; This tries To restrict the source To a *set* of pixel types,
; See TWAIN_AcquireNative above For some mask constants.
; --> This is only allowed in State 4 (TWAIN_SOURCE_OPEN)
; A parameter of 0 (TWAIN_ANYTYPE) causes no negotiation & no restriction.
; You should Not assume that the source will honor your restrictions, even
; If this call succeeds!
TWAIN_GetCurrentUnits.l() As "_TWAIN_GetCurrentUnits@0"
; Ask the source what its current unit of measure is.
; If anything goes wrong, this function just returns TWUN_INCHES (0).
TWAIN_SetCurrentUnits.l(nUnits.l) As "_TWAIN_SetCurrentUnits@4"
; Set the current unit of measure for the source.
; Unit of measure codes are in TWAIN.H, but TWUN_INCHES is 0.
TWAIN_GetBitDepth.l() As "_TWAIN_GetBitDepth@0"
; Get the current bitdepth, which can depend on the current PixelType.
; Bit depth is per color channel e.g. 24-bit RGB has bit depth 8.
; If anything goes wrong, this function returns 0.
TWAIN_SetBitDepth.l(nBits.l) As "_TWAIN_SetBitDepth@4"
; (Try to) set the current bitdepth (for the current pixel type).
TWAIN_GetPixelType.l() As "_TWAIN_GetPixelType@0"
; Ask the source For the current pixel type.
; If anything goes wrong (it shouldn't), this function returns 0 (TWPT_BW).
TWAIN_SetCurrentPixelType.l(nPixType.l) As "_TWAIN_SetCurrentPixelType@4"
; (Try To) set the current pixel type For acquisition.
; This is only allowed in State 4 (TWAIN_SOURCE_OPEN)
; The source may Select this pixel type, but don't assume it will.
TWAIN_GetCurrentResolution.d() As "_TWAIN_GetCurrentResolution@0"
; Ask the source For the current (horizontal) resolution.
; Resolution is in dots per current unit! (See TWAIN_GetCurrentUnits above)
; If anything goes wrong (it shouldn't) this function returns 0.0
TWAIN_GetYResolution.d() As "_TWAIN_GetYResolution@0"
; Returns the current vertical resolution, in dots per *current unit*.
; In the event of failure, returns 0.0.
TWAIN_SetCurrentResolution.l(dRes.d) As "_TWAIN_SetCurrentResolution@8"
; (Try To) set the current resolution For acquisition.
; Resolution is in dots per current unit! (See TWAIN_GetCurrentUnits above)
; This is only allowed in State 4 (TWAIN_SOURCE_OPEN)
; Note: The source may Select this resolution, but don't assume it will.
TWAIN_SetContrast.l(dCon.d) As "_TWAIN_SetContrast@8"
; (Try To) set the current contrast For acquisition.
; The TWAIN standard says that the range For this cap is -1000 ... +1000
TWAIN_SetBrightness.l(dBri.d) As "_TWAIN_SetBrightness@8"
; (Try To) set the current brightness For acquisition.
; The TWAIN standard says that the range For this cap is -1000 ... +1000
TWAIN_SetXferMech.l(mech.l) As "_TWAIN_SetXferMech@4"
TWAIN_XferMech.l() As "_TWAIN_XferMech@0"
; (Try To) set Or get the transfer mode - one of the following:
; #TWAIN_XFERMECH_NATIVE = 0
; #TWAIN_XFERMECH_FILE = 1
; #TWAIN_XFERMECH_MEMORY = 2
; --- Low-level Capability Negotiation Functions ---
; Setting a capability is valid only in State 4 (TWAIN_SOURCE_OPEN)
; Getting a capability is valid in State 4 Or any higher state.
TWAIN_SetCapOneValue.l(Cap.l, ItemType.l, ItemVal.l) As "_TWAIN_SetCapOneValue@12"
; Do a DAT_CAPABILITY/MSG_SET, on capability 'Cap' (e.g. ICAP_PIXELTYPE,
; CAP_AUTOFEED, etc.) using a TW_ONEVALUE container With the given item type
; And value. The item value must fit into 32 bits.
; Returns TRUE (1) If successful, FALSE (0) otherwise.
TWAIN_GetCapCurrent.l(Cap.l, ItemType.l, *pVal) As "_TWAIN_GetCapCurrent@12"
; Do a DAT_CAPABILITY/MSG_GETCURRENT on capability 'Cap'.
; Copy the current value out of the returned container into *pVal.
; If the operation fails (the source refuses the request), Or If the
; container is Not a ONEVALUE Or Enumeration, Or If the item type of the
; returned container is incompatible With the expected TWTY_ type in nType,
; returns FALSE. If this function returns FALSE, *pVal is Not touched.
TWAIN_ToFix32.l(d.d) As "_TWAIN_ToFix32@8"
; Convert a floating-point value To a 32-bit TW_FIX32 value that can be passed
; To e.g. TWAIN_SetCapOneValue
TWAIN_Fix32ToFloat.d(nfix.l) As "_TWAIN_Fix32ToFloat@4"
; Convert a TW_FIX32 value (As returned from some capability inquiries)
; To a double (floating point) value.
; --- Lowest-level functions For TWAIN protocol ---
TWAIN_DS.l(DG.l, DAT.l, MSG.l, *pData) As "_TWAIN_DS@16"
; Passes the triplet (DG, DAT, MSG, pData) To the open Data source If any.
; Returns 1 (TRUE) If the result code is TWRC_SUCCESS, 0 (FALSE) otherwise.
; The last result code can be retrieved With TWAIN_GetResultCode(), And the corresponding
; condition code can be retrieved With TWAIN_GetConditionCode().
; If no source is open this call will fail, result code TWRC_FAILURE, condition code TWCC_NODS.
TWAIN_Mgr.l(DG.l, DAT.l, MSG.l, *pData) As "_TWAIN_Mgr@16"
; Passes a triplet To the Data Source Manager (DSM).
; Returns 1 (TRUE) If the result code is TWRC_SUCCESS, 0 (FALSE) otherwise.
; The last result code can be retrieved With TWAIN_GetResultCode(), And the corresponding
; condition code can be retrieved With TWAIN_GetConditionCode().
; If the Source Manager is Not open, this call will fail, And set the result code To TWRC_FAILURE,
; With a condition code of TWCC_SEQERROR (triplet out of sequence).
EndImport
UseJPEGImageEncoder()
UsePNGImageEncoder()
Procedure.l hkTWAIN_WriteNativeToPNG(hDib.l, sPNGFileName.s)
Define lpDib.l
Define StructSize.l
Define Width.l
Define Height.l
Define Planes.w
Define BitCount.w
Define Compression.l
Define SizeImage.l
Define XPix_Meter.l
Define YPix_Meter.l
Define ColorsUsed.l
Define ColorsImportant.l
Define PalletteSize.l
Define BMPOffset.l
Define BMPSize.l
Define ImageNumber.l
Define *BMPBuffer
lpDib=GlobalLock_(hDib)
StructSize=PeekL(lpDib)
Width=PeekL(lpDib+4)
Height=PeekL(lpDib+8)
Planes=PeekW(lpDib+12)
BitCount=PeekW(lpDib+14)
Compression=PeekL(lpDib+16)
SizeImage=PeekL(lpDib+20)
XPix_Meter=PeekL(lpDib+24)
YPix_Meter=PeekL(lpDib+28)
ColorsUsed=PeekL(lpDib+32)
ColorsImportant=PeekL(lpDib+36)
;make BMP for CatchImage
If BitCount<24
PalletteSize=BitCount*8
EndIf
;BMPFileHeader is
;"BM",BMPSize.l,Reserved.w, Reserved.w, Offset.l where bmp data starts
; the offset is after the pallette info
; pallette info is RGB+1 byte for each color in the pallette
; unless it's 24bit then there's no pallette
BMPOffset=14+StructSize+PalletteSize
BMPSize=BMPOffset+SizeImage
*BMPBuffer=AllocateMemory(BMPSize)
PokeS(*BMPBuffer,"BM")
PokeL(*BMPBuffer+2,BMPSize)
PokeL(*BMPBuffer+10,BMPOffset)
CopyMemory(lpDib, *BMPBuffer+14, BMPSize-14)
GlobalUnlock_(hDib)
ImageNumber=CatchImage(#PB_Any,*BMPBuffer,BMPSize)
If sPNGFileName=""
sPNGFileName=SaveFileRequester("Save PNG file",GetHomeDirectory()+"My Documents\","PNG (*.png)|*.png",0)
EndIf
ProcedureReturn SaveImage(ImageNumber,sPNGFileName,#PB_ImagePlugin_PNG)
FreeImage(ImageNumber)
FreeMemory(*BMPBuffer)
EndProcedure
Procedure.l hkTWAIN_WriteNativeToJPG(hDib.l, sJPGFileName.s, lQuality.l)
Define lpDib.l
Define StructSize.l
Define Width.l
Define Height.l
Define Planes.w
Define BitCount.w
Define Compression.l
Define SizeImage.l
Define XPix_Meter.l
Define YPix_Meter.l
Define ColorsUsed.l
Define ColorsImportant.l
Define PalletteSize.l
Define BMPOffset.l
Define BMPSize.l
Define ImageNumber.l
Define *BMPBuffer
lpDib=GlobalLock_(hDib)
StructSize=PeekL(lpDib)
Width=PeekL(lpDib+4)
Height=PeekL(lpDib+8)
Planes=PeekW(lpDib+12)
BitCount=PeekW(lpDib+14)
Compression=PeekL(lpDib+16)
SizeImage=PeekL(lpDib+20)
XPix_Meter=PeekL(lpDib+24)
YPix_Meter=PeekL(lpDib+28)
ColorsUsed=PeekL(lpDib+32)
ColorsImportant=PeekL(lpDib+36)
;make BMP for CatchImage
If BitCount<24
PalletteSize=BitCount*8
EndIf
;BMPFileHeader is
;"BM",BMPSize.l,Reserved.w, Reserved.w, Offset.l where bmp data starts
; the offset is after the pallette info
; pallette info is RGB+1 byte for each color in the pallette
; unless it's 24bit then there's no pallette
BMPOffset=14+StructSize+PalletteSize
BMPSize=BMPOffset+SizeImage
*BMPBuffer=AllocateMemory(BMPSize)
PokeS(*BMPBuffer,"BM")
PokeL(*BMPBuffer+2,BMPSize)
PokeL(*BMPBuffer+10,BMPOffset)
CopyMemory(lpDib, *BMPBuffer+14, BMPSize-14)
GlobalUnlock_(hDib)
ImageNumber=CatchImage(#PB_Any,*BMPBuffer,BMPSize)
If sJPGFileName=""
sJPGFileName.s=SaveFileRequester("Save JPG file",GetHomeDirectory()+"My Documents\","JPG (*.jpg)|*.jpg",0)
EndIf
;lQuality is spcified in terms of a number between 1 and 10, 10 being the best quality lowest compression
; if not specified and the quality is 0 or invalid, we will default to 7
If lQuality<1 Or lQuality>10
lQuality=7
EndIf
ProcedureReturn SaveImage(ImageNumber,sJPGFileName,#PB_ImagePlugin_JPEG, lQuality)
FreeImage(ImageNumber)
FreeMemory(*BMPBuffer)
EndProcedure
DisableExplicit