/* ----------------------------------------------------------
* 文件名称:ImageUtils.cs
* 作者:秦建辉
*
* 微信:splashcn
*
* 博客:http://www.firstsolver.com/wordpress/
*
* 开发环境:
* Visual Studio V2017
* .NET Framework 4 Client Profile
*
* 版本历史:
* V1.1 2018年12月7日
* 完善接口
*
* V1.0 2018年04月25日
* Image类图像处理工具
------------------------------------------------------------ */
using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.Runtime.InteropServices;
namespace Com.FirstSolver.Splash
{
public static class ImageUtils
{
/// <summary>
/// 将Bitmap转换成Bgra线性数组
/// </summary>
/// <param name="bmp">要转换的Bitmap</param>
/// <returns>Bgra线性数组</returns>
/// <remarks>返回结果后面需要调用Marshal.FreeHGlobal释放资源</remarks>
public static IntPtr ToBgraPtr(this Bitmap bmp)
{
int PixelWidth = bmp.Width; // 图像宽度
int PixelHeight = bmp.Height; // 图像高度
int Size = (PixelHeight * PixelWidth) << 2;
IntPtr Bgra = Marshal.AllocHGlobal(Size);
// 锁定位图到系统内存
BitmapData bmpData = bmp.LockBits(new Rectangle(0, 0, PixelWidth, PixelHeight), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);
CopyMemory(Bgra, bmpData.Scan0, Size);
bmp.UnlockBits(bmpData); // 从系统内存解锁位图
return Bgra;
}
/// <summary>
/// 将Bitmap转换成灰度线性数组
/// </summary>
/// <param name="bmp">要转换的Bitmap</param>
/// <returns>灰度线性数组</returns>
/// <remarks>返回结果后面需要调用Marshal.FreeHGlobal释放资源</remarks>
public static IntPtr ToGrayPtr(this Bitmap bmp)
{
int PixelWidth = bmp.Width; // 图像宽度
int PixelHeight = bmp.Height; // 图像高度
int Size = PixelHeight * PixelWidth;
IntPtr Gray = Marshal.AllocHGlobal(Size);
BitmapData bmpData = bmp.LockBits(new Rectangle(0, 0, PixelWidth, PixelHeight), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);
BgraToGray(bmpData.Scan0, Gray, Size);
bmp.UnlockBits(bmpData); // 从系统内存解锁位图
return Gray;
}
/// <summary>
/// 将Bitmap转换成Bgr线性数组
/// </summary>
/// <param name="bmp">要转换的Bitmap</param>
/// <returns>Bgr线性数组</returns>
/// <remarks>返回结果后面需要调用Marshal.FreeHGlobal释放资源</remarks>
public static IntPtr ToBgrPtr(this Bitmap bmp)
{
int PixelWidth = bmp.Width; // 图像宽度
int PixelHeight = bmp.Height; // 图像高度
int Size = PixelHeight * PixelWidth;
IntPtr Bgr = Marshal.AllocHGlobal(Size * 3);
BitmapData bmpData = bmp.LockBits(new Rectangle(0, 0, PixelWidth, PixelHeight), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);
BgraToBgr(bmpData.Scan0, Bgr, Size);
bmp.UnlockBits(bmpData); // 从系统内存解锁位图
return Bgr;
}
/// <summary>
/// 将位图转换为一维Bgra彩色数组
/// </summary>
/// <param name="bmp">原始位图</param>
/// <returns>一维Bgra彩色数组</returns>
public static byte[] ToBgra(this Bitmap bmp)
{
int PixelWidth = bmp.Width; // 图像宽度
int PixelHeight = bmp.Height; // 图像高度
int Size = (PixelHeight * PixelWidth) << 2;
byte[] Bgra = new byte[Size];
// 锁定位图到系统内存
BitmapData bmpData = bmp.LockBits(new Rectangle(0, 0, PixelWidth, PixelHeight), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);
Marshal.Copy(bmpData.Scan0, Bgra, 0, Size); // 从非托管内存拷贝数据到托管内存
bmp.UnlockBits(bmpData); // 从系统内存解锁位图
return Bgra;
}
/// <summary>
/// 将位图转换为线性灰度数组(256级灰度)
/// </summary>
/// <param name="bmp">原始位图</param>
/// <returns>线性灰度数组</returns>
public static byte[] ToGray(this Bitmap bmp)
{
int PixelWidth = bmp.Width; // 图像宽度
int PixelHeight = bmp.Height; // 图像高度
int Size = PixelHeight * PixelWidth;
byte[] Gray = new byte[Size];
BitmapData bmpData = bmp.LockBits(new Rectangle(0, 0, PixelWidth, PixelHeight), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);
BgraToGray(bmpData.Scan0, Gray, Size);
bmp.UnlockBits(bmpData); // 从系统内存解锁位图
return Gray;
}
/// <summary>
/// 将Bitmap转换成Bgr数组
/// </summary>
/// <param name="bmp">要转换的Bitmap</param>
/// <returns>Bgr数组</returns>
public static byte[] ToBgr(this Bitmap bmp)
{
int PixelWidth = bmp.Width; // 图像宽度
int PixelHeight = bmp.Height; // 图像高度
int Size = PixelHeight * PixelWidth;
byte[] Bgr = new byte[Size * 3];
BitmapData bmpData = bmp.LockBits(new Rectangle(0, 0, PixelWidth, PixelHeight), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);
BgraToBgr(bmpData.Scan0, Bgr, Size);
bmp.UnlockBits(bmpData); // 从系统内存解锁位图
return Bgr;
}
/// <summary>
/// 将Image转换为Jpeg图像字节数组
/// </summary>
/// <param name="image">要转换的图像</param>
/// <returns>Jpeg图像字节数组</returns>
public static byte[] ToJpegByteArray(this Image image)
{
ImageCodecInfo codec = GetImageEncoder(ImageFormat.Jpeg);
if (codec == null) return null;
using (System.IO.MemoryStream ms = new System.IO.MemoryStream())
{
using (EncoderParameters eps = new EncoderParameters(1))
{
using (EncoderParameter ep = new EncoderParameter(Encoder.Quality, 100L))
{
eps.Param[0] = ep;
image.Save(ms, codec, eps);
return ms.ToArray();
}
}
}
}
/// <summary>
/// 将Image转换为Bmp图像字节数组
/// </summary>
/// <param name="image">要转换的图像</param>
/// <returns>Bmp图像字节数组</returns>
public static byte[] ToBmpByteArray(this Image image)
{
using (System.IO.MemoryStream ms = new System.IO.MemoryStream())
{
image.Save(ms, ImageFormat.Bmp);
return ms.ToArray();
}
}
/// <summary>
/// 获取指定图像格式的编码器
/// </summary>
/// <param name="format">图像格式</param>
/// <returns>图像编码器</returns>
public static ImageCodecInfo GetImageEncoder(this ImageFormat format)
{
ImageCodecInfo[] codecs = ImageCodecInfo.GetImageEncoders();
foreach (ImageCodecInfo codec in codecs)
{
if (codec.FormatID.Equals(format.Guid)) return codec;
}
return null;
}
/// <summary>
/// 将字节数组转换为位图图像
/// </summary>
/// <param name="buffer">字节数组</param>
/// <returns>位图图像</returns>
public static Bitmap ToBitmap(this byte[] buffer)
{
return new Bitmap(new System.IO.MemoryStream(buffer));
}
/// <summary>
/// 生成Bgra32位图图像
/// </summary>
/// <param name="bgra">Bgra数组</param>
/// <param name="width">图像宽度</param>
/// <param name="height">图像高度</param>
/// <returns>Bgra32位图图像</returns>
public static Bitmap ToBgra32Bitmap(byte[] bgra, int width, int height)
{
Bitmap bmp = new Bitmap(width, height, PixelFormat.Format32bppArgb);
BitmapData data = bmp.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb);
Marshal.Copy(bgra, 0, data.Scan0, bgra.Length);
bmp.UnlockBits(data);
return bmp;
}
/// <summary>
/// 生成Bgra32位图图像
/// </summary>
/// <param name="bgra">Bgra数组</param>
/// <param name="width">图像宽度</param>
/// <param name="height">图像高度</param>
/// <returns>Bgra32位图图像</returns>
public static Bitmap ToBgra32Bitmap(IntPtr bgra, int width, int height)
{
Bitmap bmp = new Bitmap(width, height, PixelFormat.Format32bppArgb);
BitmapData data = bmp.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb);
CopyMemory(data.Scan0, bgra, (width * height) << 2);
bmp.UnlockBits(data);
return bmp;
}
/// <summary>
/// 将灰度数组转换为灰度图像(256级灰度)
/// </summary>
/// <param name="gray">灰度数组</param>
/// <param name="width">图像宽度</param>
/// <param name="height">图像高度</param>
/// <returns>灰度图像</returns>
public static Bitmap ToGrayBitmap(byte[] gray, int width, int height)
{ // 创建灰度图像
Bitmap bmp = new Bitmap(width, height, PixelFormat.Format8bppIndexed);
// 设置调色板
ColorPalette cp = bmp.Palette;
for (int i = 0; i < 256; i++) cp.Entries[i] = Color.FromArgb(i, i, i);
bmp.Palette = cp;
// 设置位图图像特性
int Stride = ((width + 3) >> 2) << 2; // 跨距宽度
BitmapData data = bmp.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.WriteOnly, PixelFormat.Format8bppIndexed);
for (int i = 0; i < height; i++)
{
Marshal.Copy(gray, i * width, data.Scan0 + i * Stride, width);
}
bmp.UnlockBits(data);
return bmp;
}
/// <summary>
/// 将灰度数组转换为灰度图像(256级灰度)
/// </summary>
/// <param name="gray">灰度数组</param>
/// <param name="width">图像宽度</param>
/// <param name="height">图像高度</param>
/// <returns>灰度图像</returns>
public static Bitmap ToGrayBitmap(IntPtr gray, int width, int height)
{ // 创建灰度图像
Bitmap bmp = new Bitmap(width, height, PixelFormat.Format8bppIndexed);
// 设置调色板
ColorPalette cp = bmp.Palette;
for (int i = 0; i < 256; i++) cp.Entries[i] = Color.FromArgb(i, i, i);
bmp.Palette = cp;
// 设置位图图像特性
int Stride = ((width + 3) >> 2) << 2; // 跨距宽度
BitmapData data = bmp.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.WriteOnly, PixelFormat.Format8bppIndexed);
for (int i = 0; i < height; i++)
{
CopyMemory(data.Scan0 + i * Stride, gray + i * width, width);
}
bmp.UnlockBits(data);
return bmp;
}
/// <summary>
/// 将二值化数组转换为二值化图像
/// </summary>
/// <param name="binary">二值化数组</param>
/// <param name="width">图像宽度</param>
/// <param name="height">图像高度</param>
/// <returns>二值化图像</returns>
public static Bitmap ToBinaryBitmap(byte[] binary, int width, int height)
{ // 将二值化数组转换为二值化数据
int Stride = ((width + 31) >> 5) << 2;
byte[] Pixels = new byte[height * Stride];
int Index = 0;
for (int i = 0; i < height; i++)
{
int Base = i * Stride;
for (int j = 0; j < width; j++)
{
if (binary[Index++] != 0) Pixels[Base + (j >> 3)] |= Convert.ToByte(0x80 >> (j & 0x7));
}
}
// 创建黑白图像
Bitmap bmp = new Bitmap(width, height, PixelFormat.Format1bppIndexed);
// 设置调色板
ColorPalette cp = bmp.Palette;
cp.Entries[0] = Color.Black; // 黑色
cp.Entries[1] = Color.White; // 白色
bmp.Palette = cp;
// 设置位图图像特性
BitmapData data = bmp.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.WriteOnly, PixelFormat.Format1bppIndexed);
Marshal.Copy(Pixels, 0, data.Scan0, Pixels.Length);
bmp.UnlockBits(data);
return bmp;
}
/// <summary>
/// 位图灰度化
/// </summary>
/// <param name="bmp">原始位图</param>
/// <returns>灰度位图</returns>
public static Bitmap ToGrayBitmap(this Bitmap bmp)
{
int PixelHeight = bmp.Height; // 图像高度
int PixelWidth = bmp.Width; // 图像宽度
int Size = (PixelHeight * PixelWidth) << 2;
byte[] Bgra = new byte[Size];
// 锁定位图到系统内存
BitmapData bmpData = bmp.LockBits(new Rectangle(0, 0, PixelWidth, PixelHeight), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);
Marshal.Copy(bmpData.Scan0, Bgra, 0, Size); // 从非托管内存拷贝数据到托管内存
bmp.UnlockBits(bmpData); // 从系统内存解锁位图
// 将像素数据转换为灰度数据
int GrayStride = ((PixelWidth + 3) >> 2) << 2;
byte[] Gray = new byte[PixelHeight * GrayStride];
int Index = 0;
for (int i = 0; i < PixelHeight; i++)
{
int Base = i * GrayStride;
for (int j = 0; j < PixelWidth; j++)
{
Gray[Base++] = Convert.ToByte((Bgra[Index + 2] * 19595 + Bgra[Index + 1] * 38469 + Bgra[Index] * 7471 + 32768) >> 16);
Index += 4;
}
}
// 创建灰度图像
Bitmap GrayBmp = new Bitmap(PixelWidth, PixelHeight, PixelFormat.Format8bppIndexed);
// 设置调色表
ColorPalette cp = GrayBmp.Palette;
for (int i = 0; i < 256; i++) cp.Entries[i] = Color.FromArgb(i, i, i);
GrayBmp.Palette = cp;
// 设置位图图像特性
BitmapData GrayBmpData = GrayBmp.LockBits(new Rectangle(0, 0, PixelWidth, PixelHeight), ImageLockMode.WriteOnly, PixelFormat.Format8bppIndexed);
Marshal.Copy(Gray, 0, GrayBmpData.Scan0, Gray.Length);
GrayBmp.UnlockBits(GrayBmpData);
return GrayBmp;
}
#region DLLIMPORT
[DllImport("FileUtils.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool Prepare();
/// <summary>
/// 释放存储空间
/// </summary>
/// <param name="buffer">存储空间</param>
[DllImport("FileUtils.dll", EntryPoint = "FreeByteArray")]
public static extern void Free(ref IntPtr buffer);
/// <summary>
/// 读取文件内容到存储空间
/// </summary>
/// <param name="filename">文件名</param>
/// <param name="buffer">存储空间,后续必须调用Free释放存储空间</param>
/// <param name="size">存储空间大小</param>
/// <returns>错误代码</returns>
[DllImport("FileUtils.dll", CharSet = CharSet.Unicode, EntryPoint = "ReadFromFile")]
public static extern int ReadFile(string filename, out IntPtr buffer, out int size);
/// <summary>
/// 存储空间写入文件
/// </summary>
/// <param name="filename">文件名</param>
/// <param name="buffer">存储空间</param>
/// <param name="size">存储空间大小</param>
/// <returns>错误代码</returns>
[DllImport("FileUtils.dll", CharSet = CharSet.Unicode, EntryPoint = "WriteToFile")]
public static extern int WriteFile(string filename, IntPtr buffer, int size);
/// <summary>
/// 将图像Bgra数组转换为图像灰度数组
/// </summary>
/// <param name="bgra">图像Bgra数组</param>
/// <param name="gray">图像灰度数组</param>
/// <param name="size">需要转换的像素数</param>
[DllImport("FileUtils.dll")]
public static extern void BgraToGray(IntPtr bgra, IntPtr gray, int size);
[DllImport("FileUtils.dll")]
private static extern void BgraToGray(IntPtr bgra, byte[] gray, int size);
[DllImport("FileUtils.dll")]
public static extern void BgraToGray(byte[] bgra, byte[] gray, int size);
/// <summary>
/// 将Bgra数组转换为Bgr数组
/// </summary>
/// <param name="bgra">要转换的Bgra数组</param>
/// <param name="bgr">Bgr数组</param>
/// <param name="size">需要转换的像素数</param>
[DllImport("FileUtils.dll")]
public static extern void BgraToBgr(IntPtr bgra, IntPtr bgr, int size);
[DllImport("FileUtils.dll")]
private static extern void BgraToBgr(IntPtr bgra, byte[] bgr, int size);
[DllImport("FileUtils.dll")]
public static extern void BgraToBgr(byte[] bgra, byte[] bgr, int size);
[DllImport("FileUtils.dll")]
public static extern int ToBgra(IntPtr hBmp, out IntPtr bgra, out int width, out int height);
[DllImport("FileUtils.dll")]
public static extern int ToGray(IntPtr hBmp, out IntPtr gray, out int width, out int height);
[DllImport("FileUtils.dll", EntryPoint = "ToHBitmapFromFile")]
public static extern IntPtr ToHBitmap(string filename);
[DllImport("FileUtils.dll", EntryPoint = "ToBgraFromFile")]
public static extern int ToBgra(string filename, out IntPtr bgra, out int width, out int height);
[DllImport("FileUtils.dll", EntryPoint = "ToGrayFromFile")]
public static extern int ToGray(string filename, out IntPtr gray, out int width, out int height);
[DllImport("FileUtils.dll")]
public static extern int StartupGdiplus();
[DllImport("FileUtils.dll")]
public static extern void ShutdownGdiplus();
[DllImport("FileUtils.dll", EntryPoint = "ToHBitmapFromBuffer")]
public static extern IntPtr ToHBitmap(IntPtr buffer, int size);
[DllImport("FileUtils.dll", EntryPoint = "ToHBitmapFromBuffer")]
public static extern IntPtr ToHBitmap(byte[] buffer, int size);
[DllImport("FileUtils.dll", EntryPoint = "ToBgraFromBuffer")]
public static extern int ToBgra(IntPtr buffer, int size, out IntPtr bgra, out int width, out int height);
[DllImport("FileUtils.dll", EntryPoint = "ToBgraFromBuffer")]
public static extern int ToBgra(byte[] buffer, int size, out IntPtr bgra, out int width, out int height);
[DllImport("FileUtils.dll", EntryPoint = "ToGrayFromBuffer")]
public static extern int ToGray(IntPtr buffer, int size, out IntPtr gray, out int width, out int height);
[DllImport("FileUtils.dll", EntryPoint = "ToGrayFromBuffer")]
public static extern int ToGray(byte[] buffer, int size, out IntPtr gray, out int width, out int height);
[DllImport("Gdi32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool DeleteObject(IntPtr hObject);
/// <summary>
/// 内存拷贝
/// </summary>
/// <param name="dest">目标地址</param>
/// <param name="src">源地址</param>
/// <param name="count">要拷贝的字节数</param>
[DllImport("Kernel32.dll")]
public static extern void CopyMemory(IntPtr Destination, IntPtr Source, int Length);
#endregion
}
}
/* ----------------------------------------------------------
* 文件名称:ImageSourceUtils.cs
*
* 作者:秦建辉
*
* 微信:splashcn
*
* 博客:http://www.firstsolver.com/wordpress/
*
* 开发环境:
* Visual Studio V2017
* .NET Framework 4 Client Profile
*
* 版本历史:
* V1.1 2018年12月09日
* 完善接口
*
* V1.0 2018年01月03日
* ImageSource类图像处理工具
* ------------------------------------------------------------ */
using System;
using System.Drawing.Imaging;
using System.Runtime.InteropServices;
using System.Windows.Media;
using System.Windows.Media.Imaging;
namespace Com.FirstSolver.Splash
{
public static class ImageSourceUtils
{
/// <summary>
/// 生成Bgra数组
/// </summary>
/// <param name="bs">位图像素集</param>
/// <returns>Bgra数组</returns>
/// <remarks>返回结果后面需要调用Marshal.FreeHGlobal释放资源</remarks>
public static IntPtr ToBgraPtr(this BitmapSource bs)
{
int PixelHeight = bs.PixelHeight; // 图像高度
int PixelWidth = bs.PixelWidth; // 图像宽度
int Stride = PixelWidth << 2; // 跨距宽度
IntPtr Bgra = Marshal.AllocHGlobal(PixelHeight * Stride);
if (bs.Format == PixelFormats.Bgr32 || bs.Format == PixelFormats.Bgra32)
{
bs.CopyPixels(System.Windows.Int32Rect.Empty, Bgra, Stride, 0);
}
else
{
new FormatConvertedBitmap(bs, PixelFormats.Bgra32, null, 0).CopyPixels(System.Windows.Int32Rect.Empty, Bgra, Stride, 0);
}
return Bgra;
}
/// <summary>
/// 生成灰度数组
/// </summary>
/// <param name="bs">位图像素集</param>
/// <returns>灰度数组</returns>
/// <remarks>返回结果后面需要调用Marshal.FreeHGlobal释放资源</remarks>
public static IntPtr ToGrayPtr(this BitmapSource bs)
{
int Size = bs.PixelHeight * bs.PixelWidth;
IntPtr Gray = Marshal.AllocHGlobal(Size);
IntPtr Bgra = bs.ToBgraPtr();
ImageUtils.BgraToGray(Bgra, Gray, Size);
Marshal.FreeHGlobal(Bgra);
return Gray;
}
/// <summary>
/// 生成Bgr数组
/// </summary>
/// <param name="bs">位图像素集</param>
/// <returns>Bgr数组</returns>
/// <remarks>返回结果后面需要调用Marshal.FreeHGlobal释放资源</remarks>
public static IntPtr ToBgrPtr(this BitmapSource bs)
{
int Size = bs.PixelHeight * bs.PixelWidth;
IntPtr Bgr = Marshal.AllocHGlobal(Size * 3);
IntPtr Bgra = bs.ToBgraPtr();
ImageUtils.BgraToBgr(Bgra, Bgr, Size);
Marshal.FreeHGlobal(Bgra);
return Bgr;
}
/// <summary>
/// 生成Bgra数组
/// </summary>
/// <param name="bs">位图像素集</param>
/// <returns>Bgra数组</returns>
public static byte[] ToBgra(this BitmapSource bs)
{
int PixelHeight = bs.PixelHeight; // 图像高度
int PixelWidth = bs.PixelWidth; // 图像宽度
int Stride = PixelWidth << 2; // 跨距宽度
byte[] Bgra = new byte[PixelHeight * Stride];
if (bs.Format == PixelFormats.Bgr32 || bs.Format == PixelFormats.Bgra32)
{
bs.CopyPixels(Bgra, Stride, 0);
}
else
{
new FormatConvertedBitmap(bs, PixelFormats.Bgra32, null, 0).CopyPixels(Bgra, Stride, 0);
}
return Bgra;
}
/// <summary>
/// 生成灰度数组
/// </summary>
/// <param name="bs">位图像素集</param>
/// <returns>灰度数组</returns>
public static byte[] ToGray(this BitmapSource bs)
{
int Size = bs.PixelHeight * bs.PixelWidth;
byte[] Gray = new byte[Size];
ImageUtils.BgraToGray(bs.ToBgra(), Gray, Size);
return Gray;
}
/// <summary>
/// 生成Bgr数组
/// </summary>
/// <param name="bs">位图像素集</param>
/// <returns>Bgr数组</returns>
public static byte[] ToBgr(this BitmapSource bs)
{
int Size = bs.PixelHeight * bs.PixelWidth;
byte[] Bgr = new byte[Size * 3];
ImageUtils.BgraToBgr(bs.ToBgra(), Bgr, Size);
return Bgr;
}
/// <summary>
/// 将 BitmapSource 转化为 Jpeg 字节数组
/// </summary>
/// <param name="bs">要转换的 BitmapSource</param>
/// <returns>Jpeg字节数组</returns>
public static byte[] ToJpegByteArray(this BitmapSource bs)
{
using (System.IO.MemoryStream ms = new System.IO.MemoryStream())
{
BitmapEncoder encoder = new JpegBitmapEncoder();
encoder.Frames.Add(BitmapFrame.Create(bs));
encoder.Save(ms);
return ms.ToArray();
}
}
/// <summary>
/// 将 BitmapSource 转化为 Bmp 字节数组
/// </summary>
/// <param name="bs">要转换的 BitmapSource</param>
/// <returns>Bmp字节数组</returns>
public static byte[] ToBmpByteArray(this BitmapSource bs)
{
using (System.IO.MemoryStream ms = new System.IO.MemoryStream())
{
BitmapEncoder encoder = new BmpBitmapEncoder();
encoder.Frames.Add(BitmapFrame.Create(bs));
encoder.Save(ms);
return ms.ToArray();
}
}
/// <summary>
/// 将字节数组转换为 BitmapImage
/// </summary>
/// <param name="buffer">要转换的字节数组</param>
/// <returns>转换后的 BitmapImage</returns>
public static BitmapImage ToBitmapImage(this byte[] buffer)
{
BitmapImage bi = new BitmapImage();
bi.BeginInit();
bi.StreamSource = new System.IO.MemoryStream(buffer);
bi.EndInit();
return bi;
}
/// <summary>
/// 生成Bgra32位图图像集
/// </summary>
/// <param name="bgra">Bgra数组</param>
/// <param name="width">图像宽度</param>
/// <param name="height">图像高度</param>
/// <returns>Bgra32位图图像集</returns>
public static BitmapSource ToBgra32BitmapSource(byte[] bgra, int width, int height)
{
return BitmapSource.Create(width, height, 96, 96, PixelFormats.Bgra32, null, bgra, width << 2);
}
/// <summary>
/// 生成Bgra32位图图像集
/// </summary>
/// <param name="bgra">Bgra数组</param>
/// <param name="width">图像宽度</param>
/// <param name="height">图像高度</param>
/// <returns>Bgra32位图图像集</returns>
public static BitmapSource ToBgra32BitmapSource(IntPtr bgra, int width, int height)
{
int Stride = width << 2;
return BitmapSource.Create(width, height, 96, 96, PixelFormats.Bgra32, null, bgra, height * Stride, Stride);
}
/// <summary>
/// 生成灰度位图图像集
/// </summary>
/// <param name="gray">灰度数组</param>
/// <param name="width">图像宽度</param>
/// <param name="height">图像高度</param>
/// <returns>灰度位图图像集</returns>
public static BitmapSource ToGrayBitmapSource(byte[] gray, int width, int height)
{
int Stride = ((width + 3) >> 2) << 2;
byte[] Buffer = new byte[height * Stride];
for (int i = 0; i < height; i++) Array.Copy(gray, i * width, Buffer, i * Stride, width);
return BitmapSource.Create(width, height, 96, 96, PixelFormats.Indexed8, BitmapPalettes.Gray256, Buffer, Stride);
}
/// <summary>
/// 生成灰度位图图像集
/// </summary>
/// <param name="gray">灰度数组</param>
/// <param name="width">图像宽度</param>
/// <param name="height">图像高度</param>
/// <returns>灰度位图图像集</returns>
public static BitmapSource ToGrayBitmapSource(IntPtr gray, int width, int height)
{
int Stride = ((width + 3) >> 2) << 2;
byte[] Buffer = new byte[height * Stride];
for (int i = 0; i < height; i++) Marshal.Copy(gray + i * width, Buffer, i * Stride, width);
return BitmapSource.Create(width, height, 96, 96, PixelFormats.Indexed8, BitmapPalettes.Gray256, Buffer, Stride);
}
/// <summary>
/// 创建黑白图像
/// </summary>
/// <param name="binary">二值化数组</param>
/// <param name="width">图像宽度</param>
/// <param name="height">图像高度</param>
/// <returns>黑白图像</returns>
public static BitmapSource ToBinaryBitmapSource(byte[] binary, int width, int height)
{
int Stride = ((width + 31) >> 5) << 2;
byte[] Buffer = new byte[height * Stride];
int Index = 0;
for (int i = 0; i < height; i++)
{
int Base = i * Stride;
for (int j = 0; j < width; j++)
{
if (binary[Index++] != 0) Buffer[Base + (j >> 3)] |= Convert.ToByte(0x80 >> (j & 0x7));
}
}
// 创建黑白图像
return BitmapSource.Create(width, height, 96, 96, PixelFormats.Indexed1, BitmapPalettes.BlackAndWhite, Buffer, Stride);
}
/// <summary>
/// 转换成灰度位图图像集
/// </summary>
/// <param name="bs">原始位图图像集</param>
/// <returns>灰度位图图像集</returns>
public static BitmapSource ToGrayBitmapSource(this BitmapSource bs)
{
int PixelHeight = bs.PixelHeight; // 图像高度
int PixelWidth = bs.PixelWidth; // 图像宽度
int Stride = PixelWidth << 2; // 跨距宽度
byte[] Bgra = new Byte[PixelHeight * Stride];
if (bs.Format == PixelFormats.Bgr32 || bs.Format == PixelFormats.Bgra32)
{ // 拷贝像素数据
bs.CopyPixels(Bgra, Stride, 0);
}
else
{ // 先进行像素格式转换,再拷贝像素数据
new FormatConvertedBitmap(bs, PixelFormats.Bgra32, null, 0).CopyPixels(Bgra, Stride, 0);
}
// 将像素数据转换为灰度数据
int GrayStride = ((PixelWidth + 3) >> 2) << 2;
byte[] Gray = new byte[PixelHeight * GrayStride];
int Index = 0;
for (int i = 0; i < PixelHeight; i++)
{
int Base = i * GrayStride;
for (int j = 0; j < PixelWidth; j++)
{
Gray[Base++] = Convert.ToByte((Bgra[Index + 2] * 19595 + Bgra[Index + 1] * 38469 + Bgra[Index] * 7471 + 32768) >> 16);
Index += 4;
}
}
// 从灰度数据中创建灰度图像
return BitmapSource.Create(PixelWidth, PixelHeight, 96, 96, PixelFormats.Indexed8, BitmapPalettes.Gray256, Gray, GrayStride);
}
/// <summary>
/// 将 Bitmap 转化为 BitmapSource
/// </summary>
/// <param name="bmp"/>要转换的 Bitmap
/// <returns>转换后的 BitmapSource</returns>
public static BitmapSource ToBitmapSource(this System.Drawing.Bitmap bmp)
{
System.IntPtr hBmp = bmp.GetHbitmap();
try
{
return System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(hBmp, System.IntPtr.Zero, System.Windows.Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions());
}
finally
{
DeleteObject(hBmp);
}
}
/// <summary>
/// 将 Bitmap 转化为 BitmapSource
/// </summary>
/// <param name="bmp"/>要转换的 Bitmap
/// <returns>转换后的 BitmapImage</returns>
public static BitmapImage ToBitmapImage(this System.Drawing.Bitmap bmp)
{
System.IO.MemoryStream ms = new System.IO.MemoryStream();
bmp.Save(ms, ImageFormat.Bmp);
BitmapImage bi = new BitmapImage();
bi.BeginInit();
bi.StreamSource = ms;
bi.EndInit();
return bi;
}
/// <summary>
/// 将 BitmapSource 转化为 Bitmap
/// </summary>
/// <param name="bs">要转换的 BitmapSource</param>
/// <returns>转换后的位图图像</returns>
public static System.Drawing.Bitmap ToBitmap(this BitmapSource bs)
{
using (System.IO.MemoryStream ms = new System.IO.MemoryStream())
{
BitmapEncoder encoder = new BmpBitmapEncoder();
encoder.Frames.Add(BitmapFrame.Create(bs));
encoder.Save(ms);
return new System.Drawing.Bitmap(ms);
}
}
[DllImport("Gdi32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool DeleteObject(IntPtr hObject);
}
}