一、目标
相机捕获的图像信息通常以数组的形式传输到计算机内存中,而且其大小与相机的分辨率相对应,这就会造成其数组非常大,上千万甚至上亿。而我们需要将这些数组转成Bitmap来显示或者做一些处理。那么如何用C#语言来快速高效对其进行转换?
二、使用PinnedObject类
这个类的作用:
1、保持对目标对象的引用并将其固定在内存中,确保其在内存中的位置不被垃圾回收器改变。
2、并使用AddrOfPinnedObject()方法获取当前固定对象的地址。
using System;
using System.Runtime.InteropServices;
namespace AIPRO.VisionStudio.Toolkit._3D.LJD.Common
{
public sealed class PinnedObject : IDisposable
{
#region Field
private GCHandle _handle; // Garbage collector handle
#endregion
#region Property
/// <summary>
/// Get the address.
/// </summary>
public IntPtr Pointer
{
// Get the leading address of the current object that is pinned.
get { return _handle.AddrOfPinnedObject(); }
}
#endregion
#region Constructor
/// <summary>
/// Constructor
/// </summary>
/// <param name="target">Target to protect from the garbage collector</param>
public PinnedObject(object target)
{
// Pin the target to protect it from the garbage collector.
_handle = GCHandle.Alloc(target, GCHandleType.Pinned);
}
#endregion
#region Interface
/// <summary>
/// Interface
/// </summary>
public void Dispose()
{
_handle.Free();
_handle = new GCHandle();
}
#endregion
}
}
三、使用PinnedObject做转换
3.1、Byte[]转8位灰度图
public static Bitmap ConvertByteArrayToBitmap(byte[] grayData, int width, int height)
{
// 参数验证
if (grayData == null)
{
throw new ArgumentNullException(nameof(grayData), "Input byte array cannot be null.");
}
if (width <= 0 || height <= 0)
{
throw new ArgumentOutOfRangeException("Width and height must be positive integers.");
}
if (grayData.Length != width * height)
{
throw new ArgumentException("The length of the byte array does not match the specified width and height.");
}
using (PinnedObject pin = new PinnedObject(grayData))
{
try
{
return new Bitmap(width, height, width, PixelFormat.Format8bppIndexed, pin.Pointer);
}
catch (Exception ex)
{
// 处理 Bitmap 创建时的异常
throw new InvalidOperationException("Failed to create bitmap from byte array.", ex);
}
}
}
3.2、ushot[]转16位彩色图
public static Bitmap ConvertUShortArrayToBitmap(ushort[] heightData, int width, int height)
{
// 参数验证
if (heightData == null)
{
throw new ArgumentNullException(nameof(heightData), "Input byte array cannot be null.");
}
if (width <= 0 || height <= 0)
{
throw new ArgumentOutOfRangeException("Width and height must be positive integers.");
}
if (heightData.Length != width * height)
{
throw new ArgumentException("The length of the byte array does not match the specified width and height.");
}
using (PinnedObject pin = new PinnedObject(heightData))
{
try
{
return new Bitmap(width, height, width * 2, PixelFormat.Format16bppArgb1555, pin.Pointer);
}
catch (Exception ex)
{
// 处理 Bitmap 创建时的异常
throw new InvalidOperationException("Failed to create bitmap from byte array.", ex);
}
}
}