3

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

skaffman
  • 398,947
  • 96
  • 818
  • 769
netadptr0719
  • 57
  • 1
  • 7

2 Answers2

6

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
  • 6,169
  • 3
  • 26
  • 45
  • Is there any reason FloatToFIX32 would return as an unidentified identifier? – netadptr0719 Jun 18 '09 at 14:41
  • 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 Jun 18 '09 at 14:54
  • 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 Jun 18 '09 at 14:59
  • 3
    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 Jul 02 '09 at 23:19
  • @Dani van der Meer, I have tried your code but it doesn't work for my "Plustek OpticSlim 500" after copy paste... I just want to make addition: Some drivers require to set DPI before "EnableSource", not AFTER. I used well-known TWAIN demo from codeproject and had to refactor Acquire method for my scanner. Hope it will help other poor guys who dive into TWAIN... – Andrew Florko Sep 16 '11 at 10:02
0

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
  • 83,631
  • 31
  • 151
  • 221
  • 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 Jun 18 '09 at 14:13
  • 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 Jun 18 '09 at 17:42
  • 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 Jun 18 '09 at 17:43
  • 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 Jun 18 '09 at 18:52
  • 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 Jul 02 '09 at 23:28