mirror of
https://github.com/soukoku/ntwain.git
synced 2025-10-25 10:59:03 +08:00
Added image conversion parts from commonwin32.
This commit is contained in:
@@ -41,6 +41,7 @@
|
|||||||
<Reference Include="PresentationCore" />
|
<Reference Include="PresentationCore" />
|
||||||
<Reference Include="PresentationFramework" />
|
<Reference Include="PresentationFramework" />
|
||||||
<Reference Include="System" />
|
<Reference Include="System" />
|
||||||
|
<Reference Include="System.Drawing" />
|
||||||
<Reference Include="System.Windows.Forms" />
|
<Reference Include="System.Windows.Forms" />
|
||||||
<Reference Include="WindowsBase" />
|
<Reference Include="WindowsBase" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
@@ -87,6 +88,9 @@
|
|||||||
<Compile Include="..\NTwain\IDataSource.cs">
|
<Compile Include="..\NTwain\IDataSource.cs">
|
||||||
<Link>IDataSource.cs</Link>
|
<Link>IDataSource.cs</Link>
|
||||||
</Compile>
|
</Compile>
|
||||||
|
<Compile Include="..\NTwain\ImageTools.cs">
|
||||||
|
<Link>ImageTools.cs</Link>
|
||||||
|
</Compile>
|
||||||
<Compile Include="..\NTwain\IMemoryManager.cs">
|
<Compile Include="..\NTwain\IMemoryManager.cs">
|
||||||
<Link>IMemoryManager.cs</Link>
|
<Link>IMemoryManager.cs</Link>
|
||||||
</Compile>
|
</Compile>
|
||||||
@@ -105,18 +109,12 @@
|
|||||||
<Compile Include="..\NTwain\Internals\IWinMessageFilter.cs">
|
<Compile Include="..\NTwain\Internals\IWinMessageFilter.cs">
|
||||||
<Link>Internals\IWinMessageFilter.cs</Link>
|
<Link>Internals\IWinMessageFilter.cs</Link>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="..\NTwain\Internals\MESSAGE.cs">
|
|
||||||
<Link>Internals\MESSAGE.cs</Link>
|
|
||||||
</Compile>
|
|
||||||
<Compile Include="..\NTwain\Internals\TentativeStateCommitable.cs">
|
<Compile Include="..\NTwain\Internals\TentativeStateCommitable.cs">
|
||||||
<Link>Internals\TentativeStateCommitable.cs</Link>
|
<Link>Internals\TentativeStateCommitable.cs</Link>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="..\NTwain\Internals\TransferLogic.cs">
|
<Compile Include="..\NTwain\Internals\TransferLogic.cs">
|
||||||
<Link>Internals\TransferLogic.cs</Link>
|
<Link>Internals\TransferLogic.cs</Link>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="..\NTwain\Internals\UnsafeNativeMethods.cs">
|
|
||||||
<Link>Internals\UnsafeNativeMethods.cs</Link>
|
|
||||||
</Compile>
|
|
||||||
<Compile Include="..\NTwain\Internals\WindowsHook.cs">
|
<Compile Include="..\NTwain\Internals\WindowsHook.cs">
|
||||||
<Link>Internals\WindowsHook.cs</Link>
|
<Link>Internals\WindowsHook.cs</Link>
|
||||||
</Compile>
|
</Compile>
|
||||||
@@ -126,6 +124,21 @@
|
|||||||
<Compile Include="..\NTwain\Internals\WrappedManualResetEvent.cs">
|
<Compile Include="..\NTwain\Internals\WrappedManualResetEvent.cs">
|
||||||
<Link>Internals\WrappedManualResetEvent.cs</Link>
|
<Link>Internals\WrappedManualResetEvent.cs</Link>
|
||||||
</Compile>
|
</Compile>
|
||||||
|
<Compile Include="..\NTwain\Interop\BITMAPINFO.cs">
|
||||||
|
<Link>Interop\BITMAPINFO.cs</Link>
|
||||||
|
</Compile>
|
||||||
|
<Compile Include="..\NTwain\Interop\BITMAPINFOHEADER.cs">
|
||||||
|
<Link>Interop\BITMAPINFOHEADER.cs</Link>
|
||||||
|
</Compile>
|
||||||
|
<Compile Include="..\NTwain\Interop\MESSAGE.cs">
|
||||||
|
<Link>Interop\MESSAGE.cs</Link>
|
||||||
|
</Compile>
|
||||||
|
<Compile Include="..\NTwain\Interop\NativeMethods.cs">
|
||||||
|
<Link>Interop\NativeMethods.cs</Link>
|
||||||
|
</Compile>
|
||||||
|
<Compile Include="..\NTwain\Interop\UnsafeNativeMethods.cs">
|
||||||
|
<Link>Interop\UnsafeNativeMethods.cs</Link>
|
||||||
|
</Compile>
|
||||||
<Compile Include="..\NTwain\IPlatformInfo.cs">
|
<Compile Include="..\NTwain\IPlatformInfo.cs">
|
||||||
<Link>IPlatformInfo.cs</Link>
|
<Link>IPlatformInfo.cs</Link>
|
||||||
</Compile>
|
</Compile>
|
||||||
|
|||||||
@@ -1,8 +1,14 @@
|
|||||||
using NTwain.Data;
|
using NTwain.Data;
|
||||||
|
using NTwain.Internals;
|
||||||
|
using NTwain.Interop;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Drawing;
|
||||||
|
using System.Drawing.Imaging;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
using System.Security.Permissions;
|
||||||
|
|
||||||
namespace NTwain
|
namespace NTwain
|
||||||
{
|
{
|
||||||
@@ -131,5 +137,29 @@ namespace NTwain
|
|||||||
}
|
}
|
||||||
return Enumerable.Empty<TWInfo>();
|
return Enumerable.Empty<TWInfo>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the bitmap from the <see cref="NativeData"/> if it's an image.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
public Bitmap GetNativeBitmap()
|
||||||
|
{
|
||||||
|
Bitmap image = null;
|
||||||
|
if (NativeData != IntPtr.Zero)
|
||||||
|
{
|
||||||
|
if (PlatformInfo.Current.IsWindows)
|
||||||
|
{
|
||||||
|
image = ImageTools.ReadBitmapImage(NativeData);
|
||||||
|
}
|
||||||
|
else if (PlatformInfo.Current.IsLinux)
|
||||||
|
{
|
||||||
|
image = ImageTools.ReadTiffImage(NativeData);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return image;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
119
NTwain/ImageTools.cs
Normal file
119
NTwain/ImageTools.cs
Normal file
@@ -0,0 +1,119 @@
|
|||||||
|
using Microsoft.Win32.SafeHandles;
|
||||||
|
using NTwain.Interop;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Drawing;
|
||||||
|
using System.Drawing.Imaging;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
using System.Security;
|
||||||
|
using System.Text;
|
||||||
|
using System.Windows.Media.Imaging;
|
||||||
|
|
||||||
|
namespace NTwain
|
||||||
|
{
|
||||||
|
public static class ImageTools
|
||||||
|
{
|
||||||
|
internal static Bitmap ReadBitmapImage(IntPtr dibBitmap)
|
||||||
|
{
|
||||||
|
Bitmap finalImg = null;
|
||||||
|
Bitmap tempImg = null;
|
||||||
|
if (IsDib(dibBitmap))
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var header = (BITMAPINFOHEADER)Marshal.PtrToStructure(dibBitmap, typeof(BITMAPINFOHEADER));
|
||||||
|
|
||||||
|
if (header.Validate())
|
||||||
|
{
|
||||||
|
PixelFormat format = header.GetDrawingPixelFormat();
|
||||||
|
tempImg = new Bitmap(header.biWidth, Math.Abs(header.biHeight), header.GetStride(), format, header.GetScan0(dibBitmap));
|
||||||
|
ColorPalette pal = header.GetDrawingPalette(dibBitmap);
|
||||||
|
if (pal != null)
|
||||||
|
{
|
||||||
|
tempImg.Palette = pal;
|
||||||
|
}
|
||||||
|
float xdpi = header.GetXDpi();
|
||||||
|
float ydpi = header.GetYDpi();
|
||||||
|
if (xdpi != 0 && ydpi == 0)
|
||||||
|
{
|
||||||
|
ydpi = xdpi;
|
||||||
|
}
|
||||||
|
else if (ydpi != 0 && xdpi == 0)
|
||||||
|
{
|
||||||
|
xdpi = ydpi;
|
||||||
|
}
|
||||||
|
if (xdpi != 0)
|
||||||
|
{
|
||||||
|
tempImg.SetResolution(xdpi, ydpi);
|
||||||
|
}
|
||||||
|
if (header.IsBottomUpImage)
|
||||||
|
{
|
||||||
|
tempImg.RotateFlip(RotateFlipType.RotateNoneFlipY);
|
||||||
|
}
|
||||||
|
finalImg = tempImg;
|
||||||
|
tempImg = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
if (tempImg != null)
|
||||||
|
{
|
||||||
|
tempImg.Dispose();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return finalImg;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool IsDib(IntPtr dibBitmap)
|
||||||
|
{
|
||||||
|
// a quick check not guaranteed correct,
|
||||||
|
// compare first byte to size of struct (which is also the first field)
|
||||||
|
var test = Marshal.ReadInt32(dibBitmap);
|
||||||
|
// should be 40
|
||||||
|
return test == BITMAPINFOHEADER.GetByteSize();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Converts a <see cref="Bitmap"/> to WPF <see cref="BitmapSource"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="image">The image to convert.</param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static BitmapSource ConvertToWpfBitmap(this Bitmap image)
|
||||||
|
{
|
||||||
|
if (image != null)
|
||||||
|
{
|
||||||
|
using (var hbm = new SafeHBitmapHandle(image.GetHbitmap(), true))
|
||||||
|
{
|
||||||
|
return System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(
|
||||||
|
hbm.DangerousGetHandle(),
|
||||||
|
IntPtr.Zero,
|
||||||
|
System.Windows.Int32Rect.Empty,
|
||||||
|
BitmapSizeOptions.FromEmptyOptions());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
class SafeHBitmapHandle : SafeHandleZeroOrMinusOneIsInvalid
|
||||||
|
{
|
||||||
|
[SecurityCritical]
|
||||||
|
public SafeHBitmapHandle(IntPtr preexistingHandle, bool ownsHandle)
|
||||||
|
: base(ownsHandle)
|
||||||
|
{
|
||||||
|
SetHandle(preexistingHandle);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override bool ReleaseHandle()
|
||||||
|
{
|
||||||
|
return NativeMethods.DeleteObject(handle);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static Bitmap ReadTiffImage(IntPtr data)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
using NTwain.Data;
|
using NTwain.Data;
|
||||||
|
using NTwain.Interop;
|
||||||
using System;
|
using System;
|
||||||
using System.ComponentModel;
|
using System.ComponentModel;
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using System;
|
using NTwain.Interop;
|
||||||
|
using System;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using System.Windows.Interop;
|
using System.Windows.Interop;
|
||||||
|
|||||||
32
NTwain/Interop/BITMAPINFO.cs
Normal file
32
NTwain/Interop/BITMAPINFO.cs
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Text;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
using System.Drawing.Imaging;
|
||||||
|
using System.Drawing;
|
||||||
|
|
||||||
|
namespace NTwain.Interop
|
||||||
|
{
|
||||||
|
// this is a good read
|
||||||
|
// http://atlc.sourceforge.net/bmp.html
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Defines the dimensions and color information for a DIB.
|
||||||
|
/// </summary>
|
||||||
|
[StructLayout(LayoutKind.Sequential)]
|
||||||
|
public struct BITMAPINFO
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Structure that contains information about the dimensions of color format.
|
||||||
|
/// </summary>
|
||||||
|
public BITMAPINFOHEADER bmiHeader;
|
||||||
|
/// <summary>
|
||||||
|
/// This contains one of the following:
|
||||||
|
/// 1. An array of RGBQUAD. The elements of the array that make up the color table.
|
||||||
|
/// 2. An array of 16-bit unsigned integers that specifies indexes into the currently realized logical palette. This use of bmiColors is allowed for functions that use DIBs.
|
||||||
|
/// The number of entries in the array depends on the values of the biBitCount and biClrUsed members of the BITMAPINFOHEADER structure.
|
||||||
|
/// </summary>
|
||||||
|
public IntPtr bmiColors;
|
||||||
|
|
||||||
|
};
|
||||||
|
}
|
||||||
310
NTwain/Interop/BITMAPINFOHEADER.cs
Normal file
310
NTwain/Interop/BITMAPINFOHEADER.cs
Normal file
@@ -0,0 +1,310 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Drawing;
|
||||||
|
using System.Drawing.Imaging;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace NTwain.Interop
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Structure that contains information about the dimensions and color format of a DIB.
|
||||||
|
/// </summary>
|
||||||
|
[StructLayout(LayoutKind.Sequential)]
|
||||||
|
public struct BITMAPINFOHEADER
|
||||||
|
{
|
||||||
|
#region fields
|
||||||
|
/// <summary>
|
||||||
|
/// The number of bytes required by the structure.
|
||||||
|
/// </summary>
|
||||||
|
public uint biSize;
|
||||||
|
/// <summary>
|
||||||
|
/// The width of the bitmap, in pixels.
|
||||||
|
/// If Compression is JPEG or PNG, the Width member specifies the width of the decompressed
|
||||||
|
/// JPEG or PNG image file, respectively.
|
||||||
|
/// </summary>
|
||||||
|
public int biWidth;
|
||||||
|
/// <summary>
|
||||||
|
/// The height of the bitmap, in pixels. If Height is positive,
|
||||||
|
/// the bitmap is a bottom-up DIB and its origin is the lower-left corner.
|
||||||
|
/// If Height is negative, the bitmap is a top-down DIB and its origin is the upper-left corner.
|
||||||
|
/// If Height is negative, indicating a top-down DIB, Compression must be either RGB or BITFIELDS. Top-down DIBs cannot be compressed.
|
||||||
|
/// If Compression is JPEG or PNG, the Height member specifies the height of the decompressed JPEG or PNG image file, respectively.
|
||||||
|
/// </summary>
|
||||||
|
public int biHeight;
|
||||||
|
/// <summary>
|
||||||
|
/// The number of planes for the target device. This value must be set to 1.
|
||||||
|
/// </summary>
|
||||||
|
public ushort biPlanes;
|
||||||
|
/// <summary>
|
||||||
|
/// The number of bits-per-pixel. The BitCount member
|
||||||
|
/// determines the number of bits that define each pixel and the maximum number of colors in the bitmap.
|
||||||
|
/// </summary>
|
||||||
|
public ushort biBitCount;
|
||||||
|
/// <summary>
|
||||||
|
/// The type of compression for a compressed bottom-up bitmap (top-down DIBs cannot be compressed).
|
||||||
|
/// </summary>
|
||||||
|
public CompressionType biCompression;
|
||||||
|
/// <summary>
|
||||||
|
/// The size, in bytes, of the image. This may be set to zero for RGB bitmaps.
|
||||||
|
/// If Compression is JPEG or PNG, SizeImage indicates the size of the JPEG or PNG image buffer, respectively.
|
||||||
|
/// </summary>
|
||||||
|
public uint biSizeImage;
|
||||||
|
/// <summary>
|
||||||
|
/// The horizontal resolution, in pixels-per-meter, of the target device for the bitmap.
|
||||||
|
/// An application can use this value to select a bitmap from a resource group that
|
||||||
|
/// best matches the characteristics of the current device.
|
||||||
|
/// </summary>
|
||||||
|
public int biXPelsPerMeter;
|
||||||
|
/// <summary>
|
||||||
|
/// The vertical resolution, in pixels-per-meter, of the target device for the bitmap.
|
||||||
|
/// </summary>
|
||||||
|
public int biYPelsPerMeter;
|
||||||
|
/// <summary>
|
||||||
|
/// The number of color indexes in the color table that are actually used by the bitmap.
|
||||||
|
/// If this value is zero, the bitmap uses the maximum number of colors corresponding to
|
||||||
|
/// the value of the BitCount member for the compression mode specified by Compression.
|
||||||
|
/// </summary>
|
||||||
|
public uint biClrUsed;
|
||||||
|
/// <summary>
|
||||||
|
/// The number of color indexes that are required for displaying the bitmap.
|
||||||
|
/// If this value is zero, all colors are required.
|
||||||
|
/// </summary>
|
||||||
|
public uint biClrImportant;
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region utilities
|
||||||
|
|
||||||
|
const double METER_INCH_RATIO = 39.3700787;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the horizontal dpi of the bitmap.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
public float GetXDpi()
|
||||||
|
{
|
||||||
|
return (float)Math.Round(biXPelsPerMeter / METER_INCH_RATIO, 0);
|
||||||
|
}
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the vertical dpi of the bitmap.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
public float GetYDpi()
|
||||||
|
{
|
||||||
|
return (float)Math.Round(biYPelsPerMeter / METER_INCH_RATIO, 0);
|
||||||
|
}
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the size of the structure.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static uint GetByteSize()
|
||||||
|
{
|
||||||
|
return (uint)Marshal.SizeOf(typeof(BITMAPINFOHEADER));
|
||||||
|
}
|
||||||
|
/// <summary>
|
||||||
|
/// Checks to see if this structure contain valid data.
|
||||||
|
/// It also fills in any missing pieces if possible.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
public bool Validate()
|
||||||
|
{
|
||||||
|
if (biHeight != 0 && biWidth != 0 && biBitCount != 0)
|
||||||
|
{
|
||||||
|
if (biSize == 0)
|
||||||
|
{
|
||||||
|
biSize = GetByteSize();
|
||||||
|
}
|
||||||
|
if (biClrUsed == 0)
|
||||||
|
{
|
||||||
|
switch (biBitCount)
|
||||||
|
{
|
||||||
|
case 1:
|
||||||
|
biClrUsed = 2;
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
biClrUsed = 16;
|
||||||
|
break;
|
||||||
|
case 8:
|
||||||
|
biClrUsed = 256;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (biSizeImage == 0)
|
||||||
|
{
|
||||||
|
biSizeImage = (uint)((((
|
||||||
|
biWidth * biBitCount) + 31) & ~31) >> 3) * (uint)Math.Abs(biHeight);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the pointer to scan0 given the header pointer.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="headerPtr">The header PTR.</param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public IntPtr GetScan0(IntPtr headerPtr)
|
||||||
|
{
|
||||||
|
int p = (int)biClrUsed;
|
||||||
|
if ((p == 0) && (biBitCount <= 8))
|
||||||
|
{
|
||||||
|
p = 1 << biBitCount;
|
||||||
|
}
|
||||||
|
p = (p * 4) + (int)biSize + headerPtr.ToInt32();
|
||||||
|
return new IntPtr(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets whether the bitmap is bottom-up or top-down format.
|
||||||
|
/// </summary>
|
||||||
|
/// <value>
|
||||||
|
/// <c>true</c> if this instance is bottom up image; otherwise, <c>false</c>.
|
||||||
|
/// </value>
|
||||||
|
/// <returns></returns>
|
||||||
|
public bool IsBottomUpImage
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return biHeight > 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the System.Drawing pixel format of current structure.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
public PixelFormat GetDrawingPixelFormat()
|
||||||
|
{
|
||||||
|
switch (biBitCount)
|
||||||
|
{
|
||||||
|
case 1:
|
||||||
|
return PixelFormat.Format1bppIndexed;
|
||||||
|
case 4:
|
||||||
|
return PixelFormat.Format4bppIndexed;
|
||||||
|
case 8:
|
||||||
|
return PixelFormat.Format8bppIndexed;
|
||||||
|
case 16:
|
||||||
|
return PixelFormat.Format16bppRgb565;
|
||||||
|
case 24:
|
||||||
|
return PixelFormat.Format24bppRgb;
|
||||||
|
case 32:
|
||||||
|
return PixelFormat.Format32bppRgb;
|
||||||
|
case 48:
|
||||||
|
return PixelFormat.Format48bppRgb;
|
||||||
|
}
|
||||||
|
return PixelFormat.DontCare;
|
||||||
|
}
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the color palette that's contained in the header.
|
||||||
|
/// Note not all images will have palette, so check if the return value
|
||||||
|
/// is null before using it.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
public ColorPalette GetDrawingPalette(IntPtr headerPtr)
|
||||||
|
{
|
||||||
|
//if (format == PixelFormat.Format8bppIndexed)
|
||||||
|
//{
|
||||||
|
// // update color palette to grayscale version
|
||||||
|
// ColorPalette grayPallet = bitmap.Palette;
|
||||||
|
// for (int i = 0; i < grayPallet.Entries.Length; i++)
|
||||||
|
// {
|
||||||
|
// grayPallet.Entries[i] = Color.FromArgb(i, i, i);
|
||||||
|
// }
|
||||||
|
// bitmap.Palette = grayPallet; // this is what makes the gray pallet take effect
|
||||||
|
//}
|
||||||
|
|
||||||
|
if (biClrUsed > 0)
|
||||||
|
{
|
||||||
|
byte[] data = new byte[biClrUsed * 4];
|
||||||
|
Marshal.Copy(new IntPtr(headerPtr.ToInt32() + biSize), data, 0, data.Length);
|
||||||
|
var dummy = new System.Drawing.Bitmap(1, 1, GetDrawingPixelFormat());
|
||||||
|
ColorPalette pal = dummy.Palette;
|
||||||
|
dummy.Dispose();
|
||||||
|
int index = 0;
|
||||||
|
int setCount = data.Length / 4;
|
||||||
|
for (int i = 0; i < setCount; i++)
|
||||||
|
{
|
||||||
|
index = i * 4;
|
||||||
|
pal.Entries[i] = Color.FromArgb(data[index + 2], data[index + 1], data[index]);
|
||||||
|
}
|
||||||
|
return pal;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the stride size of this bitmap.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
public int GetStride()
|
||||||
|
{
|
||||||
|
int bitsPerRow = (biBitCount * biWidth);
|
||||||
|
int strideTest = bitsPerRow / 8 + (bitsPerRow % 8 != 0 ? 1 : 0);
|
||||||
|
int overage = strideTest % 4;
|
||||||
|
if (overage > 0)
|
||||||
|
{
|
||||||
|
strideTest += (4 - overage);
|
||||||
|
}
|
||||||
|
return strideTest;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returns a <see cref="System.String" /> that represents this instance.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>
|
||||||
|
/// A <see cref="System.String" /> that represents this instance.
|
||||||
|
/// </returns>
|
||||||
|
public override string ToString()
|
||||||
|
{
|
||||||
|
return new StringBuilder().Append("BitmapInfoHeader:")
|
||||||
|
.Append("\r\n\tSize = " + biSize)
|
||||||
|
.Append("\r\n\tWidth = " + biWidth)
|
||||||
|
.Append("\r\n\tHeight = " + biHeight)
|
||||||
|
.Append("\r\n\tPlanes = " + biPlanes)
|
||||||
|
.Append("\r\n\tBitCount = " + biBitCount)
|
||||||
|
.Append("\r\n\tCompression = " + biCompression)
|
||||||
|
.Append("\r\n\tSizeImage = " + biSizeImage)
|
||||||
|
.Append("\r\n\tXPixelsPerMeter = " + biXPelsPerMeter)
|
||||||
|
.Append("\r\n\tYPixelsPerMeter = " + biYPelsPerMeter)
|
||||||
|
.Append("\r\n\tColorUsed = " + biClrUsed)
|
||||||
|
.Append("\r\n\tColorImportant = " + biClrImportant).ToString();
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Indicates the bitmap compression of <seealso cref="BITMAPINFOHEADER"/>.
|
||||||
|
/// </summary>
|
||||||
|
public enum CompressionType : uint
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// An uncompressed format.
|
||||||
|
/// </summary>
|
||||||
|
BI_RGB = 0,
|
||||||
|
/// <summary>
|
||||||
|
/// A run-length encoded (RLE) format for bitmaps with 8 bpp. The compression format is a 2-byte format consisting of a count byte followed by a byte containing a color index. For more information, see Bitmap Compression.
|
||||||
|
/// </summary>
|
||||||
|
BI_RLE8 = 1,
|
||||||
|
/// <summary>
|
||||||
|
/// An RLE, format for bitmaps with 4 bpp. The compression format is a 2-byte format consisting of a count byte followed by two word-length color indexes. For more information, see Bitmap Compression.
|
||||||
|
/// </summary>
|
||||||
|
BI_RLE4 = 2,
|
||||||
|
/// <summary>
|
||||||
|
/// Specifies that the bitmap is not compressed and that the color table consists of three DWORD color masks that specify the red, green, and blue components of each pixel.
|
||||||
|
/// This is valid when used with 16- and 32-bpp bitmaps.
|
||||||
|
/// </summary>
|
||||||
|
BI_BITFIELDS = 3,
|
||||||
|
/// <summary>
|
||||||
|
/// Indicates that the image is a JPEG image.
|
||||||
|
/// </summary>
|
||||||
|
BI_JPEG = 4,
|
||||||
|
/// <summary>
|
||||||
|
/// Indicates that the image is a PNG image.
|
||||||
|
/// </summary>
|
||||||
|
BI_PNG = 5
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
@@ -4,10 +4,8 @@ using System.Linq;
|
|||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
|
||||||
namespace NTwain.Internals
|
namespace NTwain.Interop
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The MSG structure in Windows for TWAIN use.
|
/// The MSG structure in Windows for TWAIN use.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
18
NTwain/Interop/NativeMethods.cs
Normal file
18
NTwain/Interop/NativeMethods.cs
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace NTwain.Interop
|
||||||
|
{
|
||||||
|
static class NativeMethods
|
||||||
|
{
|
||||||
|
[DllImport("gdi32.dll", SetLastError = true)]
|
||||||
|
[return: MarshalAs(UnmanagedType.Bool)]
|
||||||
|
public static extern bool DeleteObject(IntPtr hObject);
|
||||||
|
|
||||||
|
[DllImport("user32.dll")]
|
||||||
|
public static extern IntPtr DefWindowProc(IntPtr hWnd, uint msg, IntPtr wParam, IntPtr lParam);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -2,7 +2,7 @@
|
|||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using System.Security;
|
using System.Security;
|
||||||
|
|
||||||
namespace NTwain.Internals
|
namespace NTwain.Interop
|
||||||
{
|
{
|
||||||
[SuppressUnmanagedCodeSecurity]
|
[SuppressUnmanagedCodeSecurity]
|
||||||
static class UnsafeNativeMethods
|
static class UnsafeNativeMethods
|
||||||
@@ -24,11 +24,4 @@ namespace NTwain.Internals
|
|||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
|
|
||||||
static class NativeMethods
|
|
||||||
{
|
|
||||||
|
|
||||||
[DllImport("user32.dll")]
|
|
||||||
public static extern IntPtr DefWindowProc(IntPtr hWnd, uint msg, IntPtr wParam, IntPtr lParam);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -50,6 +50,7 @@
|
|||||||
<Reference Include="PresentationCore" />
|
<Reference Include="PresentationCore" />
|
||||||
<Reference Include="PresentationFramework" />
|
<Reference Include="PresentationFramework" />
|
||||||
<Reference Include="System" />
|
<Reference Include="System" />
|
||||||
|
<Reference Include="System.Drawing" />
|
||||||
<Reference Include="System.Windows.Forms" />
|
<Reference Include="System.Windows.Forms" />
|
||||||
<Reference Include="System.Xaml" />
|
<Reference Include="System.Xaml" />
|
||||||
<Reference Include="WindowsBase" />
|
<Reference Include="WindowsBase" />
|
||||||
@@ -66,17 +67,21 @@
|
|||||||
<Compile Include="DataTransferredEventArgs.cs" />
|
<Compile Include="DataTransferredEventArgs.cs" />
|
||||||
<Compile Include="IMemoryManager.cs" />
|
<Compile Include="IMemoryManager.cs" />
|
||||||
<Compile Include="Internals\ICommittable.cs" />
|
<Compile Include="Internals\ICommittable.cs" />
|
||||||
|
<Compile Include="ImageTools.cs" />
|
||||||
<Compile Include="Internals\InternalMessageLoopHook.cs" />
|
<Compile Include="Internals\InternalMessageLoopHook.cs" />
|
||||||
<Compile Include="Internals\ITwainSessionInternal.cs" />
|
<Compile Include="Internals\ITwainSessionInternal.cs" />
|
||||||
<Compile Include="Internals\MESSAGE.cs" />
|
<Compile Include="Interop\BITMAPINFO.cs" />
|
||||||
|
<Compile Include="Interop\BITMAPINFOHEADER.cs" />
|
||||||
|
<Compile Include="Interop\MESSAGE.cs" />
|
||||||
<Compile Include="Internals\TransferLogic.cs" />
|
<Compile Include="Internals\TransferLogic.cs" />
|
||||||
<Compile Include="Internals\WindowsHook.cs" />
|
<Compile Include="Internals\WindowsHook.cs" />
|
||||||
<Compile Include="Internals\WrappedManualResetEvent.cs" />
|
<Compile Include="Internals\WrappedManualResetEvent.cs" />
|
||||||
|
<Compile Include="Interop\NativeMethods.cs" />
|
||||||
<Compile Include="IPlatformInfo.cs" />
|
<Compile Include="IPlatformInfo.cs" />
|
||||||
<Compile Include="ITripletControl.cs" />
|
<Compile Include="ITripletControl.cs" />
|
||||||
<Compile Include="ITwainSession.cs" />
|
<Compile Include="ITwainSession.cs" />
|
||||||
<Compile Include="Internals\WinMemoryManager.cs" />
|
<Compile Include="Internals\WinMemoryManager.cs" />
|
||||||
<Compile Include="Internals\UnsafeNativeMethods.cs" />
|
<Compile Include="Interop\UnsafeNativeMethods.cs" />
|
||||||
<Compile Include="Internals\IWinMessageFilter.cs" />
|
<Compile Include="Internals\IWinMessageFilter.cs" />
|
||||||
<Compile Include="ICapWrapper.cs" />
|
<Compile Include="ICapWrapper.cs" />
|
||||||
<Compile Include="MessageLoopHooks.cs" />
|
<Compile Include="MessageLoopHooks.cs" />
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
using NTwain.Data;
|
using NTwain.Data;
|
||||||
using NTwain.Internals;
|
using NTwain.Internals;
|
||||||
|
using NTwain.Interop;
|
||||||
using NTwain.Triplets;
|
using NTwain.Triplets;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
@@ -231,7 +232,7 @@ namespace NTwain
|
|||||||
IntPtr msgPtr = IntPtr.Zero;
|
IntPtr msgPtr = IntPtr.Zero;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var winMsg = new NTwain.Internals.MESSAGE(hwnd, msg, wParam, lParam);
|
var winMsg = new MESSAGE(hwnd, msg, wParam, lParam);
|
||||||
|
|
||||||
// no need to do another lock call when using marshal alloc
|
// no need to do another lock call when using marshal alloc
|
||||||
msgPtr = Marshal.AllocHGlobal(Marshal.SizeOf(winMsg));
|
msgPtr = Marshal.AllocHGlobal(Marshal.SizeOf(winMsg));
|
||||||
|
|||||||
10
README.md
10
README.md
@@ -50,7 +50,9 @@ TwainSession class provides many events, but these 2 are the most important
|
|||||||
* TransferReady - fired before a transfer occurs. You can cancel the current transfer
|
* TransferReady - fired before a transfer occurs. You can cancel the current transfer
|
||||||
or all subsequent transfers using the event object.
|
or all subsequent transfers using the event object.
|
||||||
* DataTransferred - fired after the transfer has occurred. The data available depends on
|
* DataTransferred - fired after the transfer has occurred. The data available depends on
|
||||||
what you've specified using the TWAIN API before starting the transfer.
|
what you've specified using the TWAIN API before starting the transfer. If using image
|
||||||
|
native transfer, the event arg provides a quick GetNativeBitmap() method to convert the
|
||||||
|
data to a System.Drawing.Bitmap.
|
||||||
|
|
||||||
NOTE: do not try to close the source/session in the handler of these 2 events or something
|
NOTE: do not try to close the source/session in the handler of these 2 events or something
|
||||||
unpredictable will happen. Either let the scan run its course or cancel the scan using the flag
|
unpredictable will happen. Either let the scan run its course or cancel the scan using the flag
|
||||||
@@ -137,9 +139,9 @@ session.Close();
|
|||||||
|
|
||||||
Caveats
|
Caveats
|
||||||
--------------------------------------
|
--------------------------------------
|
||||||
At the moment this lib does not provide ways to parse transferred image data and require
|
At the moment the DataTransferredEventArgs only provides conversion routine to
|
||||||
consumers to do the conversion themselves. The winform project contains one such
|
a Bitmap image when using native transfer.
|
||||||
example for handling DIB image pointer in native transfer using the CommonWin32 lib.
|
If other transfer methods are used you'll have to deal with them yourself.
|
||||||
|
|
||||||
If you just call session.Open() without passing a message loop hook argument, an
|
If you just call session.Open() without passing a message loop hook argument, an
|
||||||
internal message loop will be started behind the scenes. When this happens the session events may be raised from another thread.
|
internal message loop will be started behind the scenes. When this happens the session events may be raised from another thread.
|
||||||
|
|||||||
@@ -77,6 +77,7 @@
|
|||||||
</Reference>
|
</Reference>
|
||||||
<Reference Include="System" />
|
<Reference Include="System" />
|
||||||
<Reference Include="System.Data" />
|
<Reference Include="System.Data" />
|
||||||
|
<Reference Include="System.Drawing" />
|
||||||
<Reference Include="System.Windows.Forms" />
|
<Reference Include="System.Windows.Forms" />
|
||||||
<Reference Include="System.Windows.Interactivity, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
|
<Reference Include="System.Windows.Interactivity, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
|
||||||
<HintPath>..\..\packages\MvvmLightLibs.5.0.2.0\lib\net40\System.Windows.Interactivity.dll</HintPath>
|
<HintPath>..\..\packages\MvvmLightLibs.5.0.2.0\lib\net40\System.Windows.Interactivity.dll</HintPath>
|
||||||
|
|||||||
@@ -289,7 +289,7 @@ namespace Tester.WPF
|
|||||||
BitmapSource img = null;
|
BitmapSource img = null;
|
||||||
if (e.NativeData != IntPtr.Zero)
|
if (e.NativeData != IntPtr.Zero)
|
||||||
{
|
{
|
||||||
img = e.NativeData.GetWPFBitmap();
|
img = e.GetNativeBitmap().ConvertToWpfBitmap();
|
||||||
}
|
}
|
||||||
else if (!string.IsNullOrEmpty(e.FileDataPath))
|
else if (!string.IsNullOrEmpty(e.FileDataPath))
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
using CommonWin32;
|
using NTwain;
|
||||||
using NTwain;
|
|
||||||
using NTwain.Data;
|
using NTwain.Data;
|
||||||
using System;
|
using System;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
@@ -91,7 +90,7 @@ namespace Tester.Winform
|
|||||||
Bitmap img = null;
|
Bitmap img = null;
|
||||||
if (e.NativeData != IntPtr.Zero)
|
if (e.NativeData != IntPtr.Zero)
|
||||||
{
|
{
|
||||||
img = e.NativeData.GetDrawingBitmap();
|
img = e.GetNativeBitmap();
|
||||||
}
|
}
|
||||||
else if (!string.IsNullOrEmpty(e.FileDataPath))
|
else if (!string.IsNullOrEmpty(e.FileDataPath))
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -38,10 +38,6 @@
|
|||||||
<ApplicationIcon>scanner.ico</ApplicationIcon>
|
<ApplicationIcon>scanner.ico</ApplicationIcon>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Reference Include="CommonWin32, Version=2.0.0.0, Culture=neutral, PublicKeyToken=a0a4edcfe233918d, processorArchitecture=MSIL">
|
|
||||||
<SpecificVersion>False</SpecificVersion>
|
|
||||||
<HintPath>..\..\packages\CommonWin32.2.0.5.5\lib\net35-Client\CommonWin32.dll</HintPath>
|
|
||||||
</Reference>
|
|
||||||
<Reference Include="System" />
|
<Reference Include="System" />
|
||||||
<Reference Include="System.Drawing" />
|
<Reference Include="System.Drawing" />
|
||||||
<Reference Include="System.Windows.Forms" />
|
<Reference Include="System.Windows.Forms" />
|
||||||
@@ -70,7 +66,6 @@
|
|||||||
<DesignTime>True</DesignTime>
|
<DesignTime>True</DesignTime>
|
||||||
</Compile>
|
</Compile>
|
||||||
<None Include="app.config" />
|
<None Include="app.config" />
|
||||||
<None Include="packages.config" />
|
|
||||||
<None Include="Properties\Settings.settings">
|
<None Include="Properties\Settings.settings">
|
||||||
<Generator>SettingsSingleFileGenerator</Generator>
|
<Generator>SettingsSingleFileGenerator</Generator>
|
||||||
<LastGenOutput>Settings.Designer.cs</LastGenOutput>
|
<LastGenOutput>Settings.Designer.cs</LastGenOutput>
|
||||||
|
|||||||
@@ -1,4 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<packages>
|
|
||||||
<package id="CommonWin32" version="2.0.5.5" targetFramework="net35-Client" />
|
|
||||||
</packages>
|
|
||||||
Reference in New Issue
Block a user