C#联合halcon实现图像转换(Bitmap(8,24,32通道) 转 HImage)
前言
发布原因
(1)网络备份一下C#联合Halcon 开发的代码,方便以后使用。
(2)在C#联合halcon中Bitmap转换Halcon图像时常用的代码,如果Bitmap是32位的转换成HImage时显示图像倾斜的。网上搜了好多都无用,后来找到了要将GenImageInterleaved方法的第二个参数“bgr” 改成“bgrx”。
(3)获取图像正确格式的方法,是因为有时候直接改图像后缀名,读取图像时与图像后缀不符报错,目前暂时使用读取图像文件的二进制头部图像格式标识来判断。
///<summary>
/// Bitmap转HImage(32位4通道)
/// </summary>
public static void BitmapToHImageBpp32(Bitmap bmp, out HImage image, PixelFormat pixelFormat)
{
try
{
image = new HImage();
Rectangle rect = new Rectangle(0, 0, bmp.Width, bmp.Height);
BitmapData srcBmpData = bmp.LockBits(rect, ImageLockMode.ReadOnly, pixelFormat);
image.GenImageInterleaved(srcBmpData.Scan0, "rgbx", bmp.Width, bmp.Height, 0, "byte", bmp.Width, bmp.Height, 0, 0, -1, 0);
bmp.UnlockBits(srcBmpData);
}
catch (Exception ex)
{
image = null;
}
}
备份代码
public class ImageFormatTools
{
public class ImageFormatTools
{
#region 判断图像的正确格式
/// <summary>
/// 图像格式工具:获取正确的图像格式,通过图像文件的二进制头部图像格式标识。
/// </summary>
public static ImageFormat GetImageFormat(string filePath)
{
using (FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read))
{
using (BinaryReader br = new BinaryReader(fs))
{
// 读取文件的前几个字节
byte[] headerBytes = br.ReadBytes(16);
// 根据文件的前几个字节判断图像的实际格式
if (IsJpeg(headerBytes))
{
return ImageFormat.Jpeg;
}
else if (IsPng(headerBytes))
{
return ImageFormat.Png;
}
else if (IsGif(headerBytes))
{
return ImageFormat.Gif;
}
else if (IsBmp(headerBytes))
{
return ImageFormat.Bmp;
}
else
{
// 默认返回未知格式
return null;
}
}
}
}
private static bool IsJpeg(byte[] headerBytes)
{
// JPEG 文件的前两个字节是 0xFF, 0xD8
return headerBytes.Length >= 2 && headerBytes[0] == 0xFF && headerBytes[1] == 0xD8;
}
private static bool IsPng(byte[] headerBytes)
{
// PNG 文件的前八个字节是固定的签名:137 80 78 71 13 10 26 10
return headerBytes.Length >= 8 && headerBytes[0] == 137
&& headerBytes[1] == 80 && headerBytes[2] == 78
&& headerBytes[3] == 71 && headerBytes[4] == 13
&& headerBytes[5] == 10 && headerBytes[6] == 26
&& headerBytes[7] == 10;
}
private static bool IsGif(byte[] headerBytes)
{
// GIF 文件的前三个字节是 "GIF"
return headerBytes.Length >= 3 && headerBytes[0] == 71
&& headerBytes[1] == 73 && headerBytes[2] == 70;
}
private static bool IsBmp(byte[] headerBytes)
{
// BMP 文件的前两个字节是 "BM"
return headerBytes.Length >= 2 && headerBytes[0] == 66
&& headerBytes[1] == 77;
}
#endregion
/// <summary>
/// 获取图像通道数、图像类型
/// </summary>
public static int GetImageChannelCount(string imagePath ,out Bitmap bitmap,out PixelFormat format)
{
try
{
Image image = Image.FromFile(imagePath);
//bitmap = new Bitmap(imagePath);
bitmap = new Bitmap(image);
// 获取图像的PixelFormat
format = bitmap.PixelFormat;
image.Dispose();
// 根据PixelFormat判断通道数
switch (format)
{
case PixelFormat.Format8bppIndexed: // 灰度图
return 1;
case PixelFormat.Format24bppRgb: // RGB图
return 3;
case PixelFormat.Format32bppRgb: //
case PixelFormat.Format32bppArgb: // RGBA图 RGB + Alpha
return 4;
default:
return -1;
}
}
catch (Exception ex)
{
throw new ArgumentException($"参数异常:{ex.Message}");
}
}
/// <summary>
/// 读取图像,并返回读取信息:输入图像路径,返回HImage图像(8,24,32位(1,3,4通道))
/// </summary>
public static void ReadImage(string path,out HImage hImage,out string info)
{
hImage = new HImage();
Random random = new Random();
info = null;
int channel = GetImageChannelCount(path, out Bitmap bitmap, out PixelFormat format);
switch (format)
{
case PixelFormat.Format8bppIndexed:
try
{
hImage.ReadImage(path);
}
catch (Exception ex)
{
BitmapToHImageBpp8(bitmap, out hImage);
info= ex.Message;
}
break;
case PixelFormat.Format24bppRgb:
try
{
hImage.ReadImage(path);
}
catch (Exception ex)
{
BitmapToHImageBpp24(bitmap, out hImage);
info = ex.Message;
}
break;
case PixelFormat.Format32bppRgb:
case PixelFormat.Format32bppArgb:
try
{
hImage.ReadImage(path);
}
catch (Exception ex)
{
BitmapToHImageBpp32(bitmap, out hImage, format);
info = ex.Message;
}
break;
default:
try
{
hImage.ReadImage(path);
}
catch (Exception ex)
{
BitmapToHImageBpp8(bitmap, out hImage);
info = ex.Message;
}
break;
}
}
///<summary>
/// Bitmap转HImage(24位3通道)
/// </summary>
public static void BitmapToHImageBpp24(Bitmap bmp, out HImage image)
{
try
{
HObject tempImage = new HObject();
Rectangle rect = new Rectangle(0, 0, bmp.Width, bmp.Height);
BitmapData srcBmpData = bmp.LockBits(rect, ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);
//image.GenImageInterleaved(srcBmpData.Scan0, "rgb", bmp.Width, bmp.Height, 0, "byte", bmp.Width, bmp.Height, 0, 0, -1, 0);
HOperatorSet.GenImageInterleaved(out tempImage, srcBmpData.Scan0, "bgr", bmp.Width, bmp.Height, 0, "byte", 0, 0, 0, 0, -1, 0);
bmp.UnlockBits(srcBmpData);
image = (HImage)tempImage.Clone();
}
catch (Exception ex)
{
image = null;
}
}
///<summary>
/// Bitmap转HImage(32位4通道)
/// </summary>
public static void BitmapToHImageBpp32(Bitmap bmp, out HImage image, PixelFormat pixelFormat,int channel)
{
try
{
image = new HImage();
Rectangle rect = new Rectangle(0, 0, bmp.Width, bmp.Height);
BitmapData srcBmpData = bmp.LockBits(rect, ImageLockMode.ReadOnly, pixelFormat);
image.GenImageInterleaved(srcBmpData.Scan0, "rgbx", bmp.Width, bmp.Height, 0, "byte", bmp.Width, bmp.Height, 0, 0, -1, 0);
bmp.UnlockBits(srcBmpData);
}
catch (Exception ex)
{
image = null;
}
}
/// <summary>
/// Bitmap转HImage(8位单通道)
/// </summary>
public static void BitmapToHImageBpp8(Bitmap bmp,out HImage image)
{
try
{
image = new HImage();
Rectangle rect = new Rectangle(0, 0, bmp.Width, bmp.Height);
BitmapData srcBmpData = bmp.LockBits(rect, ImageLockMode.ReadOnly, PixelFormat.Format8bppIndexed);
image.GenImage1("byte", bmp.Width, bmp.Height, srcBmpData.Scan0);
bmp.UnlockBits(srcBmpData);
}
catch (Exception ex)
{
image = null;
}
}
/// <summary>
/// Bitmap 转HObject(24位彩色3通道)
/// </summary>
public static void BitmapToHObjectBpp24(Bitmap bmp ,out HObject image)
{
try
{
image = new HObject();
Rectangle rect = new Rectangle(0, 0, bmp.Width, bmp.Height);
BitmapData srcBmpData = bmp.LockBits(rect, ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);
HOperatorSet.GenImageInterleaved(out image, srcBmpData.Scan0, "bgr", bmp.Width, bmp.Height, 0, "byte", 0, 0, 0, 0, -1, 0);
bmp.UnlockBits(srcBmpData);
}
catch (Exception ex)
{
image = null;
}
}
}
public static int GetImageChannelCount(string imagePath ,out Bitmap bitmap,out PixelFormat format)
{
try
{
Image image = Image.FromFile(imagePath);
//bitmap = new Bitmap(imagePath);
bitmap = new Bitmap(image);
// 获取图像的PixelFormat
format = bitmap.PixelFormat;
image.Dispose();
// 根据PixelFormat判断通道数
switch (format)
{
case PixelFormat.Format8bppIndexed: // 灰度图
return 1;
case PixelFormat.Format24bppRgb: // RGB图
return 3;
case PixelFormat.Format32bppRgb: //
case PixelFormat.Format32bppArgb: // RGBA图 RGB + Alpha
return 4;
default:
return -1;
}
}
catch (Exception ex)
{
throw new ArgumentException($"参数异常:{ex.Message}");
}
}
///<summary>
/// Bitmap转HImage(24位3通道)
/// </summary>
public static void BitmapToHImageBpp24(Bitmap bmp, out HImage image)
{
try
{
HObject tempImage = new HObject();
Rectangle rect = new Rectangle(0, 0, bmp.Width, bmp.Height);
BitmapData srcBmpData = bmp.LockBits(rect, ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);
//image.GenImageInterleaved(srcBmpData.Scan0, "rgb", bmp.Width, bmp.Height, 0, "byte", bmp.Width, bmp.Height, 0, 0, -1, 0);
HOperatorSet.GenImageInterleaved(out tempImage, srcBmpData.Scan0, "bgr", bmp.Width, bmp.Height, 0, "byte", 0, 0, 0, 0, -1, 0);
bmp.UnlockBits(srcBmpData);
image = (HImage)tempImage.Clone();
}
catch (Exception ex)
{
image = null;
}
}
///<summary>
/// Bitmap转HImage(32位4通道)
/// </summary>
public static void BitmapToHImageBpp32(Bitmap bmp, out HImage image, PixelFormat pixelFormat)
{
try
{
image = new HImage();
Rectangle rect = new Rectangle(0, 0, bmp.Width, bmp.Height);
BitmapData srcBmpData = bmp.LockBits(rect, ImageLockMode.ReadOnly, pixelFormat);
image.GenImageInterleaved(srcBmpData.Scan0, "rgbx", bmp.Width, bmp.Height, 0, "byte", bmp.Width, bmp.Height, 0, 0, -1, 0);
bmp.UnlockBits(srcBmpData);
}
catch (Exception ex)
{
image = null;
}
}
/// <summary>
/// Bitmap转HImage(8位单通道)
/// </summary>
public static void BitmapToHImageBpp8(Bitmap bmp,out HImage image)
{
try
{
image = new HImage();
Rectangle rect = new Rectangle(0, 0, bmp.Width, bmp.Height);
BitmapData srcBmpData = bmp.LockBits(rect, ImageLockMode.ReadOnly, PixelFormat.Format8bppIndexed);
image.GenImage1("byte", bmp.Width, bmp.Height, srcBmpData.Scan0);
bmp.UnlockBits(srcBmpData);
}
catch (Exception ex)
{
image = null;
}
}
/// <summary>
/// Bitmap 转HObject(24位彩色3通道)
/// </summary>
public static void BitmapToHObjectBpp24(Bitmap bmp ,out HObject image)
{
try
{
image = new HObject();
Rectangle rect = new Rectangle(0, 0, bmp.Width, bmp.Height);
BitmapData srcBmpData = bmp.LockBits(rect, ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);
HOperatorSet.GenImageInterleaved(out image, srcBmpData.Scan0, "bgr", bmp.Width, bmp.Height, 0, "byte", 0, 0, 0, 0, -1, 0);
bmp.UnlockBits(srcBmpData);
}
catch (Exception ex)
{
image = null;
}
}
}