using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using VisionDesigner;
namespace MvvmScaffoldFrame48.DLL.ImageAlgorithm
{
public static class HikVisionAlgorithmRelated
{
///
/// Bitmap转MVDImage
///
///
///
///
public static void ConvertBitmap2MVDImage(Bitmap cBitmapImg, CMvdImage cMvdImg)
{
// 参数合法性判断
if (null == cBitmapImg || null == cMvdImg)
{
throw new MvdException(MVD_MODULE_TYPE.MVD_MODUL_APP, MVD_ERROR_CODE.MVD_E_PARAMETER_ILLEGAL);
}
// 判断像素格式
if (PixelFormat.Format8bppIndexed != cBitmapImg.PixelFormat && PixelFormat.Format24bppRgb != cBitmapImg.PixelFormat)
{
throw new MvdException(MVD_MODULE_TYPE.MVD_MODUL_APP, MVD_ERROR_CODE.MVD_E_SUPPORT);
}
Int32 nImageWidth = cBitmapImg.Width;
Int32 nImageHeight = cBitmapImg.Height;
Int32 nChannelNum = 0;
BitmapData bitmapData = null;
try
{
// 获取图像信息
if (PixelFormat.Format8bppIndexed == cBitmapImg.PixelFormat) // 灰度图
{
bitmapData = cBitmapImg.LockBits(new Rectangle(0, 0, nImageWidth, nImageHeight)
, ImageLockMode.ReadOnly
, PixelFormat.Format8bppIndexed);
cMvdImg.InitImage(Convert.ToUInt32(nImageWidth), Convert.ToUInt32(nImageHeight), MVD_PIXEL_FORMAT.MVD_PIXEL_MONO_08);
nChannelNum = 1;
}
else if (PixelFormat.Format24bppRgb == cBitmapImg.PixelFormat) // 彩色图
{
bitmapData = cBitmapImg.LockBits(new Rectangle(0, 0, nImageWidth, nImageHeight)
, ImageLockMode.ReadOnly
, PixelFormat.Format24bppRgb);
cMvdImg.InitImage(Convert.ToUInt32(nImageWidth), Convert.ToUInt32(nImageHeight), MVD_PIXEL_FORMAT.MVD_PIXEL_RGB_RGB24_C3);
nChannelNum = 3;
}
// 考虑图像是否4字节对齐,bitmap要求4字节对齐,而mvdimage不要求对齐
if (0 == nImageWidth % 4) // 4字节对齐时,直接拷贝
{
Marshal.Copy(bitmapData.Scan0, cMvdImg.GetImageData().stDataChannel[0].arrDataBytes, 0, nImageWidth * nImageHeight * nChannelNum);
}
else // 按步长逐行拷贝
{
// 每行实际占用字节数
Int32 nRowPixelByteNum = nImageWidth * nChannelNum + 4 - (nImageWidth * nChannelNum % 4);
// 每行首字节首地址
IntPtr bitmapDataRowPos = IntPtr.Zero;
for (int i = 0; i < nImageHeight; i++)
{
// 获取每行第一个像素值的首地址
bitmapDataRowPos = new IntPtr(bitmapData.Scan0.ToInt64() + nRowPixelByteNum * i);
Marshal.Copy(bitmapDataRowPos, cMvdImg.GetImageData().stDataChannel[0].arrDataBytes, i * nImageWidth * nChannelNum, nImageWidth * nChannelNum);
}
}
// bitmap彩色图按BGR存储,而MVDimg按RGB存储,改变存储顺序
// 交换R和B
if (PixelFormat.Format24bppRgb == cBitmapImg.PixelFormat)
{
byte bTemp;
byte[] bMvdImgData = cMvdImg.GetImageData().stDataChannel[0].arrDataBytes;
for (int i = 0; i < nImageWidth * nImageHeight; i++)
{
bTemp = bMvdImgData[3 * i];
bMvdImgData[3 * i] = bMvdImgData[3 * i + 2];
bMvdImgData[3 * i + 2] = bTemp;
}
}
}
finally
{
cBitmapImg.UnlockBits(bitmapData);
}
}
///
/// MVDImage转Bitmap
///
///
///
///
public static void ConvertMVDImage2Bitmap(CMvdImage cMvdImg, ref Bitmap cBitmapImg)
{
// 参数合法性判断
if (null == cMvdImg)
{
throw new MvdException(MVD_MODULE_TYPE.MVD_MODUL_APP, MVD_ERROR_CODE.MVD_E_PARAMETER_ILLEGAL);
}
// 判断像素格式
if (MVD_PIXEL_FORMAT.MVD_PIXEL_MONO_08 != cMvdImg.PixelFormat && MVD_PIXEL_FORMAT.MVD_PIXEL_RGB_RGB24_C3 != cMvdImg.PixelFormat)
{
throw new MvdException(MVD_MODULE_TYPE.MVD_MODUL_APP, MVD_ERROR_CODE.MVD_E_SUPPORT);
}
Int32 nImageWidth = Convert.ToInt32(cMvdImg.Width);
Int32 nImageHeight = Convert.ToInt32(cMvdImg.Height);
Int32 nChannelNum = 0;
BitmapData bitmapData = null;
byte[] bBitmapDataTemp = null;
try
{
// 获取图像信息
if (MVD_PIXEL_FORMAT.MVD_PIXEL_MONO_08 == cMvdImg.PixelFormat) // 灰度图
{
cBitmapImg = new Bitmap(nImageWidth, nImageHeight, PixelFormat.Format8bppIndexed);
// 灰度图需指定调色板
ColorPalette colorPalette = cBitmapImg.Palette;
for (int j = 0; j < 256; j++)
{
colorPalette.Entries[j] = Color.FromArgb(j, j, j);
}
cBitmapImg.Palette = colorPalette;
bitmapData = cBitmapImg.LockBits(new Rectangle(0, 0, nImageWidth, nImageHeight)
, ImageLockMode.WriteOnly
, PixelFormat.Format8bppIndexed);
// 灰度图不做深拷贝
bBitmapDataTemp = cMvdImg.GetImageData().stDataChannel[0].arrDataBytes;
nChannelNum = 1;
}
else if (MVD_PIXEL_FORMAT.MVD_PIXEL_RGB_RGB24_C3 == cMvdImg.PixelFormat) // 彩色图
{
cBitmapImg = new Bitmap(nImageWidth, nImageHeight, PixelFormat.Format24bppRgb);
bitmapData = cBitmapImg.LockBits(new Rectangle(0, 0, nImageWidth, nImageHeight)
, ImageLockMode.WriteOnly
, PixelFormat.Format24bppRgb);
// 彩色图做深拷贝
bBitmapDataTemp = new byte[cMvdImg.GetImageData().stDataChannel[0].nLen];
Array.Copy(cMvdImg.GetImageData().stDataChannel[0].arrDataBytes, bBitmapDataTemp, bBitmapDataTemp.Length);
nChannelNum = 3;
}
// bitmap彩色图按BGR存储,而MVDimg按RGB存储,改变存储顺序
// 交换R和B
if (MVD_PIXEL_FORMAT.MVD_PIXEL_RGB_RGB24_C3 == cMvdImg.PixelFormat)
{
byte bTemp;
for (int i = 0; i < nImageWidth * nImageHeight; i++)
{
bTemp = bBitmapDataTemp[3 * i];
bBitmapDataTemp[3 * i] = bBitmapDataTemp[3 * i + 2];
bBitmapDataTemp[3 * i + 2] = bTemp;
}
}
// 考虑图像是否4字节对齐,bitmap要求4字节对齐,而mvdimage不要求对齐
if (0 == nImageWidth % 4) // 4字节对齐时,直接拷贝
{
Marshal.Copy(bBitmapDataTemp, 0, bitmapData.Scan0, nImageWidth * nImageHeight * nChannelNum);
}
else // 按步长逐行拷贝
{
// 每行实际占用字节数
Int32 nRowPixelByteNum = nImageWidth * nChannelNum + 4 - (nImageWidth * nChannelNum % 4);
// 每行首字节首地址
IntPtr bitmapDataRowPos = IntPtr.Zero;
for (int i = 0; i < nImageHeight; i++)
{
// 获取每行第一个像素值的首地址
bitmapDataRowPos = new IntPtr(bitmapData.Scan0.ToInt64() + nRowPixelByteNum * i);
Marshal.Copy(bBitmapDataTemp, i * nImageWidth * nChannelNum, bitmapDataRowPos, nImageWidth * nChannelNum);
}
}
cBitmapImg.UnlockBits(bitmapData);
}
catch (MvdException ex)
{
if (null != cBitmapImg)
{
cBitmapImg.UnlockBits(bitmapData);
cBitmapImg.Dispose();
cBitmapImg = null;
}
throw ex;
}
catch (System.Exception ex)
{
if (null != cBitmapImg)
{
cBitmapImg.UnlockBits(bitmapData);
cBitmapImg.Dispose();
cBitmapImg = null;
}
throw ex;
}
}
///
/// 加载图片(从文件)
///
///
public static CMvdImage LoadImage(string LoadImagePath)
{
CMvdImage m_stInputImage = null;
try
{
if (!string.IsNullOrEmpty(LoadImagePath))
{
if (null == m_stInputImage)
{
m_stInputImage = new CMvdImage();
}
m_stInputImage.InitImage(LoadImagePath);
Console.WriteLine("Finish loading image from [" + LoadImagePath + "].");
}
}
catch (MvdException ex)
{
Console.WriteLine("Fail to load image from [" + LoadImagePath + "]. ErrorCode: 0x" + ex.ErrorCode.ToString("X"));
}
catch (Exception ex)
{
Console.WriteLine("Fail to load image from [" + LoadImagePath + "]. Error: " + ex.Message);
}
return m_stInputImage;
}
///
/// 加载图片(从Bitmap)
///
///
public static CMvdImage LoadImage(Bitmap bitmap)
{
CMvdImage m_stInputImage = null;
try
{
if (bitmap != null)
{
if (null == m_stInputImage)
{
m_stInputImage = new CMvdImage();
}
//m_stInputImage.InitImage(bitmap);
ConvertBitmap2MVDImage(bitmap, m_stInputImage);
Console.WriteLine("Finish loading image from [BitMap].");
}
}
catch (MvdException ex)
{
Console.WriteLine("Fail to load image from [BitMap]. ErrorCode: 0x" + ex.ErrorCode.ToString("X"));
}
catch (Exception ex)
{
Console.WriteLine("Fail to load image from [BitMap]. Error: " + ex.Message);
}
return m_stInputImage;
}
}
}