C#与Halcon交互-图像格式转换
自己保存,学习使用,可做参考。
// 定义共有类
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Drawing;
using System.Drawing.Imaging;
using HalconDotNet;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.IO;
using System.Drawing.Drawing2D;
namespace AlgorithmByHalcon
{
public class Utilities
{
[DllImport(“kernel32.dll”, EntryPoint = “RtlCopyMemory”, CharSet = CharSet.Ansi)]
public extern static long CopyMemory(IntPtr dest, IntPtr source, int size);
[DllImport("ntdll.dll")]
public static extern int memcpy(IntPtr dest, IntPtr source, int size);
public static bool m_bDebug = true;
// 彩色图像 Bitmap转 HObject
public static HObject BitmapToHObjectColor(Bitmap bmp)
{
HObject halcon_image = null;
HOperatorSet.GenEmptyObj(out halcon_image);
try
{
Rectangle rect = new Rectangle(0, 0, bmp.Width, bmp.Height);
BitmapData bmpData = bmp.LockBits(rect, ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);
HOperatorSet.GenImageInterleaved(out halcon_image, bmpData.Scan0, "bgr", bmp.Width, bmp.Height, -1,
"byte", bmp.Width, bmp.Height, 0, 0, -1, 0);
bmp.UnlockBits(bmpData);
}
catch (System.Exception exp)
{
Logger.Log(" 图像转换发生异常," + exp.ToString());
return null;
}
return halcon_image;
}
// 彩色图像由 HObject 转 Bitmap
public static Bitmap HObjectToBitmapColor(object obj)
{
if (obj == null)
{
Logger.Log(" 传入图像为空,请确保图像已经正确加载!");
return null;
}
HObject hObj = obj as HObject;
HOperatorSet.GetImageSize(hObj, out HTuple width, out HTuple height);
int w = 0;
double factor = 1.0;
const int scaleWidth = 4;
int mode = width % 4;
if (mode == 0)
{
w = width;
}
else
{
w = width + (scaleWidth - mode);
factor = (double)w / width;
}
HOperatorSet.ZoomImageSize(hObj, out HObject imgZoom, w, height * factor, "nearest_neighbor");
HOperatorSet.GetImagePointer3(imgZoom, out HTuple hptrRed, out HTuple hptrGreen, out HTuple hptrBlue,
out HTuple type, out HTuple imgWidth, out HTuple imgHeight);
//HOperatorSet.ClearObj(imgZoom);
Bitmap res = new Bitmap(imgWidth, imgHeight, PixelFormat.Format24bppRgb);
Rectangle rect = new Rectangle(0, 0, imgWidth, imgHeight);
BitmapData bitmapData = res.LockBits(rect, ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
unsafe
{
byte* bptr = (byte*)bitmapData.Scan0;
byte* r = ((byte*)hptrRed.IP.ToPointer());
byte* g = ((byte*)hptrGreen.IP.ToPointer());
byte* b = ((byte*)hptrBlue.IP.ToPointer());
// 此处数据长度需要以 Halcon 生成的图像的宽、高计算,否则转换后的图像会发生缺失
int length = imgWidth * imgHeight;
for (int i = 0; i < length; i++)
{
bptr[i * 3] = (b)[i];
bptr[i * 3 + 1] = (g)[i];
bptr[i * 3 + 2] = (r)[i];
}
}
res.UnlockBits(bitmapData);
var bmp = KiResizeImageColor(res, width, height, 0);
//if (res != null)
//{
// res.Dispose();
//}
return bmp;
}
// 灰度图像由 Bitmap转HObject
public static HObject BitmapToHObject(Bitmap src)
{
HObject hObj = null;
try
{
// src 为 null 由外部保证,此处不再作判断
if (src.PixelFormat != PixelFormat.Format8bppIndexed)
{
Logger.Log("只能处理灰度图像!");
return null;
}
Rectangle rect = new Rectangle(0, 0, src.Width, src.Height);
BitmapData srcData = src.LockBits(rect, ImageLockMode.ReadOnly, src.PixelFormat);
int length = srcData.Width * srcData.Height;
IntPtr srcBytes = Marshal.AllocHGlobal(sizeof(byte) * length);
for (int i = 0; i < length; ++i)
{
CopyMemory(srcBytes + i, srcData.Scan0 + i, 1);
}
HOperatorSet.GenImage1(out hObj, "byte", src.Width, src.Height, srcBytes);
// 释放内存
Marshal.FreeHGlobal(srcBytes);
src.UnlockBits(srcData);
}
catch (System.Exception ex)
{
Logger.Log(" 图像由 Bitmap 转 HObject 转换发生异常," + ex.ToString());
}
return hObj;
}
// 灰度图像由 HObject 转 Bitmap
public static Bitmap HObjectToBitmap(object obj)
{
HObject hObj = obj as HObject;
HOperatorSet.GetImageSize(hObj, out HTuple width, out HTuple height);
int w = 0;
double factor = 1.0;
const int scaleWidth = 4;
if (width % scaleWidth == 0)
{
w = width;
}
else
{
w = (width / scaleWidth + 1) * scaleWidth;
factor = (double)w / (double)width;
}
HOperatorSet.ZoomImageSize(hObj, out HObject imgZoom, w, height * factor, "nearest_neighbor");
HOperatorSet.GetImagePointer1(imgZoom, out HTuple hPoint, out HTuple type, out HTuple imgWidth,
out HTuple imgHeight);
var bmp = new Bitmap(imgWidth, imgHeight, PixelFormat.Format8bppIndexed);
ColorPalette palette = bmp.Palette;
for (int i = 0; i < 256; ++i)
{
palette.Entries[i] = Color.FromArgb(255, i, i, i);
}
bmp.Palette = palette;
Rectangle rect = new Rectangle(0, 0, imgWidth, imgHeight);
BitmapData bmpData = bmp.LockBits(rect, ImageLockMode.ReadWrite, PixelFormat.Format8bppIndexed);
int length = bmpData.Stride * bmp.Height;
CopyMemory(bmpData.Scan0, hPoint.IP, length);
bmp.UnlockBits(bmpData);
// 图像缩放后会变成 32 位
var res = KiResizeImageGray(bmp, width, height, 0);
return res;
}
public static Bitmap KiResizeImageColor(Bitmap bmp, int newW, int newH, int Mode)
{
try
{
Bitmap b = new Bitmap(newW, newH, PixelFormat.Format24bppRgb);
Graphics g = Graphics.FromImage(b);
// 插值算法的质量
g.InterpolationMode = InterpolationMode.HighQualityBicubic;
//g.InterpolationMode = InterpolationMode.Bilinear;
g.DrawImage(bmp, new Rectangle(0, 0, newW, newH), new Rectangle(0, 0, bmp.Width, bmp.Height),
GraphicsUnit.Pixel);
g.Dispose();
if (bmp != null)
{
bmp.Dispose();
}
return b;
}
catch
{
return null;
}
}
public static Bitmap KiResizeImageGray(Bitmap bmp, int newW, int newH, int Mode)
{
try
{
Bitmap b = new Bitmap(newW, newH, PixelFormat.Format24bppRgb);
Graphics g = Graphics.FromImage(b);
// 插值算法的质量
g.InterpolationMode = InterpolationMode.HighQualityBicubic;
g.DrawImage(bmp, new Rectangle(0, 0, newW, newH), new Rectangle(0, 0, bmp.Width, bmp.Height),
GraphicsUnit.Pixel);
g.Dispose();
return BitmapFactory.RgbToGrayscale(b);
}
catch
{
return null;
}
}
}
}