scanning under windows WIA with custom settings (dpi / etc )


N

News123

Hi,

I'm trying to scan a document from a python 2.6 script without user
interaction.

I found a code snippet, that allows me to scan under Vista, but that
doesn't allow me to select the dpi / color mode / etc.

The snippet uses win32com.client

# ##################### script start
import win32com.client,os

WIA_IMG_FORMAT_PNG = "{B96B3CAF-0728-11D3-9D7B-0000F81EF32E}"
WIA_COMMAND_TAKE_PICTURE = "{AF933CAC-ACAD-11D2-A093-00C04F72DC3C}"

os.chdir('c:/temp')
wia = win32com.client.Dispatch("WIA.CommonDialog")
dev = wia.ShowSelectDevice()
for command in dev.Commands:
if command.CommandID==WIA_COMMAND_TAKE_PICTURE:
foo=dev.ExecuteCommand(WIA_COMMAND_TAKE_PICTURE)
i=1
for item in dev.Items:
if i==dev.Items.Count:
image=item.Transfer(WIA_IMG_FORMAT_PNG)
break
i=i+1

image.SaveFile("test.png")
######################### script end


My problems are:

- This script works fine for me under Windows 7, however I'm
unable to specify additional parameters, like dpi and
color mode.

- The script doesn't work under windows XP, though the scanner driver is
installed. (Gimp finds the scanner (as WIA scanner)).
Perhaps 'WIA.CommonDialig' has another name or I need to install some DLL.
The error message is:
--------------------------------------------------------------------
Traceback (most recent call last):
File "C:\work\python\minidemos\wia_get_simple.py", line 7, in <module>
wia = win32com.client.Dispatch("WIA.CommonDialog")
File "C:\Python26\lib\site-packages\win32com\client\__init__.py", line
95, in Dispatch
dispatch, userName =
dynamic._GetGoodDispatchAndUserName(dispatch,userName,clsctx)
File "C:\Python26\lib\site-packages\win32com\client\dynamic.py", line
104, in _GetGoodDispatchAndUserName
return (_GetGoodDispatch(IDispatch, clsctx), userName)
File "C:\Python26\lib\site-packages\win32com\client\dynamic.py", line
84, in _GetGoodDispatch
IDispatch = pythoncom.CoCreateInstance(IDispatch, None, clsctx,
pythoncom.IID_IDispatch)
com_error: (-2147221005, 'Invalid class string', None, None)
---------------------------------------------------------------------


As I have no knowledge of Win32com and WIA I would appreciate some help
or good documentation about wincom32 / WIA with python



thanks for your help and bye


N
 
Ad

Advertisements

R

r

Hi,

I'm trying to scan a document from a python 2.6 script without user
interaction.

I found a code snippet, that allows me to scan under Vista, but that
doesn't allow me to select the dpi / color mode / etc.

The snippet uses win32com.client


Hello,
I would also like to know the answer for which i am investigating now,
although like yourself i don't know much about the windows API and the
MSDN docs aren't helping much :(. All i can understand is that doing
anything in windows is a real PITA!

I am sure someone (or many) have climbed this mountain before but all
of them seemed to have forgotten to leave us the map that shows the
easy way up... bummer! The PyWin32extensions are great but lacking
detailed information of how to use the thing. And i know some GUI kits
like wxPython have Printer support but thats not really what i am
talking about here. I want the functionality directly from Python with
only win32extentions needed! We need to extend on the great work of
PyWin32 *OR* create a new module that will be an abstraction of the
Win32 module.

The problem with Windows scripting is all the crap you need to do
before you can even set parameters. Get a device context or find some
cryptic dispatch code, then mull over some even more cryptic options
and such. By now your eyeballs are about to pop out of there sockets
and your head is ponding from a massive hemorrhage and yet you still
have nothing to show for all this jumping through MS hoops!!!

There needs to be a drive to make some docs and post them somewhere.
This knowledge must be shared! The best place would be in the PyWin32
docs, but i don't expect the creator will do this, he has given us the
vehicle now we must forge the path.

I am willing to help create this if someone with even a small amount
of win32 knowledge could lend their expertise (any takers? send me an
email!). I would write all the Python code to implement these actions
very easily. (of course i'm not promising ground breaking code here
just something that works, but a hack is better than nothing!

I think a good start would be two classes for dealing with Printers
and Scanners in a very pythonic way (no device contexts!!!), from
there the sky is the limit!


##PRINTING RAW STRING##
import win32printer
printer = win32printer.get_default()
if not printer.online():
showerror('', 'Turn it on first you idiot!')
sys.exit(1)
printer.options.update({
'orientation':'landscape',
'font':('Times New', 12),
'header':time.ctime(),
})
printer.print_raw_string('hello printer, i have have arrived!')

##SCANNING##
import win32scanner
scanner = win32scanner.get_default()
if not scanner.online():
showerror('', 'Turn it on first you idiot!')
sys.exit(1)
scanner.options['imagetype'] = '.jpg'
scanner.scan(file="C:\\tmp\\image1")

##MORE??##

All the device context and cryptic mumbo-gumbo are nicly hidden from
the user. Of course there will also be option to show dialogs for user
input because that will be needed. With this proposed module the
bumbling confusion can be avoided. Joe-Scripter can study the source
later to learn Win32 more in depth. Yes people i hate windows too, but
for now we all have to deal with Windows like it or not!
 
R

r

- This script works fine for me under Windows 7, however I'm
  unable to   specify additional parameters, like dpi and
  color mode.

I have found something interesting but have no idea HOW to implement
it?? It seems the setting for the scanner are in the registry and must
be changed that way or by specifically calling these constants on the
device.

WIA_IPS_YRES (ScannerPictureYres)
Contains the current vertical resolution, in pixels per inch, for the
device. An application sets this property to set the vertical
resolution. The minidriver creates and maintains this property. Type:
VT_I4, Access: Read/Write or Read Only, Valid Values: WIA_PROP_RANGE
or WIA_PROP_LIST

WIA_IPS_XRES (ScannerPictureXres)
Contains the current horizontal resolution, in pixels per inch, for
the device. An application sets this property to set the horizontal
resolution. The minidriver creates and maintains this property. Type:
VT_I4, Access: Read/Write or Read Only, Valid Values: WIA_PROP_RANGE
or WIA_PROP_LIST

WIA_IPS_OPTICAL_XRES (ScannerPictureOpticalXres)
Note This property is supported only by Windows Vista and later.
Horizontal Optical Resolution. Highest supported horizontal optical
resolution in DPI. This property is a single value. This is not a list
of all resolutions that can be generated by the device. Rather, this
is the resolution of the device's optics. The minidriver creates and
maintains this property. This property is required for all items.
Type: VT_I4, Access: Read Only, Valid values: WIA_PROP_NONE

WIA_IPS_OPTICAL_YRES (ScannerPictureOpticalYres)
Note This property is supported only by Windows Vista and later.
Vertical Optical Resolution. Highest supported vertical optical
resolution in DPI. This property is a single value. This is not a list
of all resolutions that are generated by the device. Rather, this is
the resolution of the device's optics. The minidriver creates and
maintains this property. This property is required for all items.Type:
VT_I4, Access: Read Only, Valid values: WIA_PROP_NONE

WIA_IPS_BRIGHTNESS (ScannerPictureBrightness)
The image brightness values available within the scanner.Contains the
current hardware brightness setting for the device. An application
sets this property to the hardware's brightness value. The minidriver
creates and maintains this property. Type: VT_I4, Access: Read/Write,
Valid Values: WIA_PROP_RANGE

WIA_IPS_CONTRAST (ScannerPictureContrast)
Contains the current hardware contrast setting for a device. An
application sets this property to the hardware's contrast value. The
minidriver creates and maintains this property. Type: VT_I4, Access:
Read/Write, Valid Values: WIA_PROP_RANGE

WIA_IPS_ORIENTATION (ScannerPictureOrientation)
Specifies the current orientation of the documents to be scanned. The
minidriver creates and maintains this property. Type: VT_I4, Access:
Read/Write, Valid Values: WIA_PROP_LIST

------------------------
Image Intent Constants
------------------------
Image intent constants specify what type of data the image is meant to
represent. The WIA_IPS_CUR_INTENT scanner property uses these flags.
To provide an intent, combine an intended image type flag with an
intended size/quality flag by using the OR operator. WIA_INTENT_NONE
should not be combined with any other flags. Note that an image cannot
be both grayscale and color.

WIA_INTENT_IMAGE_TYPE_COLOR (ImageTypeColor)
WIA_INTENT_IMAGE_TYPE_GRAYSCALE (ImageTypeGrayscale)
WIA_INTENT_IMAGE_TYPE_TEXT (ImageTypeText)
WIA_INTENT_MINIMIZE_SIZE (MinimizeSize)
WIA_INTENT_MAXIMIZE_QUALITY (MaximizeQuality)
WIA_INTENT_BEST_PREVIEW (BestPreview)
 
N

News123

Hi r,
I have found something interesting but have no idea HOW to implement
it?? It seems the setting for the scanner are in the registry and must
be changed that way or by specifically calling these constants on the
device.

WIA_IPS_YRES (ScannerPictureYres)
Contains the current vertical resolution, in pixels per inch, for the
device. An application sets this property to set the vertical
resolution. The minidriver creates and maintains this property. Type:
VT_I4, Access: Read/Write or Read Only, Valid Values: WIA_PROP_RANGE
or WIA_PROP_LIST


This sounds interesting.

I do have two questions:

1.) do these entries really have an impact?
---------------------------------------------
Did you find out whether changing the resolution or color mode in the
registry has really an impact when scanning an image with my python script?


2.) Where are these registry entries?
---------------------------------------

Under which windows version did you find these registry entries (XP,
Vista or Win7)?

I can't locate them, but probably my approach is too naive.
I started regedit and searched with CTRL-F for 'WIA_IPS_YRES'.

Perhaps these settings are scanner dependant?


My current script:
# ##################### script start
import win32com.client,os

WIA_IMG_FORMAT_PNG = "{B96B3CAF-0728-11D3-9D7B-0000F81EF32E}"
WIA_COMMAND_TAKE_PICTURE = "{AF933CAC-ACAD-11D2-A093-00C04F72DC3C}"

os.chdir('c:/temp')
wia = win32com.client.Dispatch("WIA.CommonDialog")
dev = wia.ShowSelectDevice()
for command in dev.Commands:
if command.CommandID==WIA_COMMAND_TAKE_PICTURE:
foo=dev.ExecuteCommand(WIA_COMMAND_TAKE_PICTURE)
i=1
for item in dev.Items:
if i==dev.Items.Count:
image=item.Transfer(WIA_IMG_FORMAT_PNG)
break
i=i+1

image.SaveFile("test.png")
######################### script end


bye


N
 
N

News123

Hi r,
I have found something interesting but have no idea HOW to implement
it?? It seems the setting for the scanner are in the registry and must
be changed that way or by specifically calling these constants on the
device.

WIA_IPS_YRES (ScannerPictureYres)
Contains the current vertical resolution, in pixels per inch, for the
device. An application sets this property to set the vertical
resolution. The minidriver creates and maintains this property. Type:
VT_I4, Access: Read/Write or Read Only, Valid Values: WIA_PROP_RANGE
or WIA_PROP_LIST


This sounds interesting.

I do have two questions:

1.) do these entries really have an impact?
---------------------------------------------
Did you find out whether changing the resolution or color mode in the
registry has really an impact when scanning an image with my python script?


2.) Where are these registry entries?
---------------------------------------

Under which windows version did you find these registry entries (XP,
Vista or Win7)?

I can't locate them, but probably my approach is too naive.
I started regedit and searched with CTRL-F for 'WIA_IPS_YRES'.

Perhaps these settings are scanner dependant?


My current script:
# ##################### script start
import win32com.client,os

WIA_IMG_FORMAT_PNG = "{B96B3CAF-0728-11D3-9D7B-0000F81EF32E}"
WIA_COMMAND_TAKE_PICTURE = "{AF933CAC-ACAD-11D2-A093-00C04F72DC3C}"

os.chdir('c:/temp')
wia = win32com.client.Dispatch("WIA.CommonDialog")
dev = wia.ShowSelectDevice()
for command in dev.Commands:
if command.CommandID==WIA_COMMAND_TAKE_PICTURE:
foo=dev.ExecuteCommand(WIA_COMMAND_TAKE_PICTURE)
i=1
for item in dev.Items:
if i==dev.Items.Count:
image=item.Transfer(WIA_IMG_FORMAT_PNG)
break
i=i+1

image.SaveFile("test.png")
######################### script end


bye


N
 
R

r

more *maybe useful dump?
for p in i.Properties:
if not p.IsReadOnly:
print p.Name, '->', p.Value

Color Profile Name -> sRGB Color Space Profile
Brightness -> 0
Contrast -> 0
Private Highlight Level -> 0
Private Midtone Level -> 0
Private Shadow Level -> 0
Private Gamma -> 2200
Private Saturation -> 1000
Private Hue X -> 0
Private Hue Y -> 0
Private Sharpen Level -> 3
Threshold -> 55
Horizontal Resolution -> 200
Vertical Resolution -> 200
Horizontal Start Position -> 0
Vertical Start Position -> 0
Horizontal Extent -> 1700
Vertical Extent -> 2338
Current Intent -> 0
Data Type -> 3
Media Type -> 128
Format -> {B96B3CAA-0728-11D3-9D7B-0000F81EF32E}
Private Source Depth -> 0
Private Preview -> 0
Private Exposure Method -> 0
Private Smoothing -> 1
Private Color Enhanced -> 0
Private TMA Method -> 0

u'{6BDD1FC6-810F-11D0-BEC7-08002BE2092F}\\0000'
print p.Name, '->', p.Value

Item Name -> Root
Full Item Name -> 0000\Root
Item Flags -> 76
Unique Device ID -> {6BDD1FC6-810F-11D0-BEC7-08002BE2092F}\0000
Manufacturer -> Hewlett-Packard
Description -> HP Deskjet F300
Type -> 65538
Port -> \\.\Usbscan0
Name -> HP Deskjet F300
Server -> local
Remote Device ID ->
UI Class ID -> {0A8DC120-D685-4247-9CD1-8712F6BB2DED}
Hardware Configuration -> 0
BaudRate ->
STI Generic Capabilities -> 48
WIA Version -> 2.0
Driver Version -> 0.0.0.216
PnP ID String -> \\?\usb#vid_03f0&pid_5511&mi_00#6&2def7e7&0&0000#
{6bdd1fc6-810f-11d0-bec7-08002be2092f}
STI Driver Version -> 2
Horizontal Bed Size -> 8500
Vertical Bed Size -> 11690
Horizontal Bed Registration -> 0
Vertical Bed Registration -> 0
Access Rights -> 3
Horizontal Optical Resolution -> 2400
Vertical Optical Resolution -> 2400
Firmware Version -> 1.0.na
Max Scan Time -> 500000

Now how to set the values... hmmm?
 
Ad

Advertisements

N

News123

News123 said:
Hi,

I'm trying to scan a document from a python 2.6 script without user
interaction.

I found a code snippet, that allows me to scan under Vista, but that
doesn't allow me to select the dpi / color mode / etc.

I'm still stuck.


I'll try to look at any solution (visual C++, C#, Basic) first.
Then it's perhaps easier to pythonize it via python .net.

However I don't know whether python .net exists for 2.6 and whether it
is stable enough.


N
 
N

News123

r said:
more *maybe useful dump?

for p in i.Properties:
if not p.IsReadOnly:
print p.Name, '->', p.Value
.. . .
Horizontal Resolution -> 200
Vertical Resolution -> 200
Horizontal Start Position -> 0 .. . .

Now how to set the values... hmmm?

How to set the values? This is THE magic question.

At least I found out how to set the values in C# :

foreach (Property prop in item.Properties){
if (prop.IsReadOnly) continue;
if (prop.Name == "Horizontal Resolution")
{
IProperty iprop = (IProperty)prop;
Object val = 75;
iprop.set_Value(ref val);
}
}



Below my most recent complete script:
(still not able to set params, though I can with C#)

import win32com.client, os

WIA_COM = "WIA.CommonDialog"
WIA_IMG_FORMAT_PNG = "{B96B3CAF-0728-11D3-9D7B-0000F81EF32E}"
WIA_COMMAND_TAKE_PICTURE="{AF933CAC-ACAD-11D2-A093-00C04F72DC3C}"

def takePictureOrNot(dev): # cameras have to call TakePicture
for command in dev.Commands:
if command.CommandID==WIA_COMMAND_TAKE_PICTURE:
print "take PICK"
foo=dev.ExecuteCommand(WIA_COMMAND_TAKE_PICTURE)

def setImgProps(item): # here scan properties should be set
for prop in item.Properties:
if prop.IsReadOnly: continue
if(prop.Name == "Horizontal Resolution"):
res = 250
print "trying to set",prop.Name,prop,"to ",res
### unfortunately the next line (if uncommented) fails
#prop.set_Value(res)

def transferImg(dev): # set properties and scan image
i=1
image = None
for item in dev.Items:
if i==dev.Items.Count:
setImgProps(item)
image=item.Transfer(WIA_IMG_FORMAT_PNG)
break
i=i+1
return image

def scan_image_wia():
wia = win32com.client.Dispatch(WIA_COM) # CommonDialog object
dev = wia.ShowSelectDevice()
takePictureOrNot(dev)
image = transferImg(dev)
return image

image = scan_image_wia()
fname = 'wia-test.jpg'
if os.path.exists(fname):
os.remove(fname)
image.SaveFile(fname)


bye

N
 
N

News123

MRAB said:
Well, according to that they /aren't/ read-only because it says:

if not p.IsReadOnly:
^^^
Exactly they are NOT read only, which means they are supposed to be
writable.

the python code is
for p in i.Properties:
if not.p.ISReadOnly:
# if I'm here I'm supposed to change them, but how?


the C# code, which succeds changing the property is:
foreach (Property prop in item.Properties){
if (prop.IsReadOnly) continue; // skip rest of loop
// if property cannot
// be modified
// now change property
if (prop.Name == "Horizontal Resolution")
{
IProperty iprop = (IProperty)prop;
Object val = 75;
iprop.set_Value(ref val);
}
}



The main question is the correct python method to change the property

prop = 300 # doesn't work as it just replaces the property with an integer

prop.set_Value(res) # doesn't work as the method set_Value doesn't seem
to exist
Traceback (most recent call last):
File "C:\WIA\scan_wia.py", line 41, in <module>
image = scan_image_wia()
File "C:\WIA\scan_wia.py", line 37, in scan_image_wia
image = transferImg(dev)
File "C:\WIA\scan_wia.py", line 27, in transferImg
setImgProps(item)
File "C:\WIA\scan_wia.py", line 20, in setImgProps
prop.set_Value(res)
File "C:\Python26\lib\site-packages\win32com\client\dynamic.py", line 512, in
__getattr__
raise AttributeError("%s.%s" % (self._username_, attr))
AttributeError: <unknown>.set_Value


bye


N
 
Ad

Advertisements

J

John Bokma

News123 said:
[..]

The main question is the correct python method to change the property

prop = 300 # doesn't work as it just replaces the property with an
integer

wild guess, but how about p.Value = 300 ?

John
 
Ad

Advertisements

N

News123

Hi John,

John said:
News123 said:
MRAB said:
News123 wrote:
r wrote:
more *maybe useful dump?

for i in dev.Items:
for p in i.Properties:
if not p.IsReadOnly:
print p.Name, '->', p.Value
[..]

The main question is the correct python method to change the property

prop = 300 # doesn't work as it just replaces the property with an
integer

wild guess, but how about p.Value = 300 ?

John

Wild and good guess indeed.

p.Value = 300 is working.

Finally I can do WIA scans and set the parameters.




How could I have found this out without guessing?

Or phrased differently: What would be the correct way to find out what
can be done with variables returned by win32com.client s.

I tried
dir(prop)
prop.__doc__
type(prop)

and got

['_ApplyTypes_', '_FlagAsMethod', '_LazyAddAttr_', '_NewEnum',
'_Release_', '__AttrToID__', '__LazyMap__', '__call__', '__doc__',
'__eq__', '__getattr__', '__getitem__', '__init__', '__int__',
'__len__', '__module__', '__ne__', '__nonzero__', '__repr__',
'__setattr__', '__setitem__', '__str__', '_builtMethods_', '_enum_',
'_find_dispatch_type_', '_get_good_object_', '_get_good_single_object_',
'_lazydata_', '_make_method_', '_mapCachedItems_', '_oleobj_',
'_olerepr_', '_print_details_', '_proc_', '_unicode_to_string_',
'_username_', '_wrap_dispatch_']

The dynamic class used as a last resort.
The purpose of this overriding of dynamic.CDispatch is to perpetuate the
policy
of using the makepy generated wrapper Python class instead of
dynamic.CDispatch if/when possible.


and
T <type 'instance'>

I'd like to avoid wild guessing when being confronted with another
win32.com object.


Thanks again

N
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top