tags:

views:

800

answers:

2

I am using TWAIN in C++ and I am trying to set the DPI manually so that a user is not displayed with the scan dialog but instead the page just scans with set defaults and is stored for them. I need to set the DPI manually but I can not seem to get it to work. I have tried setting the capability using the ICAP_XRESOLUTION and the ICAP_YRESOLUTION. When I look at the image's info though it always shows the same resolution no matter what I set it to using the ICAPs. Is there another way to set the resolution of a scanned in image or is there just an additional step that needs to be done that I can not find in the documentation anywhere?

Thanks

A: 

It should work the way.

But unfortunately we're not living in a perfect world. TWAIN drivers are among the most buggy drivers out there. Controlling the scanning process with TWAIN has always been a big headache because most drivers have never been tested without the scan dialog.

As far as I know there is also no test-suite for twain-drivers, so each of them will behave slightly different.

I wrote an OCR application back in the 90th and had to deal with these issues as well. What I ended up was having a list of supported scanners and a scanner module with lots of hacks and work-arounds for each different driver.

Take the ICAP_XRESOLUTION for example: The TWAIN documentation sais you have to send the resolution as a 32 bit float. Have you tried to set it using an integer instead? Or send it as float but put the bit-representation of an integer into the float, or vice versa. All this could work for the driver you're working with. Or it could not work at all.

I doubt the situation has changed much since then. So good luck getting it working on at least half of the machines that are out there.

Nils Pipenbrinck
I have pretty much tried all the above, int, float, int into float. It just doesn't seem to want to play nice. I have noticed that over all it is a fairly buggy driver. I have had to fight with TWAIN since day one to get much of anything to work. This is the only one however I have been unable to find a work around for. I just assumed that one existed that I am just missing or something
netadptr0719
you should have no problems getting a twain driver to deliver an image using the built-in GUI. I consider every functionality beyond that is experimental.
Nils Pipenbrinck
OH - btw. How many mainstream applications do you know that don't use the built-in TWAIN GUI. Let me guess: None.. Any idea why it is so?
Nils Pipenbrinck
Yeah, I would like to use the GUI, it would sure make this a lot easier. The whole goal of this is a point an click system though which involves minimal screen interaction.
netadptr0719
I wrote the freeware EZTwain back in 1994, and have been selling a commercial version since 1999. The majority of my customers run scanners with the UI suppressed, and inability to set the resolution is a very very rare problem. I concur that TWAIN drivers are buggy and poorly tested in the No-UI mode, but my experience doesn't support Nils' pessimism. Sorry if this sounds commercial, it's not meant to be. I've been writing TWAIN code for 10 years, I'm just kind of a nut on the subject... Happy to answer questions!
Spike0xff
+3  A: 

I use ICAP_XRESOLUTION and the ICAP_YRESOLUTION to set the scan resolution for a scanner, and it works at least for a number of HP scanners.

Code snipset:

float x_res = 1200;
cap.Cap = ICAP_XRESOLUTION;
cap.ConType = TWON_ONEVALUE;
cap.hContainer = GlobalAlloc(GHND, sizeof(TW_ONEVALUE));
if(cap.hContainer)
{
 val_p = (pTW_ONEVALUE)GlobalLock(cap.hContainer);
 val_p->ItemType = TWTY_FIX32;
 TW_FIX32 fix32_val = FloatToFIX32(x_res);
 val_p->Item = *((pTW_INT32) &fix32_val);
 GlobalUnlock(cap.hContainer);
 ret_code = SetCapability(cap);
 GlobalFree(cap.hContainer);
}

TW_FIX32 FloatToFIX32(float i_float)
{
    TW_FIX32 Fix32_value;
    TW_INT32 value = (TW_INT32) (i_float * 65536.0 + 0.5);
    Fix32_value.Whole = LOWORD(value >> 16);
    Fix32_value.Frac = LOWORD(value & 0x0000ffffL);
    return Fix32_value;
}

The value should be of type TW_FIX32 which is a floating point format defined by twain (strange but true).

I hope it works for you!

Dani van der Meer
Is there any reason FloatToFIX32 would return as an unidentified identifier?
netadptr0719
Sorry, forgot to add it.
Dani van der Meer
You sir are a hero, I hope this makes it to front page Google because this is documented almost nowhere at all. Where it is mentioned it isn't mentioned in much detail.
netadptr0719
Great to be a hero :) I must admit that I don't remember where I found it, it must be some 7 or 8 years ago.
Dani van der Meer
OK, I write TWAIN toolkits for a living, so I'm not a normal person - but what is this "documented almost nowhere at all"? The TWAIN spec says ICAP_XRESOLUTION takes a FIX32 value. You set capabilities by sending a MSG_SET. See "Controlling a TWAIN Session from Your Application" which provides C code for setting a capability. Dani's code is almost identical to the code in the TWAIN spec, and FloatToFIX32 is *verbatim* from the spec. TWAIN *is* a horribly written spec, no argument, but... surely you didn't try programming to the TWAIN API without reading the spec?
Spike0xff