Home › Forums › TWAIN Classic › Memory Transfer Mode
- This topic has 1 reply, 2 voices, and was last updated 13 years, 10 months ago by MSM.
- AuthorPosts
Hi,
I am trying to implement the memory transfer mode, and I have this issue:
Sometimes the images get scanned correctly and sometimes they get stretched
On investigation, I found that the image size obtained from calculation (lBitmapInfo.BmiHeader.biSizeImage = (UInt32)((((lImageInfo.ImageWidth * lImageInfo.BitsPerPixel + 31) / 32) * 4) * lImageInfo.ImageLength);)is different from the summation of ImageMemXfer.BytesWritten.
if the differenc is 0, then I am getting perfect images.
The x and y resolution of the images are same.
What might be the reason for this behaviour?
The code in c# is given below.Thanks in advance.
Girish
[/quote]
while (lHasNextBuffer)
{
switch (_TripletContainer.DataGroup.TWImage.TWImageMemXfer.Get(ref lImageMemXfer))
{
case ReturnCodesEnum.Success:
byte[] lByteArray = new byte[lImageMemXfer.BytesWritten];
Marshal.Copy(lBuffer, lByteArray, 0, lByteArray.Length);
totalbytes = totalbytes + lImageMemXfer.BytesWritten;
lMemoryStream.Write(lByteArray, 0, lByteArray.Length);
string lMessage = string.Format("lImageMemXfer.BytesWritten = {0}", lImageMemXfer.BytesWritten);
_LoggingService.WriteLog(lMessage, 2, lLogTitle,
lLogModuleName, lLogMethodName,
lLogCreatedBy, lLogSessionID);
// Free the current buffer
Kernel32.GlobalUnlock(lBuffer);
Kernel32.GlobalFree(lHBuffer);
lHBuffer = IntPtr.Zero;
lBuffer = IntPtr.Zero;
lHBuffer = Kernel32.GlobalAlloc(0x42, lSetupMemXfer.Preferred);
lBuffer = Kernel32.GlobalLock(lHBuffer);
lImageMemXfer = new ImageMemXfer();
lImageMemXfer.Memory.Flags = (uint)(MemoryEnum.AppOwns | MemoryEnum.Pointer);
lImageMemXfer.Memory.Length = lSetupMemXfer.Preferred;
lImageMemXfer.Memory.TheMem = lBuffer;
lImageMemXfer.Compression = (ushort)On16Enum.twDontCare16;
lImageMemXfer.BytesPerRow = (uint)On32Enum.twDontCare32;
lImageMemXfer.Columns = (uint)On32Enum.twDontCare32;
lImageMemXfer.Rows = (uint)On32Enum.twDontCare32;
lImageMemXfer.XOffset = (uint)On32Enum.twDontCare32;
lImageMemXfer.YOffset = (uint)On32Enum.twDontCare32;
lImageMemXfer.BytesWritten = (uint)On32Enum.twDontCare32;
break;
case ReturnCodesEnum.XferDone:
byte[] lByteArray1 = new byte[lImageMemXfer.BytesWritten];
lMessage = string.Format("lImageMemXfer.BytesWritten = {0}", lImageMemXfer.BytesWritten);
_LoggingService.WriteLog(lMessage, 2, lLogTitle,
lLogModuleName, lLogMethodName,
lLogCreatedBy, lLogSessionID);
Marshal.Copy(lBuffer, lByteArray1, 0, lByteArray1.Length);
totalbytes = totalbytes + lImageMemXfer.BytesWritten;
long Diffrence = lBitmapInfo.BmiHeader.biSizeImage - totalbytes;
lMemoryStream.Write(lByteArray1, 0, lByteArray1.Length);
lFileName = NextAvailableFilename(lSessionDir.FullName, _CurrentImageFileFormat.ToString().ToLower());
//DIB.BitmapFromDIB(lMemoryStream).Save(lFileName);
DIB.BitmapFromDIB(lMemoryStream).Save(lFileName);
lMessage = string.Format("Memory Transfer Done for Image Name {0}", lFileName);
_LoggingService.WriteLog(lMessage, 2, lLogTitle,
lLogModuleName, lLogMethodName,
lLogCreatedBy, lLogSessionID);
lMessage = string.Format("TotalBytes received from Scanner = {0}, Bitmap size from ImageInfo = {1}, Difference = {2} ", totalbytes, lBitmapInfo.BmiHeader.biSizeImage, Diffrence);
_LoggingService.WriteLog(lMessage, 2, lLogTitle,
lLogModuleName, lLogMethodName,
lLogCreatedBy, lLogSessionID);
lMemoryStream.Close();
Kernel32.GlobalUnlock(lBuffer);
Kernel32.GlobalFree(lHBuffer);
_Images.Add(lFileName);
lPendingXfers = DoEndXfer();
lHasNextBuffer = false;
break;
case ReturnCodesEnum.Cancel:
break;
case ReturnCodesEnum.Failure:
break;
}
}
Hi,
I would recommend you to update ImageInfo (DG_IMAGE / DAT_IMAGEINFO/MSG_GET) after you received ReturnCodesEnum.XferDone, but before you do DoEndXfer();Pay attantion the fact that some DS does not support DG_IMAGE / DAT_IMAGEINFO/MSG_GET in state 7 (after you start transfering).
So you will need one DG_IMAGE / DAT_IMAGEINFO/MSG_GET before your first “_TripletContainer.DataGroup.TWImage.TWImageMemXfer.Get” (I suppose where it is now) and one just after “case ReturnCodesEnum.XferDone:” . If second call succeeds then use its data to update bitmap header.
- AuthorPosts