# VBForums CodeBank > CodeBank - Visual Basic 6 and earlier >  VB6 - WIA Scanning Demo

## dilettante

Windows Image Acquisition (WIA) 2.0 is a great feature added in contemporary versions of Windows.  It was an enhancement over the older WIA 1.0 that shipped with XP and Win2K.

Windows Image Acquisition (WIA)

The nice thing is that WIA 2.0 can be deployed to Windows XP SP1 or later as well:

Windows® Image Acquisition Automation Library v2.0 Tool: Image acquisition and manipulation component for VB and scripting


Because it is so new, it isn't documented in the MSDN Library CDs that came with VB6.  The best source of documentation is a recent Windows SDK, such as:

Microsoft® Windows® Software Development Kit Update for Windows Vista™

Microsoft Windows SDK for Windows 7 and .NET Framework 4


While WIA can be an easy way to do many types of image capture and processing in VB6 programs, the attached demo just shows a few of them:
Selecting a scanner.Scanning a document.Scaling an image.Converting an image's format.Displaying a WIA ImageFile object's contents.Saving a WIA ImageFile object's contents to disk.
Here we select a scanner, then we scan and scale/convert to JPEG, display the result, and optionally save the image to disk.


There is also a menu in the demo that can be used to display/report various attributes of the selected scanner.  The information can be useful to a developer though you wouldn't normally fetch it in a real application.  However the logic used to fetch and report it may help reveal more about how some WIA objects work, so it is worth looking at.

Similar reports can be created that extract things like Filter documentation from WIA objects.


*Note:*

Many older scanners do not come with a WIA driver, and only support the TWAIN API.  These older scanners can't be used via WIA.  Even some newer scanners don't expose full functionality via their WIA drivers, and may limit resolution and other properties.

----------


## VBClassicRocks

Thanks for sharing.  I had to change two lines in the SetUIValues routine
to get it to work.  Perhaps something relating to my scanner (HP Photosmart C6100).


```
  txtDPI(txtDPI.LBound).Text = CStr(![Horizontal Resolution]) '.SubTypeMin)
  txtDPI(txtDPI.UBound).Text = CStr(![Vertical Resolution]) '.SubTypeMin)
```

----------


## dilettante

Thanks.

I wasn't handling some cases where scanning properties in my user interface are read-only for a given scanner.

It looks like your change copies the default property of these Wia.Property objects (i.e. *.Value*) into the text boxes.  I have updated the demo code to handle this better.

----------


## raghavendran

Can you incorporate resize image / crop into this project ? I'm urgently in need of this.  Thank you.

----------


## dilettante

It is hard to say exactly how you want to incorporate those actions.  The biggest issue would be designing the user interface.  Choose scaling size via Slider?  Set cropping margins via some sort of draggable lines?

However you can probably design that yourself.  What might be missing is how to accomplish scaling and cropping once you know how much you want to do one, the other, or both.

Well this is pretty well covered in the WIA documentation, and I think there are even samples there.  The process is fairly simple, as shown in the attached demo:




```
Private Sub cmdCropScale_Click()
    Dim ipCropScale As WIA.ImageProcess
    Dim imgCroppedScaled As WIA.ImageFile
    
    Set ipCropScale = New WIA.ImageProcess
    With ipCropScale
        .Filters.Add .FilterInfos!Crop.FilterID
        .Filters.Add .FilterInfos!Scale.FilterID
        With .Filters(1).Properties
            !Left = 50
            !Top = 100
            !Right = 50
            !Bottom = 100
        End With
        With .Filters(2).Properties
            !MaximumWidth = 300
            !MaximumHeight = 454
            !PreserveAspectRatio = False
        End With
        Set imgCroppedScaled = .Apply(imgOriginal)
    End With
    Image2.Picture = imgCroppedScaled.FileData.Picture
End Sub
```

So adding such features to the scanning project yourself the way you want it should be easy enough.

----------


## raghavendran

Dear dilettante
what i was trying to ask is that: after scanning the image, it does't fit into a A4 size sheet. I want to know how to programatically fit the entire image to the size i want. kindly help me. Thanks for your quick reply.

----------


## dilettante

The problem is that you need to know what size the image has to be for your printer.  The image size will be in pixels, and your printer might print at different "pixels per inch" (dots per inch), per cm, etc.

So you need to decide what resolution you'll use to print.  Then take that resolution per unit of linear measure (inches, cm, etc.), multiply it by the horizontal and vertical psper size in linear measurements (inches, cm), and that give you the size in pixels you need to scale the image to before printing.

Since printers often have borders they will not print in, you might have to adjust the "paper size" dimensions a little smaller to accomodate this.


Now, your program will need to fetch the information for your printer and paper since they aren't universal values.  From there you can calculate the required dimensions in pixels and do your scaling.

The print spooler can provide this information to your program.  DeviceCapabilities() in winspool.drv can provide paper sizes in units of 1/10 mm for you to work with.  Here's a demo program that retrieves such information:


You'd fetch the 3 types of info (paper ID, paper name, paper sizes) and then use the paper ID value if you know it to look up its index in the table, then use that index to get the sizes.  If you haven't hard-coded your paper's ID you may need to scan the paper names list to get the index.


But none of this is related to WIA scanning at all.  _It's printer stuff and needs a VB6 question thread of its own rather than an off-topic  discussion here._


You'd also need your printer resolution so I've updated the attachment to retrieve that as well.

----------


## raghavendran

Sir

In the 'SaveCard' program is it possible to replace an existing file with the same file name ? WiaImageFile.Savefile saves the file. But it does't allow if already a file is existing with the same name. Kindly reply.

----------


## dilettante

As written it tries to create an unused file name by testing for one that already is in use:


```
Private Sub cmdSaveCard_Click()
    Dim FileTry As Long
    Dim FileName As String
    
    FileTry = Fix(Timer() * 1000)
    On Error Resume Next
    Do
        FileTry = FileTry + 1
        FileName = "P" & Hex$(FileTry) & ".jpg"
        GetAttr FileName
    Loop Until Err
    On Error GoTo 0
    WiaImageFile.SaveFile FileName
    cmdSaveCard.Enabled = False
End Sub
```

If this doesn't work for you changing it to another scheme should be a trivial matter.  But as written it should not try to write over an existing file.

Remember, this is just an example and not a finished application.

----------


## raghavendran

Sir

"ScanCard" does't display entire sheet after scanning. what changes i have to make in order to see the whole image in "imgdisplay" control which you have used. kindly help me. Earlier i was not raising printing issue at all. Probably my 'question presentation' may be wrong.

----------


## raghavendran

To save the file with WIA what I did is that:

dim vPictureFile as string
dim vPicturePath as string 

vPictureFile = "raghs.jpg"
vPicturePath = "" & App.Path & "\Picture\" & vPictureFile

Kill vPicturePath       ' >>>> after checking whether file is available or not (that part i have not included here)

WiaImageFile.SaveFile vPicturePath

----------


## dilettante

> "ScanCard" does't display entire sheet after scanning. what changes i have to make in order to see the whole image in "imgdisplay" control which you have used. kindly help me. Earlier i was not raising printing issue at all. Probably my 'question presentation' may be wrong.


You started by asking for "resize/crop" and I addressed that.  Now it sounds like you need something else entirely.

The demo only scans "cards" of 3.375 inches by 2.125 inches.  It is just a demonstration and was never meant to scan other document sizes.  For that matter imgDisplay is only large enough for these "cards."

Here is part of the code, showing where the scan dimensions are set:


```
Private Sub cmdScanCard_Click()
    Dim WiaRootItem As WIA.Item

    MousePointer = vbHourglass

    Set WiaRootItem = WiaDev.Items(1) 'Root\Top item of the device.
    With WiaRootItem.Properties
        With ![Current Intent]
            If Not .IsReadOnly Then .Value = WiaIntent
        End With
        With ![Brightness]
            If Not .IsReadOnly Then .Value = sldBrightness.Value
        End With
        With ![Contrast]
            If Not .IsReadOnly Then .Value = sldContrast.Value
        End With
        With ![Threshold]
            If Not .IsReadOnly Then .Value = sldThreshold.Value
        End With
        ![Horizontal Resolution].Value = CLng(txtDPI(txtDPI.LBound).Text)
        ![Vertical Resolution].Value = CLng(txtDPI(txtDPI.UBound).Text)
        'Size of a "credit card" in 1000ths of an inch, scaled to pixels (dots) here.
        ![Horizontal Extent].Value = CLng(![Horizontal Resolution].Value * 3375 \ 1000)
        ![Vertical Extent].Value = CLng(![Vertical Resolution].Value * 2125 \ 1000)
    End With
```

To scan different document sizes you need to make changes there.  Once you have made that change you'd also need to deal with scaling in order to show the result in the "preview" displayed in imgDisplay.

----------


## raghavendran

The Resize/Crop program was also very useful to me. I put these together in my project and it's successful. I could learn WIA filter properties, constants, etc. with the help of your codes in these. Thank you so much.

Will it be possible to change the progress bar title (percent complete) in this project ?

----------


## raghavendran

Suppose if I need to scan both the sides of a sheet - each separately and then put them together to save as a single file - what i need to do? 
i.e. Join two scanned images and store as one - is it possible?

----------


## dilettante

> Will it be possible to change the progress bar title (percent complete) in this project ?


You can do whatever you want.  This isn't a finished product, just a demonstration of concepts.  That's why it is in the CodeBank and not the UtilityBank.

----------


## dilettante

> Suppose if I need to scan both the sides of a sheet - each separately and then put them together to save as a single file - what i need to do? 
> i.e. Join two scanned images and store as one - is it possible?


I tried to answer this in your VB6 question thread.

Scanner software often stores the images in a TIFF file to retain more detail, and those can have multipage image data in them.

----------


## hameed

Dear sir,
Please let me know where and what should i change to the code to scan a document for A4 size instead of card size. 
And please look at the following code that i have changed from your code, it is scanning in A4 size but not clear and the file size is taking up to 2.5MB,
please help me sir to scan A4 size with clear resolution and less sized file. Many thanks in advance.
thanks alot for helping people.


        ![Horizontal Extent].Value = 1600
        ![Vertical Extent].Value = 2200

----------


## dilettante

As far as I know, WIA always uses PPI/DPI for resolutions, and probably for extents as well.

A4 size is 8.3 inches by 11.7 inches.  In 1000ths that is 8300 by 117000, so:



```
        'Size of a "credit card" in 1000ths of an inch, scaled to pixels (dots) here.
        ![Horizontal Extent].Value = CLng(![Horizontal Resolution].Value * 3375 \ 1000)
        ![Vertical Extent].Value = CLng(![Vertical Resolution].Value * 2125 \ 1000)
```

Should become:



```
        'Size of a "credit card" in 1000ths of an inch, scaled to pixels (dots) here.
        ![Horizontal Extent].Value = CLng(![Horizontal Resolution].Value * 8300\ 1000)
        ![Vertical Extent].Value = CLng(![Vertical Resolution].Value * 117000\ 1000)
```

Of course the scanned image won't fit in imgDisplay without drastic scaling down.  So in cmdScanCard_Click you would need code to _scale_ WiaImageFile into a _separate_ temporary ImageFile object for display:



```
    If WiaImageFile.FormatID <> wiaFormatJPEG Then
        With New WIA.ImageProcess
            .Filters.Add .FilterInfos![Scale].FilterID
            With .Filters(1).Properties
                ![PreserveAspectRatio].Value = True
                'We take off 4px for the border around imgDisplay:
                ![MaximumWidth].Value = CLng(ScaleX(imgDisplay.Width, ScaleMode, vbPixels) - 4)
                ![MaximumHeight].Value = CLng(ScaleY(imgDisplay.Height, ScaleMode, vbPixels) - 4)
            End With
            .Filters.Add .FilterInfos![Convert].FilterID
            With .Filters(2).Properties
                ![FormatID].Value = wiaFormatJPEG
                ![Quality].Value = 70
            End With
            Set WiaImageFile = .Apply(WiaImageFile)
        End With
    End If
    Set imgDisplay.Picture = WiaImageFile.FileData.Picture
    cmdSaveCard.Enabled = True
```

Will need to be changed.  Maybe something like:



```
    With New WIA.ImageProcess
        .Filters.Add .FilterInfos![Convert].FilterID
        With .Filters(1).Properties
            ![FormatID].Value = wiaFormatJPEG
            ![Quality].Value = 70
        End With
        Set WiaImageFile = .Apply(WiaImageFile)
    End With

    Dim TempImageFile As WIA.ImageFile

    With New WIA.ImageProcess
        .Filters.Add .FilterInfos![Scale].FilterID
        With .Filters(1).Properties
            ![PreserveAspectRatio].Value = True
            'We take off 4px for the border around imgDisplay:
            ![MaximumWidth].Value = CLng(ScaleX(imgDisplay.Width, ScaleMode, vbPixels) - 4)
            ![MaximumHeight].Value = CLng(ScaleY(imgDisplay.Height, ScaleMode, vbPixels) - 4)
        End With
        .Filters.Add .FilterInfos![Convert].FilterID
        With .Filters(2).Properties
            ![FormatID].Value = wiaFormatJPEG
            ![Quality].Value = 70
        End With
        Set TempImageFile = .Apply(WiaImageFile)
    End With
    Set imgDisplay.Picture = TempImageFile.FileData.Picture
    cmdSaveCard.Enabled = True
```

----------


## hameed

Dear sir,
how can we scan multiple pages A4 sized documents to PDF or Jpeg, and i do not need to view the scanned pages. Please give me the code. Thank in Advance for helping the VB beginners.

----------


## dilettante

There is no PDF support in WIA and JPEG does not support "pages."

As for specific applications, there should be plenty here to help a programmer get started.  Perhaps you should consider hiring one?  We don't do free custom programming here.

----------


## cyberzilla

> There is no PDF support in WIA and JPEG does not support "pages."
> 
> As for specific applications, there should be plenty here to help a programmer get started.  Perhaps you should consider hiring one?  We don't do free custom programming here.


Is WIA support duplex / scan two side?

----------

