首页 新闻 会员 周边 捐助

WindowsForm一个用TWAIN调用扫描仪的程序!

0
悬赏园豆:80 [已关闭问题]

关于这个例子,它是实现用“TWAIN”调用扫描设备(后来经实验,任何图像采录设备,只要驱动安装完好,就可调用)进行图像扫描,返回图像到“PICTUREBOX”里。

但该例子,不尽完美。就是在扫描图片时,圈定多个扫描区域,理应返回对应的区域的图片对像,为什么返回的图片对像只有一个,(就是激活那个圈定区域)可否返回多个图片对像?这也是一直困扰着我的难题。。。希望群友们试验一下,如解决了问题,请上传一份,供大家一同进步。。。

今天同样也试验过几次,我使用的扫描设备是:CANON LIDE 200 还是回传一个图片对像(打电话到CANON技术部去问,他们说‘自带的驱动只能选定一个区域扫描,返回一个图片对像。但是驱程光盘里的自带的软件“ArcSoft PhotoStudio 5.5”却能圈定多个区域,返回多个图片对像。不知是那个工程师“猪”,还是在忽悠我想早点下班,因为那时是午饭时间),但奇怪的是,我当时用最原始版本去试 BENQ 的一台扫描议时(具体什么型号,忘了),程序能识别为多个“扫描裁剪区”但可惜的是当时那个版本只有一个“PICTUREBOX”在里边,那天也忙,没多试了(那次的目的,只是想去证实程序的兼容性问题)。所以希望有BENQ扫描议的群友多试试,或许一试就能解决。

另,从朋友那借回了一台“高拍仪”,程序却正常得不得了,你拍多少张,只要选定回传,就给你回传多少个,那么从这个角度来分析,程序本身是具备多对像回传的,可能是在扫描仪那块对于选定扫描区域的API没有做好完整的逻辑。。。;还有就是,为了能得到相应的扫描区域,而不用重复鼠标动作,程序里是通过对窗体有多少个“PICTUREBOX”来判断按多少次“button_Click”。。。


希望以上能给大家一个线索。。。以及共同进步的话题。。。

代码TwainLib.cs
1 using System;
2  using System.Collections;
3  using System.Runtime.InteropServices;
4  using System.Windows.Forms;
5
6  namespace TwainLib
7 {
8  public enum TwainCommand
9 {
10 Not = -1,
11 Null = 0,
12 TransferReady = 1,
13 CloseRequest = 2,
14 CloseOk = 3,
15 DeviceEvent = 4
16 }
17
18
19
20
21  public class Twain
22 {
23 private const short CountryUSA = 1;
24 private const short LanguageUSA = 13;
25
26 public Twain()
27 {
28 appid = new TwIdentity();
29 appid.Id = IntPtr.Zero;
30 appid.Version.MajorNum = 1;
31 appid.Version.MinorNum = 1;
32 appid.Version.Language = LanguageUSA;
33 appid.Version.Country = CountryUSA;
34 appid.Version.Info = "Hack 1";
35 appid.ProtocolMajor = TwProtocol.Major;
36 appid.ProtocolMinor = TwProtocol.Minor;
37 appid.SupportedGroups = (int)(TwDG.Image | TwDG.Control);
38 appid.Manufacturer = "NETMaster";
39 appid.ProductFamily = "Freeware";
40 appid.ProductName = "Hack";
41
42 srcds = new TwIdentity();
43 srcds.Id = IntPtr.Zero;
44
45 evtmsg.EventPtr = Marshal.AllocHGlobal( Marshal.SizeOf( winmsg ) );
46 }
47
48 ~Twain()
49 {
50 Marshal.FreeHGlobal( evtmsg.EventPtr );
51 }
52
53
54
55
56 public void Init( IntPtr hwndp )
57 {
58 Finish();
59 TwRC rc = DSMparent( appid, IntPtr.Zero, TwDG.Control, TwDAT.Parent, TwMSG.OpenDSM, ref hwndp );
60 if( rc == TwRC.Success )
61 {
62 rc = DSMident( appid, IntPtr.Zero, TwDG.Control, TwDAT.Identity, TwMSG.GetDefault, srcds );
63 if( rc == TwRC.Success )
64 hwnd = hwndp;
65 else
66 rc = DSMparent( appid, IntPtr.Zero, TwDG.Control, TwDAT.Parent, TwMSG.CloseDSM, ref hwndp );
67 }
68 }
69
70 public void Select()
71 {
72 TwRC rc;
73 CloseSrc();
74 if( appid.Id == IntPtr.Zero )
75 {
76 Init( hwnd );
77 if( appid.Id == IntPtr.Zero )
78 return;
79 }
80 rc = DSMident( appid, IntPtr.Zero, TwDG.Control, TwDAT.Identity, TwMSG.UserSelect, srcds );
81 }
82
83
84 public void Acquire()
85 {
86 TwRC rc;
87 CloseSrc();
88 if( appid.Id == IntPtr.Zero )
89 {
90 Init( hwnd );
91 if( appid.Id == IntPtr.Zero )
92 return;
93 }
94 rc = DSMident( appid, IntPtr.Zero, TwDG.Control, TwDAT.Identity, TwMSG.OpenDS, srcds );
95 if( rc != TwRC.Success )
96 return;
97
98 TwCapability cap = new TwCapability( TwCap.XferCount, 1 );
99 rc = DScap( appid, srcds, TwDG.Control, TwDAT.Capability, TwMSG.Set, cap );
100 if( rc != TwRC.Success )
101 {
102 CloseSrc();
103 return;
104 }
105
106 TwUserInterface guif = new TwUserInterface();
107 guif.ShowUI = 1;
108 guif.ModalUI = 1;
109 guif.ParentHand = hwnd;
110 rc = DSuserif( appid, srcds, TwDG.Control, TwDAT.UserInterface, TwMSG.EnableDS, guif );
111 if( rc != TwRC.Success )
112 {
113 CloseSrc();
114 return;
115 }
116 }
117
118
119 public ArrayList TransferPictures()
120 {
121 ArrayList pics = new ArrayList();
122 if( srcds.Id == IntPtr.Zero )
123 return pics;
124
125 TwRC rc;
126 IntPtr hbitmap = IntPtr.Zero;
127 TwPendingXfers pxfr = new TwPendingXfers();
128
129 do
130 {
131 pxfr.Count = 0;
132 hbitmap = IntPtr.Zero;
133
134 TwImageInfo iinf = new TwImageInfo();
135 rc = DSiinf( appid, srcds, TwDG.Image, TwDAT.ImageInfo, TwMSG.Get, iinf );
136 if( rc != TwRC.Success )
137 {
138 CloseSrc();
139 return pics;
140 }
141
142 rc = DSixfer( appid, srcds, TwDG.Image, TwDAT.ImageNativeXfer, TwMSG.Get, ref hbitmap );
143 if( rc != TwRC.XferDone )
144 {
145 CloseSrc();
146 return pics;
147 }
148
149 rc = DSpxfer( appid, srcds, TwDG.Control, TwDAT.PendingXfers, TwMSG.EndXfer, pxfr );
150 if( rc != TwRC.Success )
151 {
152 CloseSrc();
153 return pics;
154 }
155
156 pics.Add( hbitmap );
157 }
158 while( pxfr.Count != 0 );
159
160 rc = DSpxfer( appid, srcds, TwDG.Control, TwDAT.PendingXfers, TwMSG.Reset, pxfr );
161 return pics;
162 }
163
164
165 public TwainCommand PassMessage( ref Message m )
166 {
167 if( srcds.Id == IntPtr.Zero )
168 return TwainCommand.Not;
169
170 int pos = GetMessagePos();
171
172 winmsg.hwnd = m.HWnd;
173 winmsg.message = m.Msg;
174 winmsg.wParam = m.WParam;
175 winmsg.lParam = m.LParam;
176 winmsg.time = GetMessageTime();
177 winmsg.x = (short) pos;
178 winmsg.y = (short) (pos >> 16);
179
180 Marshal.StructureToPtr( winmsg, evtmsg.EventPtr, false );
181 evtmsg.Message = 0;
182 TwRC rc = DSevent( appid, srcds, TwDG.Control, TwDAT.Event, TwMSG.ProcessEvent, ref evtmsg );
183 if( rc == TwRC.NotDSEvent )
184 return TwainCommand.Not;
185 if( evtmsg.Message == (short) TwMSG.XFerReady )
186 return TwainCommand.TransferReady;
187 if( evtmsg.Message == (short) TwMSG.CloseDSReq )
188 return TwainCommand.CloseRequest;
189 if( evtmsg.Message == (short) TwMSG.CloseDSOK )
190 return TwainCommand.CloseOk;
191 if( evtmsg.Message == (short) TwMSG.DeviceEvent )
192 return TwainCommand.DeviceEvent;
193
194 return TwainCommand.Null;
195 }
196
197 public void CloseSrc()
198 {
199 TwRC rc;
200 if( srcds.Id != IntPtr.Zero )
201 {
202 TwUserInterface guif = new TwUserInterface();
203 rc = DSuserif( appid, srcds, TwDG.Control, TwDAT.UserInterface, TwMSG.DisableDS, guif );
204 rc = DSMident( appid, IntPtr.Zero, TwDG.Control, TwDAT.Identity, TwMSG.CloseDS, srcds );
205 }
206 }
207
208 public void Finish()
209 {
210 TwRC rc;
211 CloseSrc();
212 if( appid.Id != IntPtr.Zero )
213 rc = DSMparent( appid, IntPtr.Zero, TwDG.Control, TwDAT.Parent, TwMSG.CloseDSM, ref hwnd );
214 appid.Id = IntPtr.Zero;
215 }
216
217 private IntPtr hwnd;
218 private TwIdentity appid;
219 private TwIdentity srcds;
220 private TwEvent evtmsg;
221 private WINMSG winmsg;
222
223
224
225 // ------ DSM entry point DAT_ variants:
226   [DllImport("twain_32.dll", EntryPoint="#1")]
227 private static extern TwRC DSMparent( [In, Out] TwIdentity origin, IntPtr zeroptr, TwDG dg, TwDAT dat, TwMSG msg, ref IntPtr refptr );
228
229 [DllImport("twain_32.dll", EntryPoint="#1")]
230 private static extern TwRC DSMident( [In, Out] TwIdentity origin, IntPtr zeroptr, TwDG dg, TwDAT dat, TwMSG msg, [In, Out] TwIdentity idds );
231
232 [DllImport("twain_32.dll", EntryPoint="#1")]
233 private static extern TwRC DSMstatus( [In, Out] TwIdentity origin, IntPtr zeroptr, TwDG dg, TwDAT dat, TwMSG msg, [In, Out] TwStatus dsmstat );
234
235
236 // ------ DSM entry point DAT_ variants to DS:
237 [DllImport("twain_32.dll", EntryPoint="#1")]
238 private static extern TwRC DSuserif( [In, Out] TwIdentity origin, [In, Out] TwIdentity dest, TwDG dg, TwDAT dat, TwMSG msg, TwUserInterface guif );
239
240 [DllImport("twain_32.dll", EntryPoint="#1")]
241 private static extern TwRC DSevent( [In, Out] TwIdentity origin, [In, Out] TwIdentity dest, TwDG dg, TwDAT dat, TwMSG msg, ref TwEvent evt );
242
243 [DllImport("twain_32.dll", EntryPoint="#1")]
244 private static extern TwRC DSstatus( [In, Out] TwIdentity origin, [In] TwIdentity dest, TwDG dg, TwDAT dat, TwMSG msg, [In, Out] TwStatus dsmstat );
245
246 [DllImport("twain_32.dll", EntryPoint="#1")]
247 private static extern TwRC DScap( [In, Out] TwIdentity origin, [In] TwIdentity dest, TwDG dg, TwDAT dat, TwMSG msg, [In, Out] TwCapability capa );
248
249 [DllImport("twain_32.dll", EntryPoint="#1")]
250 private static extern TwRC DSiinf( [In, Out] TwIdentity origin, [In] TwIdentity dest, TwDG dg, TwDAT dat, TwMSG msg, [In, Out] TwImageInfo imginf );
251
252 [DllImport("twain_32.dll", EntryPoint="#1")]
253 private static extern TwRC DSixfer( [In, Out] TwIdentity origin, [In] TwIdentity dest, TwDG dg, TwDAT dat, TwMSG msg, ref IntPtr hbitmap );
254
255 [DllImport("twain_32.dll", EntryPoint="#1")]
256 private static extern TwRC DSpxfer( [In, Out] TwIdentity origin, [In] TwIdentity dest, TwDG dg, TwDAT dat, TwMSG msg, [In, Out] TwPendingXfers pxfr );
257
258
259 [DllImport("kernel32.dll", ExactSpelling=true)]
260 internal static extern IntPtr GlobalAlloc( int flags, int size );
261 [DllImport("kernel32.dll", ExactSpelling=true)]
262 internal static extern IntPtr GlobalLock( IntPtr handle );
263 [DllImport("kernel32.dll", ExactSpelling=true)]
264 internal static extern bool GlobalUnlock( IntPtr handle );
265 [DllImport("kernel32.dll", ExactSpelling=true)]
266 internal static extern IntPtr GlobalFree( IntPtr handle );
267
268 [DllImport("user32.dll", ExactSpelling=true)]
269 private static extern int GetMessagePos();
270 [DllImport("user32.dll", ExactSpelling=true)]
271 private static extern int GetMessageTime();
272
273
274 [DllImport("gdi32.dll", ExactSpelling=true)]
275 private static extern int GetDeviceCaps( IntPtr hDC, int nIndex );
276
277 [DllImport("gdi32.dll", CharSet=CharSet.Auto)]
278 private static extern IntPtr CreateDC( string szdriver, string szdevice, string szoutput, IntPtr devmode );
279
280 [DllImport("gdi32.dll", ExactSpelling=true)]
281 private static extern bool DeleteDC( IntPtr hdc );
282
283
284
285
286 public static int ScreenBitDepth {
287 get {
288 IntPtr screenDC = CreateDC( "DISPLAY", null, null, IntPtr.Zero );
289 int bitDepth = GetDeviceCaps( screenDC, 12 );
290 bitDepth *= GetDeviceCaps( screenDC, 14 );
291 DeleteDC( screenDC );
292 return bitDepth;
293 }
294 }
295
296
297 [StructLayout(LayoutKind.Sequential, Pack=4)]
298 internal struct WINMSG
299 {
300 public IntPtr hwnd;
301 public int message;
302 public IntPtr wParam;
303 public IntPtr lParam;
304 public int time;
305 public int x;
306 public int y;
307 }
308
309
310 } // class Twain
代码TwainDefs.cs
1 using System;
2 using System.Runtime.InteropServices;
3 using System.Windows.Forms;
4
5 namespace TwainLib
6 {
7
8 public class TwProtocol
9 { // TWON_PROTOCOL...
10 public const short Major = 1;
11 public const short Minor = 9;
12 }
13
14
15 [Flags]
16 internal enum TwDG : short
17 { // DG_.....
18 Control = 0x0001,
19 Image = 0x0002,
20 Audio = 0x0004
21 }
22
23 internal enum TwDAT : short
24 { // DAT_....
25 Null = 0x0000,
26 Capability = 0x0001,
27 Event = 0x0002,
28 Identity = 0x0003,
29 Parent = 0x0004,
30 PendingXfers = 0x0005,
31 SetupMemXfer = 0x0006,
32 SetupFileXfer = 0x0007,
33 Status = 0x0008,
34 UserInterface = 0x0009,
35 XferGroup = 0x000a,
36 TwunkIdentity = 0x000b,
37 CustomDSData = 0x000c,
38 DeviceEvent = 0x000d,
39 FileSystem = 0x000e,
40 PassThru = 0x000f,
41
42 ImageInfo = 0x0101,
43 ImageLayout = 0x0102,
44 ImageMemXfer = 0x0103,
45 ImageNativeXfer = 0x0104,
46 ImageFileXfer = 0x0105,
47 CieColor = 0x0106,
48 GrayResponse = 0x0107,
49 RGBResponse = 0x0108,
50 JpegCompression = 0x0109,
51 Palette8 = 0x010a,
52 ExtImageInfo = 0x010b,
53
54 SetupFileXfer2 = 0x0301
55 }
56
57 internal enum TwMSG : short
58 { // MSG_.....
59 Null = 0x0000,
60 Get = 0x0001,
61 GetCurrent = 0x0002,
62 GetDefault = 0x0003,
63 GetFirst = 0x0004,
64 GetNext = 0x0005,
65 Set = 0x0006,
66 Reset = 0x0007,
67 QuerySupport = 0x0008,
68
69 XFerReady = 0x0101,
70 CloseDSReq = 0x0102,
71 CloseDSOK = 0x0103,
72 DeviceEvent = 0x0104,
73
74 CheckStatus = 0x0201,
75
76 OpenDSM = 0x0301,
77 CloseDSM = 0x0302,
78
79 OpenDS = 0x0401,
80 CloseDS = 0x0402,
81 UserSelect = 0x0403,
82
83 DisableDS = 0x0501,
84 EnableDS = 0x0502,
85 EnableDSUIOnly = 0x0503,
86
87 ProcessEvent = 0x0601,
88
89 EndXfer = 0x0701,
90 StopFeeder = 0x0702,
91
92 ChangeDirectory = 0x0801,
93 CreateDirectory = 0x0802,
94 Delete = 0x0803,
95 FormatMedia = 0x0804,
96 GetClose = 0x0805,
97 GetFirstFile = 0x0806,
98 GetInfo = 0x0807,
99 GetNextFile = 0x0808,
100 Rename = 0x0809,
101 Copy = 0x080A,
102 AutoCaptureDir = 0x080B,
103
104 PassThru = 0x0901
105 }
106
107
108 internal enum TwRC : short
109 { // TWRC_....
110 Success = 0x0000,
111 Failure = 0x0001,
112 CheckStatus = 0x0002,
113 Cancel = 0x0003,
114 DSEvent = 0x0004,
115 NotDSEvent = 0x0005,
116 XferDone = 0x0006,
117 EndOfList = 0x0007,
118 InfoNotSupported = 0x0008,
119 DataNotAvailable = 0x0009
120 }
121
122 internal enum TwCC : short
123 { // TWCC_....
124 Success = 0x0000,
125 Bummer = 0x0001,
126 LowMemory = 0x0002,
127 NoDS = 0x0003,
128 MaxConnections = 0x0004,
129 OperationError = 0x0005,
130 BadCap = 0x0006,
131 BadProtocol = 0x0009,
132 BadValue = 0x000a,
133 SeqError = 0x000b,
134 BadDest = 0x000c,
135 CapUnsupported = 0x000d,
136 CapBadOperation = 0x000e,
137 CapSeqError = 0x000f,
138 Denied = 0x0010,
139 FileExists = 0x0011,
140 FileNotFound = 0x0012,
141 NotEmpty = 0x0013,
142 PaperJam = 0x0014,
143 PaperDoubleFeed = 0x0015,
144 FileWriteError = 0x0016,
145 CheckDeviceOnline = 0x0017
146 }
147
148
149
150
151 internal enum TwOn : short
152 { // TWON_....
153 Array = 0x0003,
154 Enum = 0x0004,
155 One = 0x0005,
156 Range = 0x0006,
157 DontCare = -1
158 }
159
160 internal enum TwType : short
161 { // TWTY_....
162 Int8 = 0x0000,
163 Int16 = 0x0001,
164 Int32 = 0x0002,
165 UInt8 = 0x0003,
166 UInt16 = 0x0004,
167 UInt32 = 0x0005,
168 Bool = 0x0006,
169 Fix32 = 0x0007,
170 Frame = 0x0008,
171 Str32 = 0x0009,
172 Str64 = 0x000a,
173 Str128 = 0x000b,
174 Str255 = 0x000c,
175 Str1024 = 0x000d,
176 Str512 = 0x000e
177 }
178
179
180 internal enum TwCap : short
181 {
182 XferCount = 0x0001, // CAP_XFERCOUNT
183 ICompression = 0x0100, // ICAP_...
184 IPixelType = 0x0101,
185 IUnits = 0x0102,
186 IXferMech = 0x0103
187 }
188
189
190
191
192
193
194
195
196
197
198 // ------------------- STRUCTS --------------------------------------------
199
200 [StructLayout(LayoutKind.Sequential, Pack=2, CharSet=CharSet.Ansi)]
201 internal class TwIdentity
202 { // TW_IDENTITY
203 public IntPtr Id;
204 public TwVersion Version;
205 public short ProtocolMajor;
206 public short ProtocolMinor;
207 public int SupportedGroups;
208 [MarshalAs(UnmanagedType.ByValTStr, SizeConst=34)]
209 public string Manufacturer;
210 [MarshalAs(UnmanagedType.ByValTStr, SizeConst=34)]
211 public string ProductFamily;
212 [MarshalAs(UnmanagedType.ByValTStr, SizeConst=34)]
213 public string ProductName;
214 }
215
216 [StructLayout(LayoutKind.Sequential, Pack=2, CharSet=CharSet.Ansi)]
217 internal struct TwVersion
218 { // TW_VERSION
219 public short MajorNum;
220 public short MinorNum;
221 public short Language;
222 public short Country;
223 [MarshalAs(UnmanagedType.ByValTStr, SizeConst=34)]
224 public string Info;
225 }
226
227 [StructLayout(LayoutKind.Sequential, Pack=2)]
228 internal class TwUserInterface
229 { // TW_USERINTERFACE
230 public short ShowUI; // bool is strictly 32 bit, so use short
231 public short ModalUI;
232 public IntPtr ParentHand;
233 }
234
235 [StructLayout(LayoutKind.Sequential, Pack=2)]
236 internal class TwStatus
237 { // TW_STATUS
238 public short ConditionCode; // TwCC
239 public short Reserved;
240 }
241
242 [StructLayout(LayoutKind.Sequential, Pack=2)]
243 internal struct TwEvent
244 { // TW_EVENT
245 public IntPtr EventPtr;
246 public short Message;
247 }
248
249
250 [StructLayout(LayoutKind.Sequential, Pack=2)]
251 internal class TwImageInfo
252 { // TW_IMAGEINFO
253 public int XResolution;
254 public int YResolution;
255 public int ImageWidth;
256 public int ImageLength;
257 public short SamplesPerPixel;
258 [MarshalAs( UnmanagedType.ByValArray, SizeConst=8)]
259 public short[] BitsPerSample;
260 public short BitsPerPixel;
261 public short Planar;
262 public short PixelType;
263 public short Compression;
264 }
265
266 [StructLayout(LayoutKind.Sequential, Pack=2)]
267 internal class TwPendingXfers
268 { // TW_PENDINGXFERS
269 public short Count;
270 public int EOJ;
271 }
272
273
274
275
276
277
278 [StructLayout(LayoutKind.Sequential, Pack=2)]
279 internal struct TwFix32
280 { // TW_FIX32
281 public short Whole;
282 public ushort Frac;
283
284 public float ToFloat()
285 {
286 return (float) Whole + ( (float)Frac /65536.0f );
287 }
288 public void FromFloat( float f )
289 {
290 int i = (int)((f * 65536.0f) + 0.5f);
291 Whole = (short) (i >> 16);
292 Frac = (ushort) (i & 0x0000ffff);
293 }
294 }
295
296
297
298
299
300
301
302 [StructLayout(LayoutKind.Sequential, Pack=2)]
303 internal class TwCapability
304 { // TW_CAPABILITY
305 public TwCapability( TwCap cap )
306 {
307 Cap = (short) cap;
308 ConType = -1;
309 }
310 public TwCapability( TwCap cap, short sval )
311 {
312 Cap = (short) cap;
313 ConType = (short) TwOn.One;
314 Handle = Twain.GlobalAlloc( 0x42, 6 );
315 IntPtr pv = Twain.GlobalLock( Handle );
316 Marshal.WriteInt16( pv, 0, (short) TwType.Int16 );
317 Marshal.WriteInt32( pv, 2, (int) sval );
318 Twain.GlobalUnlock( Handle );
319 }
320 ~TwCapability()
321 {
322 if( Handle != IntPtr.Zero )
323 Twain.GlobalFree( Handle );
324 }
325 public short Cap;
326 public short ConType;
327 public IntPtr Handle;
328 }
329
330
331
332
333
334
335
336
337 } // namespace TwainLib
338

 

代码GdiPlusLib.cs
1 using System;
2 using System.IO;
3 using System.Collections;
4 using System.Runtime.InteropServices;
5 using System.Drawing;
6 using System.Drawing.Imaging;
7 using System.Windows.Forms;
8
9 namespace GdiPlusLib
10 {
11
12
13 public class Gdip
14 {
15 private static ImageCodecInfo[] codecs = ImageCodecInfo.GetImageEncoders();
16
17 private static bool GetCodecClsid( string filename, out Guid clsid )
18 {
19 clsid = Guid.Empty;
20 string ext = Path.GetExtension( filename );
21 if( ext == null )
22 return false;
23 ext = "*" + ext.ToUpper();
24 foreach( ImageCodecInfo codec in codecs )
25 {
26 if( codec.FilenameExtension.IndexOf( ext ) >= 0 )
27 {
28 clsid = codec.Clsid;
29 return true;
30 }
31 }
32 return false;
33 }
34
35
36 public static bool SaveDIBAs( string picname, IntPtr bminfo, IntPtr pixdat )
37 {
38 SaveFileDialog sd = new SaveFileDialog();
39
40 sd.FileName = picname;
41 sd.Title = "Save bitmap as...";
42 sd.Filter = "Bitmap file (*.bmp)|*.bmp|TIFF file (*.tif)|*.tif|JPEG file (*.jpg)|*.jpg|PNG file (*.png)|*.png|GIF file (*.gif)|*.gif|All files (*.*)|*.*";
43 sd.FilterIndex = 1;
44 if( sd.ShowDialog() != DialogResult.OK )
45 return false;
46
47 Guid clsid;
48 if( ! GetCodecClsid( sd.FileName, out clsid ) )
49 {
50 MessageBox.Show( "Unknown picture format for extension " + Path.GetExtension( sd.FileName ),
51 "Image Codec", MessageBoxButtons.OK, MessageBoxIcon.Information );
52 return false;
53 }
54
55 IntPtr img = IntPtr.Zero;
56 int st = GdipCreateBitmapFromGdiDib( bminfo, pixdat, ref img );
57 if( (st != 0) || (img == IntPtr.Zero) )
58 return false;
59
60 st = GdipSaveImageToFile( img, sd.FileName, ref clsid, IntPtr.Zero );
61 GdipDisposeImage( img );
62 return st == 0;
63 }
64
65
66
67
68 [DllImport("gdiplus.dll", ExactSpelling=true)]
69 internal static extern int GdipCreateBitmapFromGdiDib( IntPtr bminfo, IntPtr pixdat, ref IntPtr image );
70
71 [DllImport("gdiplus.dll", ExactSpelling=true, CharSet=CharSet.Unicode)]
72 internal static extern int GdipSaveImageToFile( IntPtr image, string filename, [In] ref Guid clsid, IntPtr encparams );
73
74 [DllImport("gdiplus.dll", ExactSpelling=true)]
75 internal static extern int GdipDisposeImage( IntPtr image );
76
77 }
78
79 } // namespace GdiPlusLib
80

 

代码GdiPlusLib.cs
1 using System;
2 using System.Collections.Generic;
3 using System.Text;
4 using System.Drawing;
5 using System.Runtime.InteropServices;
6
7 namespace TwainGui
8 {
9 public class GetGraphics
10 {
11 private Graphics _g = null;
12 private Bitmap _bitmap = null;
13 public GetGraphics(IntPtr dibhandp)
14 {
15
16 bmprect = new Rectangle(0, 0, 0, 0);
17 dibhand = dibhandp;
18 bmpptr = GlobalLock(dibhand);
19 pixptr = GetPixelInfo(bmpptr);
20 this._bitmap = new Bitmap(bmprect.Width, bmprect.Height);
21 this._g = Graphics.FromImage(this._bitmap);
22 }
23
24 public static Bitmap KiRotate90(Bitmap img)
25 {
26 try
27 {
28 img.RotateFlip(RotateFlipType.Rotate270FlipNone);
29 //顺时针旋转90度 RotateFlipType.Rotate90FlipNone
30 //逆时针旋转90度 RotateFlipType.Rotate270FlipNone
31 //水平翻转 RotateFlipType.Rotate180FlipY
32 //垂直翻转 RotateFlipType.Rotate180FlipX
33 return img;
34 }
35 catch
36 {
37 return null;
38 }
39 }
40
41 public Bitmap GetImage()
42 {
43 IntPtr hdc = this._g.GetHdc();
44 SetDIBitsToDevice(hdc, 0, 0, bmprect.Width, bmprect.Height,
45 0, 0, 0, bmprect.Height, pixptr, bmpptr,0);
46
47 this._g.ReleaseHdc(hdc);
48
49 Pen p = new Pen(Color.Red, 10);
50 Bitmap newbitmip = new Bitmap(this._bitmap.Width, this._bitmap.Height);
51 Graphics g = Graphics.FromImage(newbitmip);
52 g.DrawImage(this._bitmap, 0, 0, this._bitmap.Width, this._bitmap.Height);
53 //g.DrawLine(p, 0, 0, 20, 20);
54
55 return KiRotate90(newbitmip);
56 }
57
58 protected IntPtr GetPixelInfo(IntPtr bmpptr)
59 {
60 bmi = new BITMAPINFOHEADER();
61 Marshal.PtrToStructure(bmpptr, bmi);
62
63 bmprect.X = bmprect.Y = 0;
64 bmprect.Width = bmi.biWidth;
65 bmprect.Height = bmi.biHeight;
66
67 if (bmi.biSizeImage == 0)
68 bmi.biSizeImage = ((((bmi.biWidth * bmi.biBitCount) + 31) & ~31) >> 3) * bmi.biHeight;
69
70 int p = bmi.biClrUsed;
71 if ((p == 0) && (bmi.biBitCount <= 8))
72 p = 1 << bmi.biBitCount;
73 p = (p * 4) + bmi.biSize + (int)bmpptr;
74 return (IntPtr)p;
75 }
76
77
78 BITMAPINFOHEADER bmi;
79 Rectangle bmprect;
80 IntPtr dibhand;
81 IntPtr bmpptr;
82 IntPtr pixptr;
83
84 [DllImport("gdi32.dll", ExactSpelling = true)]
85 internal static extern int SetDIBitsToDevice(IntPtr hdc, int xdst, int ydst,
86 int width, int height, int xsrc, int ysrc, int start, int lines,
87 IntPtr bitsptr, IntPtr bmiptr, int color);
88
89 [DllImport("kernel32.dll", ExactSpelling = true)]
90 internal static extern IntPtr GlobalLock(IntPtr handle);
91 [DllImport("kernel32.dll", ExactSpelling = true)]
92 internal static extern IntPtr GlobalFree(IntPtr handle);
93
94 [DllImport("kernel32.dll", CharSet = CharSet.Auto)]
95 public static extern void OutputDebugString(string outstr);
96
97 }
98 [StructLayout(LayoutKind.Sequential, Pack = 2)]
99 internal class BITMAPINFOHEADER
100 {
101 public int biSize;
102 public int biWidth;
103 public int biHeight;
104 public short biPlanes;
105 public short biBitCount;
106 public int biCompression;
107 public int biSizeImage;
108 public int biXPelsPerMeter;
109 public int biYPelsPerMeter;
110 public int biClrUsed;
111 public int biClrImportant;
112 }
113
114
115 }
116

 

//WINDOWS界面的代码
代码Form1.cs
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using TwainLib;
using System.Drawing.Imaging;
using System.Collections;
using TwainGui;

namespace WindowsForm
{
public partial class Form1 : System.Windows.Forms.Form, IMessageFilter
{
Hashtable images
= new Hashtable();


DataSet ds
= new DataSet();

private void EndingScan()
{
if (msgfilter)
{
Application.RemoveMessageFilter(
this);
msgfilter
= false;
this.Enabled = true;
this.Activate();
}
}

private bool msgfilter;
private Twain tw;
private int picnumber = 0;

public Form1()
{
InitializeComponent();
tw
= new Twain();
tw.Init(
this.Handle);
}

#region IMessageFilter 成员

public bool PreFilterMessage(ref Message m)
{
TwainCommand cmd
= tw.PassMessage(ref m);
if (cmd == TwainCommand.Not)
return false;

switch (cmd)
{
case TwainCommand.CloseRequest:
{
EndingScan();
tw.CloseSrc();
break;
}
case TwainCommand.CloseOk:
{
EndingScan();
tw.CloseSrc();
break;
}
case TwainCommand.DeviceEvent:
{
break;
}
case TwainCommand.TransferReady:
{
ArrayList pics
= tw.TransferPictures();
EndingScan();
tw.CloseSrc();
picnumber
++;

for (int i = 0; i < pics.Count; i++)
{
IntPtr img
= (IntPtr)pics[i];
//PicForm newpic = new PicForm( img );
//newpic.MdiParent = this;
//int picnum = i + 1;
//newpic.Text = "ScanPass" + picnumber.ToString() + "_Pic" + picnum.ToString();
//newpic.Show();
GetGraphics get = new GetGraphics(img);
Bitmap b
= get.GetImage();
images.Add((images.Count
+ 1).ToString(), b);
//b.Save("c:\\1.jpg", System.Drawing.Imaging.ImageFormat.Jpeg);
//this.components.Add(p, "picturebox");
//pictureBox1.Image = b;

}

if (images.Count < 2) button2_Click(null, null);
else
{
foreach (object o in images.Keys)
{
if (this.Controls["pictureBox" + o.ToString()] != null)
((PictureBox)
this.Controls["pictureBox" + o.ToString()]).Image = (Bitmap)images[o];
}

}
break;
}
}

return true;
}

#endregion

private static ImageCodecInfo GetEncoderInfo(String mimeType)
{
int j;
ImageCodecInfo[] encoders;
encoders
= ImageCodecInfo.GetImageEncoders();
for (j = 0; j < encoders.Length; ++j)
{
if (encoders[j].MimeType == mimeType)
return encoders[j];
}
return null;
}

public void SetImage(Bitmap b)
{
this.pictureBox1.Image = b;
}

private void DANSScanForm_FormClosing(object sender, FormClosingEventArgs e)
{
Application.ExitThread();
}

private void button2_Click(object sender, EventArgs e)
{
//images.Clear();
if (!msgfilter)
{
this.Enabled = false;
msgfilter
= true;
Application.AddMessageFilter(
this);
}
tw.Acquire();

}
}
}

 


 

visatest的主页 visatest | 初学一级 | 园豆:122
提问于:2010-04-30 09:23
< >
分享
所有回答(3)
0

想问 GdipSaveImageToFile save 时 ,可不可以改变图片的像素大小

sigmund | 园豆:202 (菜鸟二级) | 2013-01-24 14:45
0

楼主 解决 那个 问题了 吗 ?

我 现在 也在做这块 ,能把 源代码 分享一下吗?

谢啦?QQ397870376

悬崖边的贵族 | 园豆:202 (菜鸟二级) | 2013-06-21 07:38
0

请问,能调用twain 自动拍照功能吗?

十色 | 园豆:210 (菜鸟二级) | 2021-11-08 09:36
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册