Using Windows Handles to Images
In Memory
ImageControls 3 provides the ability to process images directly
to and from memory, bypassing using a scanner or hard disk to
obtain data or using a hard drive to write data. This allows for
the ability to import images from another application, or to export
images to another application. For example, a image may be scanned
to memory for use by another application, then after this application
is finished, the image data may be imported back to ImageControls.
This project modifies the original demonstration utility, VBDEM32x.EXE,
source code as provided with the ImageControls 3 Toolkit. It provides
the ability to process a single page image, from a scanner or
importing from a hard drive. It then provides the ability to process
the image in memory so that it may be written on to a hard drive.
When a image is processed form memory, it clears the handle to
the memory image data.
It contains one additional form, frmImageHandle, which is a dialog
box to select which image handle format (DIB or DDB) will be used
to store the data to memory. This form consists of the following:
- Three (3) options buttons: optBitmap, optDIB and optImageDesc
- One (1) frame containing the option buttons: Frame1
- One (1) command button: cmdOK
Figure 1 displays the placement of these objects on the form.

Figure 1
A menu selection, mnuFileHandleFormat, was added after the Storage
Format menu item in File pull down menu of the main form, frmMain.
When it is selected, the form frmImageHandle is displayed. When
the user closes the dialog box, it is unloaded.
Private Sub mnuFileHandleFormat_Click()
'***** Menu selection to select memory format for
'***** scanning/importing images to memory.
'***** Use demonstration utility built in procedure to
'***** display developer created dialog box.
KFShowFormWithHourGlass frmImageHandle, True
'***** Unload the dialog box when completed.
Unload frmImageHandle
End Sub
The user is able to select which format will be used, Device
Dependent Bitmap (DDB) or Device Independent Bitmap (DIB). When
the form loads, it selects the appropriate option button based
on the applications existing selection for the Image Handle format.
Image Descriptor is disabled, as it is presently not available
in ImageControls 3, but will become available in a future release.
Private Sub Form_Load()
'***** Initialize settings for use with memory format
'***** selection dialog box, frmImageHandle.
'***** If DDB currently selected, Bitmap selection True
If frmMain!Kscan1.HImageFormat = KSHIMAGEFORMATBITMAP Then
optBitmap.Value = True
Else
'***** Else, set DIB selection True.
optDIB.Value = True
End If
'***** Disable Image Description selection. Not
'***** presently supported. Future enhancement.
optImageDesc.Enabled = False
End Sub
If the user selects the first option button, optBitmap, then
the Image Handle format will be set to KSHIMAGEFORMATBITMAP, Device
Dependent Bitmap.
Private Sub optBitmap_Click()
'***** If selected, set memory format to DDB.
frmMain!Kscan1.HImageFormat = KSHIMAGEFORMATBITMAP
End Sub
If the user selects the second option button, optDIB, then the
Image Handle format will be set to KSHIMAGEFORMATDIB, Device Independent
Bitmap.
Private Sub optDIB_Click()
'***** If selected, set memory format to DIB.
frmMain!Kscan1.HImageFormat = KSHIMAGEFORMATDIB
End Sub
The OK button hides the dialog box.
Private Sub cmdOK_Click()
'***** Hide Image Handle Form when finished.
Me.Hide
End Sub
A global variable, g_ImageHandle is added to the General Declarations
of KFUTIL.BAS. This variable will be used to store the Image Handle.
'***** Declare global variable for image handle
Global g_ImageHandle As Long
Also, the function GlobalFree is declared in the General Declarations
of the main form, frmMain (MAINFORM.FRM). It will be required
to free the handle of DIB images from memory.
'***** Declare function GlobalFree to clear image handle for
DIB
Private Declare Function GlobalFree Lib "kernel32"
(ByVal hMem As Long) As Long
Then the main form is loaded, Form_Load event, the global variable
g_ImageHandle is initialized.
'***** Initialize global image handle variable.
g_ImageHandle = 0
Two menu selections are added to the Source pull down menu, mnuSourceToMemory
and mnuSourceFromMemory.
When mnuSourceToMemory is selected, the process to scan or import
a image into memory is launched. It is similar to the mnuSourceProcessImage_Click
event. The variable g_ImageHandle is used as a flag to specify
that if a image is to be scanned to memory.
Private Sub mnuSourceToMemory_Click()
'***** Menu selection for scanning images to memory.
'***** Similar to scanning/importing single images
'***** Disable toolbar buttons
DisableToolbarButtons
Kscan1.ScanDuplex = False
'***** Set scan method to a single page
Kscan1.DeviceMethod = KSDEVICEMETHODSINGLE
'***** Use image handle variable as flag to specify
'***** when image is to be scanned to memory.
g_ImageHandle = -1
'***** Start the job
Call StartJob
'***** Disable toolbar buttons
EnableToolbarButtons
End Sub
When mnuSourceFromMemory is selected, the process to import a
image from memory is launched. As the mnuSourceToMemory_Click
event, it is also similar to the mnuSourceProcessImage_Click event.
Private Sub mnuSourceFromMemory_Click()
'***** Menu selection for scanning images from memory.
'***** Similiar to scanning/importing single images
'***** Disable toolbar buttons
DisableToolbarButtons
Kscan1.ScanDuplex = False
'***** Set scan method to a single page
Kscan1.DeviceMethod = KSDEVICEMETHODSINGLE
'***** Start the job
Call StartJob
'***** Disable toolbar buttons
EnableToolbarButtons
End Sub
The KScan1_PageEnd event is modified to send the image data to
memory instead of a hard drive when appropriate. It is also modified
to remove the image handle if a image is processed from memory.
This section of code is inserted between the existing code to
not save image data if it is smaller then the delete threshold
and the analysis dialog form update.
(Existing Code)
'***** Set filename to nothing so it is not saved
'***** (if it is smaller than the delete threshold)
If Kscan1.PEDelete Then
Kscan1.PEFileName = ""
End If
Kscan1.PEPage = g_PEPage
(New Code)
'***** If scanning from memory, clear image handle. DeleteObject
'***** for DDB images, GlobalFree for DIB images.
If g_ImageHandle > 0 Then
If Kscan1.HImageFormat = KSHIMAGEFORMATBITMAP Then
DeleteObject (g_ImageHandle)
Else
GlobalFree (g_ImageHandle)
End If
g_ImageHandle = 0
End If
'***** Set image handle and PEFilename if scanning to memory.
If g_ImageHandle = -1 Then
Kscan1.PEFileName = ""
g_ImageHandle = Kscan1.PEHImage
frmMain.Caption = gc_Title & " - " & "Bitmap
Image in Memory at " & g_ImageHandle
End If
(Existing Code)
'***** Update analysis dialog
'***** Different for gold and standard.
The KScan1_PageStart event is modified to read the image data
from memory instead of a scanner or hard drive when desired. This
section of code is a conditional statement and commands wrapped
around existing code that is used to determine the KScan settings.
(Existing Code)
'***** Log the event
Debug.Print "KScan1 -- PageStart Event"
KFAnalysisLog "***** START IMAGE *****"
(New Code)
'***** Add conditional statement for scanning images from memory
'***** that will wrap the existing conditional statements.
If g_ImageHandle > 0 Then
Kscan1.PSFileName = ""
Kscan1.PSHImage = g_ImageHandle
Else
(Existing Code)
'***** Set filename to operate on for device=disk.
If Kscan1.ActiveDevice = KSACTIVEDEVICEDISK Then
If Kscan1.DeviceMethod = KSDEVICEMETHODSINGLE Then
'***** For single pages, use the current image name
If Not g_ActiveKView.Displayed Then
Call KFErrorMsgBoxWithString("No file open for Disk Device")
Exit Sub
End If
'***** Use file currently active displayed file
Kscan1.PSFileName = g_ActiveKView.FileName
Kscan1.PSPage = 1
Else
'***** Determine if batch is done
If g_PSPageCount >= UBound(g_PSFileArray) Then
'***** Null filename means no more files....
Kscan1.PSFileName = ""
Else
'***** Batch is not done.
'***** Increment page start count -- note page start count
'***** can be out of sync with page end count when prescan
'***** greater than 0.
g_PSPageCount = g_PSPageCount + 1
'***** For batch jobs, use create unique names
'***** based on file list from SETPATH form.
If Right$(g_PSFilePath, 1) <> "\" Then
g_PSFilePath = g_PSFilePath + "\"
End If
Kscan1.PSFileName = g_PSFilePath + g_PSFileArray(g_PSPageCount)
Kscan1.PSPage = 1
End If
End If
End If
(New Code)
'***** End of conditional statement of scanning from memory.
End If
|