坐看云起2024 2024年5月13日 18:56
///
/// 复制此对象到参数目标对象中
///
/// 要将此图像复制到的目标图像。
/// 该方法将当前非托管映像复制到指定的映像。目标图像的大小和像素格式必须完全相同。
public void Copy(Image dest)
{
if ((_width != dest._width) || (_height != dest._height) || (_pixelFormat != dest._pixelFormat))
{
throw new Exception("目标图像具有与此对象不同的大小或像素格式。");
}
if (_stride == dest._stride)
{
// 复制图像
SystemTools.CopyUnmanagedMemory(dest._imageData, _imageData, _stride * _height);
}
else
{
unsafe
{
int dstStride = dest._stride;
int copyLength = (_stride < dstStride) ? _stride : dstStride;
byte* src = (byte*)_imageData.ToPointer();
byte* dst = (byte*)dest._imageData.ToPointer();
// 复制行
for (int i = 0; i < _height; i++)
{
SystemTools.CopyUnmanagedMemory(dst, src, copyLength);
dst += dstStride;
src += _stride;
}
}
}
}
///
/// 在非托管内存中分配新图片。
///
/// 图像宽度
/// 图像高度
/// 图像像素格式.
/// 在非托管内存中分配具有指定宽高的新图片
public static Image Create(int width, int height, PixelFormat pixelFormat)
{
int bytesPerPixel = 0;
// 计算每像素的字节数
switch (pixelFormat)
{
case PixelFormat.Format8bppIndexed:
bytesPerPixel = 1;
break;
case PixelFormat.Format16bppGrayScale:
bytesPerPixel = 2;
break;
case PixelFormat.Format24bppRgb:
bytesPerPixel = 3;
break;
case PixelFormat.Format32bppRgb:
case PixelFormat.Format32bppArgb:
case PixelFormat.Format32bppPArgb:
bytesPerPixel = 4;
break;
case PixelFormat.Format48bppRgb:
bytesPerPixel = 6;
break;
case PixelFormat.Format64bppArgb:
case PixelFormat.Format64bppPArgb:
bytesPerPixel = 8;
break;
default:
throw new Exception("只读的像素格式无效");
}
// 检查图像大小
if ((width <= 0) || (height <= 0))
{
throw new Exception("指定的图像大小无效。");
}
// 计算跨辐
int stride = width * bytesPerPixel;
if (stride % 4 != 0)
{
stride += (4 - (stride % 4));
}
// 为图片分配内存
IntPtr imageData = Marshal.AllocHGlobal(stride * height);
SystemTools.SetUnmanagedMemory(imageData, 0, stride * height);
GC.AddMemoryPressure(stride * height);
var image = new Image(imageData, width, height, stride, pixelFormat);
image._mustBeDisposed = true;
return image;
}
///
/// 从指定的托管图像创建非托管映像。
///
/// 源托管图像
/// 返回新的非托管映像,该映像是源托管映像的副本。
/// 该方法创建指定托管映像的精确副本,已在非托管内存中分配。
public static Image FromImage(Bitmap image)
{
Image dst = null;
BitmapData sData = image.LockBits(new Rectangle(0, 0, image.Width, image.Height),
ImageLockMode.ReadOnly, image.PixelFormat);
try
{
dst = FromImage(sData);
}
finally
{
image.UnlockBits(sData);
}
return dst;
}