I am using the example code and the tiffs sent back are corrupted. With a disk file transfer everything works, but not when I try to switch to memory transfer.
private void Twain_MemXferEvent(object sender, Twain32.MemXferEventArgs e)
{
try
{
if (TiffMemXfer.Current != null)
{
long _bitsPerRow = e.ImageInfo.BitsPerPixel * e.ImageMemXfer.Columns;
long _bytesPerRow = Math.Min(e.ImageMemXfer.BytesPerRow, (_bitsPerRow >> 3) + ((_bitsPerRow & 0x07) != 0 ? 1 : 0));
using (MemoryStream _stream = new MemoryStream())
{
for (int i = 0; i < e.ImageMemXfer.Rows; i++)
{
_stream.Position = 0;
_stream.Write(e.ImageMemXfer.ImageData, (int)(e.ImageMemXfer.BytesPerRow * i), (int)_bytesPerRow);
TiffMemXfer.Current.Strips.Add(TiffMemXfer.Current.Writer.WriteData(_stream.ToArray()));
TiffMemXfer.Current.StripByteCounts.Add((uint)_stream.Length);
}
}
}
else
{
MemFileXfer.Current.Writer.Write(e.ImageMemXfer.ImageData);
}
}
catch (Exception ex)
{
Debug.WriteLine(string.Format("{0}: {1}\n{2}", ex.GetType().Name, ex.Message, ex.StackTrace));
}
}
private void Twain_SetupMemXferEvent(object sender, Twain32.SetupMemXferEventArgs e)
{
try
{
if (this._twain.Capabilities.XferMech.GetCurrent() == TwSetupTransfer.Memory)
{
if (TiffMemXfer.Current == null)
{
TiffMemXfer.Create((int)e.BufferSize);
}
#region Color Map
if (e.ImageInfo.PixelType == TwPixelType.Palette)
{
Twain32.ColorPalette _palette = this._twain.Palette.Get();
TiffMemXfer.Current.ColorMap = new ushort[_palette.Colors.Length * 3];
for (int i = 0; i < _palette.Colors.Length; i++)
{
TiffMemXfer.Current.ColorMap[i] = (ushort)(_palette.Colors[i].R);
TiffMemXfer.Current.ColorMap[i + _palette.Colors.Length] = (ushort)(_palette.Colors[i].G);
TiffMemXfer.Current.ColorMap[i + (_palette.Colors.Length << 1)] = (ushort)(_palette.Colors[i].B);
}
}
#endregion
}
else
{ // MemFile
MemFileXfer.Create((int)e.BufferSize, this._twain.Capabilities.ImageFileFormat.GetCurrent().ToString().ToLower());
}
}
catch (Exception ex)
{
Debug.WriteLine(string.Format("{0}: {1}\n{2}", ex.GetType().Name, ex.Message, ex.StackTrace));
}
}
private void Twain_XferDone(object sender, Twain32.XferDoneEventArgs e)
{
if (TiffMemXfer.Current != null && TiffMemXfer.Current.Writer != null)
{
Twain32.ImageInfo _info = e.GetImageInfo();
Collection<ITag> _tags = new Collection<ITag> {
Tag<uint>.Create(TiffTags.ImageWidth,(uint)_info.ImageWidth),
Tag<uint>.Create(TiffTags.ImageLength,(uint)_info.ImageLength),
Tag<ushort>.Create(TiffTags.SamplesPerPixel,(ushort)_info.BitsPerSample.Length),
Tag<ushort>.Create(TiffTags.BitsPerSample,new Func<short[],ushort[]>(val=>{
ushort[] _result=new ushort[_info.BitsPerSample.Length];
for(int i=0; i<_result.Length; i++) {
_result[i]=(ushort)_info.BitsPerSample[i];
}
return _result;
})(_info.BitsPerSample)),
Tag<ushort>.Create(TiffTags.Orientation,(ushort)TiffOrientation.TOPLEFT),
Tag<TiffCompression>.Create(TiffTags.Compression,TiffCompression.NONE),
Tag<TiffResolutionUnit>.Create(TiffTags.ResolutionUnit,new Func<TwUnits,TiffResolutionUnit>(val=>{
switch(val){
case TwUnits.Centimeters:
return TiffResolutionUnit.CENTIMETER;
case TwUnits.Inches:
return TiffResolutionUnit.INCH;
default:
return TiffResolutionUnit.NONE;
}
})(this._twain.Capabilities.Units.GetCurrent())),
Tag<ulong>.Create(TiffTags.XResolution,(1UL<<32)|(ulong)_info.XResolution),
Tag<ulong>.Create(TiffTags.YResolution,(1UL<<32)|(ulong)_info.YResolution),
Tag<TiffHandle>.Create(TiffTags.StripOffsets,TiffMemXfer.Current.Strips.ToArray()),
Tag<uint>.Create(TiffTags.StripByteCounts,TiffMemXfer.Current.StripByteCounts.ToArray()),
Tag<uint>.Create(TiffTags.RowsPerStrip,1u),
//Tag<char>.Create(TiffTags.Software, Application.ProductName.ToCharArray()),
Tag<char>.Create(TiffTags.Model,this._twain.GetSourceProductName(this._twain.SourceIndex).ToCharArray()),
Tag<char>.Create(TiffTags.DateTime,DateTime.Now.ToString("yyyy:MM:dd HH:mm:ss").PadRight(20,'\0').ToCharArray()),
Tag<char>.Create(TiffTags.HostComputer,Environment.MachineName.ToCharArray()),
Tag<ushort>.Create(TiffTags.PlanarConfiguration,(ushort)TiffPlanarConfig.CONTIG),
Tag<char>.Create(TiffTags.Copyright,((AssemblyCopyrightAttribute)this.GetType().Assembly.GetCustomAttributes(typeof(AssemblyCopyrightAttribute),false)[0]).Copyright.ToCharArray())
};
switch (_info.PixelType)
{
case TwPixelType.BW:
_tags.Add(Tag<TiffPhotoMetric>.Create(TiffTags.PhotometricInterpretation, TiffPhotoMetric.BlackIsZero));
break;
case TwPixelType.Gray:
_tags.Add(Tag<TiffPhotoMetric>.Create(TiffTags.PhotometricInterpretation, TiffPhotoMetric.BlackIsZero));
break;
case TwPixelType.Palette:
_tags.Add(Tag<TiffPhotoMetric>.Create(TiffTags.PhotometricInterpretation, TiffPhotoMetric.Palette));
_tags.Add(Tag<ushort>.Create(TiffTags.ColorMap, TiffMemXfer.Current.ColorMap));
break;
case TwPixelType.RGB:
_tags.Add(Tag<TiffPhotoMetric>.Create(TiffTags.PhotometricInterpretation, TiffPhotoMetric.RGB));
break;
default:
break;
}
TiffMemXfer.Current.Handle = TiffMemXfer.Current.Writer.WriteImageFileDirectory(TiffMemXfer.Current.Handle, _tags);
TiffMemXfer.Current.Strips.Clear();
TiffMemXfer.Current.StripByteCounts.Clear();
}
}
private void Twain_AcquireCompleted(object sender, EventArgs e)
{
if (this._twain.ImageCount > 0)
{
this.CurrentBitmap = this._twain.GetImage(0) as Bitmap;
}
if (TiffMemXfer.Current != null)
{
try
{
TiffMemXfer.Current.Writer.BaseStream.Seek(0, SeekOrigin.Begin);
this.CurrentBitmap = Image.FromStream(TiffMemXfer.Current.Writer.BaseStream) as Bitmap;
}
finally
{
TiffMemXfer.Dispose();
}
}
FinalizeScan();
}
private void Twain_AcquireError(object sender, Twain32.AcquireErrorEventArgs e)
{
FinalizeScan();
if (e.Exception.ConditionCode != TwCC.Success)
{
_onError?.Invoke("Twain encountered an acquire error: " + e.Exception.ToString());
}
}