📄 freeimagewrapper.cs
字号:
// ==========================================================
// FreeImage 3 .NET wrapper
// Original FreeImage 3 functions and .NET compatible derived functions
//
// Design and implementation by
// - Jean-Philippe Goerke (jpgoerke@users.sourceforge.net)
// - Carsten Klein (cklein05@users.sourceforge.net)
//
// Contributors:
// - David Boland (davidboland@vodafone.ie)
//
// Main reference : MSDN Knowlede Base
//
// This file is part of FreeImage 3
//
// COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS, WITHOUT WARRANTY
// OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, WITHOUT LIMITATION, WARRANTIES
// THAT THE COVERED CODE IS FREE OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE
// OR NON-INFRINGING. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED
// CODE IS WITH YOU. SHOULD ANY COVERED CODE PROVE DEFECTIVE IN ANY RESPECT, YOU (NOT
// THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE COST OF ANY NECESSARY
// SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL
// PART OF THIS LICENSE. NO USE OF ANY COVERED CODE IS AUTHORIZED HEREUNDER EXCEPT UNDER
// THIS DISCLAIMER.
//
// Use at your own risk!
// ==========================================================
// ==========================================================
// CVS
// $Revision: 1.6 $
// $Date: 2008/06/17 13:50:59 $
// $Id: FreeImageWrapper.cs,v 1.6 2008/06/17 13:50:59 cklein05 Exp $
// ==========================================================
using System;
using System.Collections;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Reflection;
using System.Runtime.InteropServices;
using FreeImageAPI.IO;
using FreeImageAPI.Metadata;
namespace FreeImageAPI
{
/// <summary>
/// Static class importing functions from the FreeImage library
/// and providing additional functions.
/// </summary>
public static partial class FreeImage
{
#region Constants
/// <summary>
/// Array containing all 'FREE_IMAGE_MDMODEL's.
/// </summary>
public static readonly FREE_IMAGE_MDMODEL[] FREE_IMAGE_MDMODELS =
(FREE_IMAGE_MDMODEL[])Enum.GetValues(typeof(FREE_IMAGE_MDMODEL));
/// <summary>
/// Saved instance for faster access.
/// </summary>
private static readonly ConstructorInfo PropertyItemConstructor =
typeof(PropertyItem).GetConstructor(
BindingFlags.NonPublic | BindingFlags.Instance, null, new Type[] { }, null);
private const int DIB_RGB_COLORS = 0;
private const int DIB_PAL_COLORS = 1;
private const int CBM_INIT = 0x4;
/// <summary>
/// An uncompressed format.
/// </summary>
public const int 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.
/// </summary>
public const int 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.
/// </summary>
public const int BI_RLE4 = 2;
/// <summary>
/// Specifies that the bitmap is not compressed and that the color table consists of three
/// <b>DWORD</b> color masks that specify the red, green, and blue components, respectively,
/// of each pixel. This is valid when used with 16- and 32-bpp bitmaps.
/// </summary>
public const int BI_BITFIELDS = 3;
/// <summary>
/// <b>Windows 98/Me, Windows 2000/XP:</b> Indicates that the image is a JPEG image.
/// </summary>
public const int BI_JPEG = 4;
/// <summary>
/// <b>Windows 98/Me, Windows 2000/XP:</b> Indicates that the image is a PNG image.
/// </summary>
public const int BI_PNG = 5;
#endregion
#region Callback
// Callback delegate
private static OutputMessageFunction outputMessageFunction;
// Handle to pin the functions address
private static GCHandle outputMessageHandle;
static FreeImage()
{
// Check if FreeImage.dll is present and cancel setting the callbackfuntion if not
if (!IsAvailable())
{
return;
}
// Create a delegate (function pointer) to 'OnMessage'
outputMessageFunction = new OutputMessageFunction(OnMessage);
// Pin the object so the garbage collector does not move it around in memory
outputMessageHandle = GCHandle.Alloc(outputMessageFunction, GCHandleType.Normal);
// Set the callback
SetOutputMessage(outputMessageFunction);
}
/// <summary>
/// Internal callback
/// </summary>
private static void OnMessage(FREE_IMAGE_FORMAT fif, string message)
{
// Invoke the message
if (Message != null)
{
Message.Invoke(fif, message);
}
}
/// <summary>
/// Internal errors in FreeImage generate a logstring that can be
/// captured by this event.
/// </summary>
public static event OutputMessageFunction Message;
#endregion
#region General functions
/// <summary>
/// Returns the internal version of this FreeImage 3 .NET wrapper.
/// </summary>
/// <returns>The internal version of this FreeImage 3 .NET wrapper.</returns>
public static string GetWrapperVersion()
{
return FREEIMAGE_MAJOR_VERSION + "." + FREEIMAGE_MINOR_VERSION + "." + FREEIMAGE_RELEASE_SERIAL;
}
/// <summary>
/// Returns a value indicating if the FreeImage DLL is available or not.
/// </summary>
/// <returns>True, if the FreeImage DLL is available, false otherwise.</returns>
public static bool IsAvailable()
{
try
{
// Call a static fast executing function
GetVersion();
// No exception thrown, the dll seems to be present
return true;
}
catch (DllNotFoundException)
{
return false;
}
catch (EntryPointNotFoundException)
{
return false;
}
}
#endregion
#region Bitmap management functions
/// <summary>
/// Converts a FreeImage bitmap to a .NET <see cref="System.Drawing.Bitmap"/>.
/// </summary>
/// <param name="dib">Handle to a FreeImage bitmap.</param>
/// <returns>The converted .NET <see cref="System.Drawing.Bitmap"/>.</returns>
/// <remarks>Copying metadata has been disabled until a proper way
/// of reading and storing metadata in a .NET bitmap is found.</remarks>
/// <exception cref="ArgumentNullException">
/// <paramref name="dib"/> is null.</exception>
/// <exception cref="ArgumentException">
/// The image type of <paramref name="dib"/> is not FIT_BITMAP.</exception>
public static Bitmap GetBitmap(FIBITMAP dib)
{
return GetBitmap(dib, true);
}
/// <summary>
/// Converts a FreeImage bitmap to a .NET <see cref="System.Drawing.Bitmap"/>.
/// </summary>
/// <param name="dib">Handle to a FreeImage bitmap.</param>
/// <param name="copyMetadata">When true existing metadata will be copied.</param>
/// <returns>The converted .NET <see cref="System.Drawing.Bitmap"/>.</returns>
/// <remarks>Copying metadata has been disabled until a proper way
/// of reading and storing metadata in a .NET bitmap is found.</remarks>
/// <exception cref="ArgumentNullException">
/// <paramref name="dib"/> is null.</exception>
/// <exception cref="ArgumentException">
/// The image type of <paramref name="dib"/> is not FIT_BITMAP.</exception>
internal static Bitmap GetBitmap(FIBITMAP dib, bool copyMetadata)
{
if (dib.IsNull)
{
throw new ArgumentNullException("dib");
}
if (GetImageType(dib) != FREE_IMAGE_TYPE.FIT_BITMAP)
{
throw new ArgumentException("Only bitmaps with type of FIT_BITMAP can be converted.");
}
PixelFormat format = GetPixelFormat(dib);
if ((format == PixelFormat.Undefined) && (GetBPP(dib) == 16u))
{
throw new ArgumentException("Only 16bit 555 and 565 are supported.");
}
int height = (int)GetHeight(dib);
int width = (int)GetWidth(dib);
int pitch = (int)GetPitch(dib);
Bitmap result = new Bitmap(width, height, format);
BitmapData data;
// Locking the complete bitmap in writeonly mode
data = result.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.WriteOnly, format);
// Writing the bitmap data directly into the new created .NET bitmap.
ConvertToRawBits(data.Scan0, dib, pitch, GetBPP(dib),
GetRedMask(dib), GetGreenMask(dib), GetBlueMask(dib), true);
// Unlock the bitmap
result.UnlockBits(data);
// Apply the bitmaps resolution
result.SetResolution(GetResolutionX(dib), GetResolutionY(dib));
// Check whether the bitmap has a palette
if (GetPalette(dib) != IntPtr.Zero)
{
// Get the bitmaps palette to apply changes
ColorPalette palette = result.Palette;
// Get the orgininal palette
Color[] colorPalette = new Palette(dib).ColorData;
// Copy each value
if (palette.Entries.Length == colorPalette.Length)
{
for (int i = 0; i < colorPalette.Length; i++)
{
palette.Entries[i] = colorPalette[i];
}
// Set the bitmaps palette
result.Palette = palette;
}
}
// Copy metadata
if (copyMetadata)
{
try
{
List<PropertyItem> list = new List<PropertyItem>();
// Get a list of all types
FITAG tag;
FIMETADATA mData;
foreach (FREE_IMAGE_MDMODEL model in FREE_IMAGE_MDMODELS)
{
// Get a unique search handle
mData = FindFirstMetadata(model, dib, out tag);
// Check if metadata exists for this type
if (mData.IsNull) continue;
do
{
PropertyItem propItem = CreatePropertyItem();
propItem.Len = (int)GetTagLength(tag);
propItem.Id = (int)GetTagID(tag);
propItem.Type = (short)GetTagType(tag);
byte[] buffer = new byte[propItem.Len];
unsafe
{
byte* src = (byte*)GetTagValue(tag);
fixed (byte* dst = buffer)
{
MoveMemory(dst, src, (uint)propItem.Len);
}
}
propItem.Value = buffer;
list.Add(propItem);
}
while (FindNextMetadata(mData, out tag));
FindCloseMetadata(mData);
}
foreach (PropertyItem propItem in list)
{
result.SetPropertyItem(propItem);
}
}
catch
{
}
}
return result;
}
/// <summary>
/// Converts an .NET <see cref="System.Drawing.Bitmap"/> into a FreeImage bitmap.
/// </summary>
/// <param name="bitmap">The <see cref="System.Drawing.Bitmap"/> to convert.</param>
/// <returns>Handle to a FreeImage bitmap.</returns>
/// <remarks>Copying metadata has been disabled until a proper way
/// of reading and storing metadata in a .NET bitmap is found.</remarks>
/// <exception cref="ArgumentNullException">
/// <paramref name="bitmap"/> is null.</exception>
/// <exception cref="ArgumentException">
/// The bitmaps pixelformat is invalid.</exception>
public static FIBITMAP CreateFromBitmap(Bitmap bitmap)
{
return CreateFromBitmap(bitmap, false);
}
/// <summary>
/// Converts an .NET <see cref="System.Drawing.Bitmap"/> into a FreeImage bitmap.
/// </summary>
/// <param name="bitmap">The <see cref="System.Drawing.Bitmap"/> to convert.</param>
/// <param name="copyMetadata">When true existing metadata will be copied.</param>
/// <returns>Handle to a FreeImage bitmap.</returns>
/// <remarks>Copying metadata has been disabled until a proper way
/// of reading and storing metadata in a .NET bitmap is found.</remarks>
/// <exception cref="ArgumentNullException">
/// <paramref name="bitmap"/> is null.</exception>
/// <exception cref="ArgumentException">
/// The bitmaps pixelformat is invalid.</exception>
internal static FIBITMAP CreateFromBitmap(Bitmap bitmap, bool copyMetadata)
{
if (bitmap == null)
{
throw new ArgumentNullException("bitmap");
}
uint bpp, red_mask, green_mask, blue_mask;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -