TWAIN Working Group

Newsletter Signup
Donate
Help keep TWAIN free
  • About TWAIN
    • What’s New?
    • News
    • Events
    • Membership
    • Consider a Donation
    • Contact Us
  • Why TWAIN?
  • Developers
    • Driver Developer
    • Application Developer
    • TWAIN Features
    • Specification & Tools
    • Self Certification Process
  • Support Forums
  • Scanner End-User
  • Find Certified Drivers
    • Facebook
    • LinkedIn
    • Vimeo

Scanning directly into a file

Forums › TWAIN Classic › Scanning directly into a file

  • This topic has 19 replies, 3 voices, and was last updated 13 years, 3 months ago by ZiggyShort.
Viewing 15 posts - 1 through 15 (of 20 total)
1 2 →
  • Author
    Posts
  • January 21, 2008 at 2:09 pm #22274 Reply
    ZiggyShort
    Participant
    • Topics - 4
    • Replies - 16
    • Total Posts - 20

    Hello,
    I found an article on Codeproject which gives a comprehensive example of scanning an image and loading it directly into a window.

    http://www.codeproject.com/KB/dotnet/twaindotnet.aspx

    When saving, however it will always save as 96 dpi. Is there any way of upping this?

    I looked at GdipSaveImageToFile and saw the last argument is an IntPtr based on an EncoderParameters variable, but couldn’t figure how to massage that in. Any attempt at a Marshal.StructureToPtr failed miserably.

    But also, is there any way of getting the scan directly into a file from the Twain, without getting the Image and saving that?

    Any help gratefully appreciated.

    ZiggyShort

    January 21, 2008 at 9:18 pm #24280 Reply
    Kaij
    Participant
    • Topics - 9
    • Replies - 132
    • Total Posts - 141

    You can scan direct into an image file if you select the FILE MODE as TWAIN transfer mode. Refer also to the TWAIN spec. The supported file formats are depending on the TWAIN data source.

    Best regards,
    Kaij

    January 21, 2008 at 10:38 pm #24281 Reply
    ZiggyShort
    Participant
    • Topics - 4
    • Replies - 16
    • Total Posts - 20

    I tried:

    rc = DSM_Entry(appid, srcds, TwDG.Control, TwDAT.SetupFileXfer, TwMSG.Set, twsfFile);

    where twsfFile is a SetupFileXfers structure.

    I am using C#. My SetupFileXfers structure is as follows:

    internal class SetupFileXfers
    {
    /* [MarshalAs( UnmanagedType.ByValArray, SizeConst=256)] – commented out */
    public Byte[] FileName = new Byte[256]; /* File to contain data */
    public UInt16 Format; /* A TWFF_xxxx constant */
    public IntPtr VrefNum; /* Used for Macintosh only */
    }

    I get a Failure report when this is called, but don’t know how to get an error code.
    I suspect the structure is wrong?

    January 22, 2008 at 5:38 am #24282 Reply
    gabe
    Participant
    • Topics - 9
    • Replies - 583
    • Total Posts - 592

    you’ll have to tweak this from vb.net, but for managed code this works.


    'TW_SETUPFILEXFER
    '''
    ''' Describes the file format and file specification information for a transfer through a disk file.
    '''

    ''' TW_SETUPFILEXFER from TWAIN Spec
    _
    Public Structure twSetupFileXfer

    #Region " C++ Reference "
    '/* DAT_SETUPFILEXFER. Sets up DS to application data transfer via a file. */
    'typedef struct {
    ' TW_STR255 FileName;
    ' TW_UINT16 Format; /* Any TWFF_ constant */
    ' TW_INT16 VRefNum; /* Used for Mac only */
    '} TW_SETUPFILEXFER, FAR * pTW_SETUPFILEXFER;
    #End Region

    '''
    ''' A complete file specifier to the target file. On Windows, be sure to include the
    ''' complete pathname.
    '''

    ''' Original type was TW_STR255.
    _
    Public FileName As String

    '''
    ''' The format of the file the Source is to fill. Fill with the correct constant—as
    ''' negotiated with the Source—of type TWFF_xxxx.
    '''

    ''' Original type was TW_UINT16
    Public Format As Enumerations.ImageFileFormat

    '''
    ''' The volume reference number for the file. This applies to Macintosh only. On
    ''' Windows, fill the field with TWON_DONTCARE16.
    '''

    ''' Original type was TW_INT16
    Public VrefNum As Int16

    End Structure

    and like Kaij said, you’ll have to set XferMode to File.

    .

    January 22, 2008 at 11:12 am #24283 Reply
    ZiggyShort
    Participant
    • Topics - 4
    • Replies - 16
    • Total Posts - 20

    Doesn’t the following setup the transfer mode to file?
    rc = DSM_Entry(appid, srcds, TwDG.Control, TwDAT.SetupFileXfer, TwMSG.Set, twsfFile);

    January 22, 2008 at 11:20 am #24284 Reply
    gabe
    Participant
    • Topics - 9
    • Replies - 583
    • Total Posts - 592

    nope, that tells the source where to put the file after the you’ve been notified that the source is ready to deliver the file to you

    to tell the source to use file for the XferMode I use something like:


    Public Function SetXferMech(ByVal value As String) As Boolean

    Dim xferMechVal As Enumerations.XferMech
    Select Case value

    Case Enumerations.XferMech.File.ToString
    xferMechVal = Enumerations.XferMech.File

    Case Enumerations.XferMech.Memory.ToString
    xferMechVal = Enumerations.XferMech.Memory

    Case Else
    xferMechVal = Enumerations.XferMech.Native

    End Select

    'SetXferMode(_Profile.TransferMode)
    '//
    alias the namespace for shorter calls (not needed, just prettier)
    Dim cap_XferMech As Enumerations.Capability = Enumerations.Capability.Icap_XferMech

    '//
    prep the container
    Dim XferMechOneval As New DataStructures.twOneValue
    XferMechOneval.ItemType = DataStructures.twCapability.CapType(cap_XferMech)
    XferMechOneval.Item = xferMechVal

    '//
    create the CapStruc with the container
    Dim capXferMech As New DataStructures.twCapability(cap_XferMech, XferMechOneval)

    '//
    set the Cap
    Dim retBool As Boolean = OperationTriplets.Control.Capability.Set(capXferMech)

    Return retBool

    End Function

    and I call that function after/If OpenDs returns twSuccess but before EnableDs gets called

    .

    January 22, 2008 at 12:09 pm #24285 Reply
    ZiggyShort
    Participant
    • Topics - 4
    • Replies - 16
    • Total Posts - 20

    I pumped that code through a VB to C# converter (see http://labs.developerfusion.co.uk/convert/vb-to-csharp.aspx)
    so it’s easier for me to follow, and got the following:

    public bool SetXferMech(string value)
    {
    Enumerations.XferMech xferMechVal;

    switch (value) {
    case Enumerations.XferMech.File.ToString:
    xferMechVal = Enumerations.XferMech.File;
    break;
    case Enumerations.XferMech.Memory.ToString:
    xferMechVal = Enumerations.XferMech.Memory;
    break;
    default:
    xferMechVal = Enumerations.XferMech.Native;
    break;
    }

    //SetXferMode(_Profile.TransferMode)
    ////


    alias the namespace for shorter calls (not needed, just prettier)
    Enumerations.Capability cap_XferMech = Enumerations.Capability.Icap_XferMech;

    //prep the container
    DataStructures.twOneValue XferMechOneval = new DataStructures.twOneValue();
    XferMechOneval.ItemType = DataStructures.twCapability.CapType(cap_XferMech);
    XferMechOneval.Item = xferMechVal;

    //create the CapStruc with the container
    DataStructures.twCapability capXferMech = new DataStructures.twCapability(cap_XferMech, XferMechOneval);
    //set the Cap
    bool retBool = OperationTriplets.Control.Capability.Set(capXferMech);
    return retBool;
    }

    Where can I download your classes eg. OperationTriplets.Control.Capability.Set – I assume that equates to

    DSM_Entry(..,..,Control, Capability, Set, Val);
    //OperationTriplets.Control.Capability.Set equates to :

    January 22, 2008 at 12:12 pm #24286 Reply
    gabe
    Participant
    • Topics - 9
    • Replies - 583
    • Total Posts - 592

    they’re all in the opentwain project:
    http://www.codeplex.com/opentwain

    on the releases tab, I think the most current one is named december 2007

    .

    January 22, 2008 at 12:56 pm #24287 Reply
    ZiggyShort
    Participant
    • Topics - 4
    • Replies - 16
    • Total Posts - 20

    I succeed in setting up the capability via:

    TwCapability cap2 = new TwCapability(TwCap.IXferMech, (short) TwXferMech.FILE);
    rc = DScap(appid, srcds, TwDG.Control, TwDAT.Capability, TwMSG.Set, cap2);

    rc returns success.

    I still get a failure later on in

    rc = DSsetupFileXfer(appid, srcds, TwDG.Control, TwDAT.SetupFileXfer, TwMSG.Set, twsfFile);

    Where DSsetupFileXfer is:

    [DllImport(“twain_32.dll”, EntryPoint = “#1”)]
    private static extern TwRC DSsetupFileXfer([In, Out] TwIdentity origin, [In] TwIdentity dest, TwDG dg, TwDAT dat, TwMSG msg, TwSetupFileXfers sfxfr);

    I have setup TwSetupFileXfers as follows:
    internal class TwSetupFileXfers
    {
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst=256)]
    public Byte[] FileName = new Byte[256]; /* File to contain data */
    public UInt16 Format; /* A TWFF_xxxx constant */
    public IntPtr VrefNum; /* Used for Macintosh only */
    }

    How do I get an error message back?

    January 22, 2008 at 1:05 pm #24288 Reply
    gabe
    Participant
    • Topics - 9
    • Replies - 583
    • Total Posts - 592

    I don’t know if it is going to make a different but I define twSetupFileXfer a little different,


    'TW_SETUPFILEXFER
    '''
    ''' Describes the file format and file specification information for a transfer through a disk file.
    '''

    ''' TW_SETUPFILEXFER from TWAIN Spec
    _
    Public Structure twSetupFileXfer

    #Region " C++ Reference "
    '/* DAT_SETUPFILEXFER. Sets up DS to application data transfer via a file. */
    'typedef struct {
    ' TW_STR255 FileName;
    ' TW_UINT16 Format; /* Any TWFF_ constant */
    ' TW_INT16 VRefNum; /* Used for Mac only */
    '} TW_SETUPFILEXFER, FAR * pTW_SETUPFILEXFER;
    #End Region

    '''
    ''' A complete file specifier to the target file. On Windows, be sure to include the
    ''' complete pathname.
    '''

    ''' Original type was TW_STR255.
    _
    Public FileName As String

    '''
    ''' The format of the file the Source is to fill. Fill with the correct constant—as
    ''' negotiated with the Source—of type TWFF_xxxx.
    '''

    ''' Original type was TW_UINT16
    Public Format As Enumerations.ImageFileFormat

    '''
    ''' The volume reference number for the file. This applies to Macintosh only. On
    ''' Windows, fill the field with TWON_DONTCARE16.
    '''

    ''' Original type was TW_INT16
    Public VrefNum As Int16

    End Structure

    then ::GetLastError *may* provide some information, but if memory serves GetLastError didn’t always return the stuff you thought it should when called from .net depending on how you you’re pinvoke was defined.

    that said, if you’ve already pulled down the openTwain a working model of the code you’re looking for is in the cTwain.vb file in a method named TransferPicturesAsFile.

    .

    January 22, 2008 at 1:12 pm #24289 Reply
    ZiggyShort
    Participant
    • Topics - 4
    • Replies - 16
    • Total Posts - 20

    Just changed my TwSetupFileXfers back to :

    internal class TwSetupFileXfers
    {
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
    //public Byte[] FileName = new Byte[256]; /* File to contain data */
    public string FileName = “”;
    public UInt16 Format; /* A TWFF_xxxx constant */
    public IntPtr VrefNum; /* Used for Macintosh only */
    }

    This STILL returns Failure.

    January 22, 2008 at 1:16 pm #24290 Reply
    gabe
    Participant
    • Topics - 9
    • Replies - 583
    • Total Posts - 592

    yes. but our class and structure don’t look alike.

    my structure is decorated with
    _

    your class isn’t

    January 22, 2008 at 1:18 pm #24291 Reply
    gabe
    Participant
    • Topics - 9
    • Replies - 583
    • Total Posts - 592

    and you’re welcome to open an IM.
    you have my gmail address.

    January 22, 2008 at 1:23 pm #24292 Reply
    gabe
    Participant
    • Topics - 9
    • Replies - 583
    • Total Posts - 592

    and while we’re at it some of this is coming back to me (probably because I had a look thru the source code)

    I don’t save the image from the DIB the way NetMaster shows in his interop artacle. …It didn’t do what I wanted for some reason ( but honestly that part hasn’t come back to me yet), and I switched to using SetDIBitsToDevice, but the part that struck me was that I don’t update the dpi with the GdipBitmapSetResolution call because I never got the drivers that I test with to give me dpi in a way that makes sense.

    I did however build the project at one time with an option to update the resolution but I just used the SetResolution method (System.Drawing.Bitmap.SetResolution).

    I know why I don’t fiddle with the resolution (my scanner’s driver wanted to tell me that the x and yResolution was 7432 or something when I thought it was 300) but why don’t you use SetResolution from the framework instead?

    just wondering, it shouldn’t impact your current error.

    January 22, 2008 at 1:37 pm #24293 Reply
    ZiggyShort
    Participant
    • Topics - 4
    • Replies - 16
    • Total Posts - 20

    I remember getting something daft like 11811 – which, if you divide by 39.37 …. something gives 300 – 39.37 inches in a meter.

    Thanks for all your help. I have grabbed the download, and will give that a go.

  • Author
    Posts
Viewing 15 posts - 1 through 15 (of 20 total)
1 2 →
Reply To: Reply #24289 in Scanning directly into a file
Your information:




Quick Links

Service Providers
TWAIN Support Forums
Membership
Contact Us
Privacy Policy

Newsletter Signup

TWAIN Working Group Family

TWAIN Working Group
TWAIN Direct®
TWAIN Resources
TWAIN Certified Drivers
PDF/raster

  • Facebook
  • GitHub
  • LinkedIn
  • Vimeo

Recent Topics

  • TWAIN for dental imaging integration
  • PDF/R For who and where?
  • Making searchable PDF with PDF/R
  • Backward compatibility with PDF/A and traditional PDF
  • could not open the twain source. Make sure there is a valid source for your sca
  • Quarterly Newsletter
  • TWAIN Working Group Membership
  • Logo Usage
  • TWAIN License
  • Contact Us
Privacy Policy • Privacy Tools • Copyright © 2021 TWAIN Working Group • by iHwy, LLC • Log in

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.