mirror of
https://github.com/soukoku/ntwain.git
synced 2025-12-01 10:54:08 +08:00
Added tiff support.
This commit is contained in:
@@ -4,6 +4,7 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.Drawing.Imaging;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Security;
|
||||
@@ -14,77 +15,117 @@ namespace NTwain
|
||||
{
|
||||
public static class ImageTools
|
||||
{
|
||||
internal static Bitmap ReadBitmapImage(IntPtr dibBitmap)
|
||||
internal static bool IsDib(IntPtr data)
|
||||
{
|
||||
// a quick check not guaranteed correct,
|
||||
// compare first 2 bytes to size of struct (which is also the first field)
|
||||
var test = Marshal.ReadInt16(data);
|
||||
// should be 40
|
||||
return test == BITMAPINFOHEADER.GetByteSize();
|
||||
}
|
||||
internal static bool IsTiff(IntPtr data)
|
||||
{
|
||||
var test = Marshal.ReadInt16(data);
|
||||
// should be II
|
||||
return test == 0x4949;
|
||||
}
|
||||
internal static Bitmap ReadBitmapImage(IntPtr data)
|
||||
{
|
||||
Bitmap finalImg = null;
|
||||
Bitmap tempImg = null;
|
||||
if (IsDib(dibBitmap))
|
||||
try
|
||||
{
|
||||
try
|
||||
{
|
||||
var header = (BITMAPINFOHEADER)Marshal.PtrToStructure(dibBitmap, typeof(BITMAPINFOHEADER));
|
||||
var header = (BITMAPINFOHEADER)Marshal.PtrToStructure(data, 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 (header.Validate())
|
||||
{
|
||||
if (tempImg != null)
|
||||
PixelFormat format = header.GetDrawingPixelFormat();
|
||||
tempImg = new Bitmap(header.biWidth, Math.Abs(header.biHeight), header.GetStride(), format, header.GetScan0(data));
|
||||
ColorPalette pal = header.GetDrawingPalette(data);
|
||||
if (pal != null)
|
||||
{
|
||||
tempImg.Dispose();
|
||||
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)
|
||||
internal static Image ReadTiffImage(IntPtr data)
|
||||
{
|
||||
// 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();
|
||||
// this is modified from twain cs sample
|
||||
// http://sourceforge.net/projects/twainforcsharp/?source=typ_redirect
|
||||
|
||||
|
||||
// Find the size of the image so we can turn it into a memory stream...
|
||||
var headerSize = Marshal.SizeOf(typeof(TIFFHEADER));
|
||||
var tagSize = Marshal.SizeOf(typeof(TIFFTAG));
|
||||
var tiffSize = 0;
|
||||
var header = (TIFFHEADER)Marshal.PtrToStructure(data, typeof(TIFFHEADER));
|
||||
var tagPtr = data.ToInt64() + headerSize;
|
||||
for (int i = 0; i < 999; i++)
|
||||
{
|
||||
tagPtr += (tagSize * i);
|
||||
var tag = (TIFFTAG)Marshal.PtrToStructure((IntPtr)tagPtr, typeof(TIFFTAG));
|
||||
|
||||
switch (tag.u16Tag)
|
||||
{
|
||||
case 273: // StripOffsets...
|
||||
case 279: // StripByteCounts...
|
||||
tiffSize += (int)tag.u32Value;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (tiffSize > 0)
|
||||
{
|
||||
var dataCopy = new byte[tiffSize];
|
||||
Marshal.Copy(data, dataCopy, 0, tiffSize);
|
||||
|
||||
return Image.FromStream(new MemoryStream(dataCopy));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts a <see cref="Bitmap"/> to WPF <see cref="BitmapSource"/>.
|
||||
/// Converts an <see cref="Image"/> to WPF <see cref="BitmapSource"/> if the image
|
||||
/// is a <see cref="Bitmap"/>.
|
||||
/// </summary>
|
||||
/// <param name="image">The image to convert.</param>
|
||||
/// <returns></returns>
|
||||
public static BitmapSource ConvertToWpfBitmap(this Bitmap image)
|
||||
public static BitmapSource ConvertToWpfBitmap(this Image image)
|
||||
{
|
||||
if (image != null)
|
||||
var bmp = image as Bitmap;
|
||||
if (bmp != null)
|
||||
{
|
||||
using (var hbm = new SafeHBitmapHandle(image.GetHbitmap(), true))
|
||||
using (var hbm = new SafeHBitmapHandle(bmp.GetHbitmap(), true))
|
||||
{
|
||||
return System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(
|
||||
hbm.DangerousGetHandle(),
|
||||
@@ -110,10 +151,5 @@ namespace NTwain
|
||||
return NativeMethods.DeleteObject(handle);
|
||||
}
|
||||
}
|
||||
|
||||
internal static Bitmap ReadTiffImage(IntPtr data)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user