开启左侧

C# bitmap 与 HObject 互转,包括彩图和灰度图

[复制链接]
王耀辉 发表于 2020-10-28 09:36:08 | 显示全部楼层 |阅读模式
本文代码部分来此其他网站的copy,但是我在使用过程中,发现存在以下两个问题:
1.hobject 灰度图转bitmap 灰度图方法,在X64平台上报错。
2. 原版代码HObject2Bpp32 这个方法,我在方法内用 Graphics 类把Format32bppArgb 重画为Format24bppRgb,但是在连续调用用此方法时,会报内存错误。

上述两个问题,我在网上搜索了很久,都找不到解决方案。
之后我仔细研究研究转换原理,最后在原有代码基础上改造成功。

文中只贴出了bitmap 转Hobject代码(包括灰度图和彩图),附档中包含Hobject 转bitmap(包括灰度图和彩图),此部分有本人自创内容,完整代码请下载附档查看。

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Threading.Tasks;
  6. using System.Drawing;
  7. using HalconDotNet;
  8. using System.IO;
  9. using System.Drawing.Imaging;
  10. using System.Runtime.InteropServices;   // 必须要有
  11. using System.Diagnostics;

  12. public class bmp_halcon
  13.     {
  14.         [DllImport("kernel32.dll")]
  15.         public static extern void CopyMemory(int Destination, int add, int Length);
  16.        //彩色图转换
  17.         public void Bitmap2HObjectBpp24(Bitmap bmp, out HObject image)
  18.         {
  19.             try
  20.             {
  21.                 Rectangle rect = new Rectangle(0, 0, bmp.Width, bmp.Height);

  22.                 BitmapData srcBmpData = bmp.LockBits(rect, ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);
  23.                 HOperatorSet.GenImageInterleaved(out image, srcBmpData.Scan0, "bgr", bmp.Width, bmp.Height, 0, "byte", 0, 0, 0, 0, -1, 0);
  24.                 bmp.UnlockBits(srcBmpData);

  25.             }
  26.             catch (Exception ex)
  27.             {
  28.                 image = null;
  29.             }
  30.         }
  31.         //灰度图转换
  32.         public void Bitmap2HObjectBpp8(Bitmap bmp, out HObject image)
  33.         {
  34.             try
  35.             {
  36.                 Rectangle rect = new Rectangle(0, 0, bmp.Width, bmp.Height);

  37.                 BitmapData srcBmpData = bmp.LockBits(rect, ImageLockMode.ReadOnly, PixelFormat.Format8bppIndexed);

  38.                 HOperatorSet.GenImage1(out image, "byte", bmp.Width, bmp.Height, srcBmpData.Scan0);
  39.                 bmp.UnlockBits(srcBmpData);
  40.             }
  41.             catch (Exception ex)
  42.             {
  43.                 image = null;
  44.             }
  45.         }
  46.         // 32位平台可用,附档内有可用于64位平台可用的方法
  47.         public void HObject2Bpp8(HObject image, out Bitmap res)
  48.         {
  49.             HTuple hpoint, type, width, height;

  50.             const int Alpha = 255;
  51.             int[] ptr = new int[2];
  52.            //.....................................

  53.         }
  54.    // old way
  55.      public void HObject2Bpp32(HObject image, out Bitmap res)
  56.         {
  57.             HTuple hred, hgreen, hblue, type, width, height;

  58.            //.........................................................

  59.         }
  60.     // halcon 17 之后的版本可用,速度比上个方法(HObject2Bpp32 )快很多
  61.     public void HObject2Bpp24(HObject ho_image, out Bitmap res24)
  62.         {


  63.             HTuple width0, height0, type, width, height;
  64.             //获取图像尺寸
  65.             HOperatorSet.GetImageSize(ho_image, out width0, out height0);

  66.            //..........................................................
  67.         }

  68.         }
复制代码

bitmapt2hobject.pdf (175.52 KB, 下载次数: 12, 售价: 10 视觉币)
Ken1024 发表于 2020-10-28 13:48:44 | 显示全部楼层
请问你这个确定可以用吗?
 楼主| 王耀辉 发表于 2020-10-28 18:51:20 | 显示全部楼层
Ken1024 发表于 2020-10-28 13:48
请问你这个确定可以用吗?

亲测可以
virtual 发表于 2022-7-9 14:12:22 | 显示全部楼层
亲测没卵用, 可以转,但转成右边这什么鬼样, 24位图都懒得试了。。代码贴出来了


laji.JPG


// 经本人改造,X64 平台可用。bitmap 灰度图 转Hobject 灰度图
public void HObject2Bpp8(HObject image, out Bitmap res)
{
HTuple hpoint, type, width, height;
const int Alpha = 255;
HOperatorSet.GetImagePointer1(image, out hpoint, out type, out width, out height);
res = new Bitmap(width, height, PixelFormat.Format8bppIndexed);
ColorPalette pal = res.Palette;
for (int i = 0; i <= 255; i++)
{
pal.Entries = Color.FromArgb(Alpha, i, i, i);
}
res.Palette = pal;
Rectangle rect = new Rectangle(0, 0, width, height);
BitmapData bitmapData = res.LockBits(rect, ImageLockMode.WriteOnly,
PixelFormat.Format8bppIndexed);
int PixelSize = Bitmap.GetPixelFormatSize(bitmapData.PixelFormat) / 8;
IntPtr ptr1 = bitmapData.Scan0;
IntPtr ptr2 = hpoint;
int bytes = width * height;
byte[] rgbvalues = new byte[bytes];
System.Runtime.InteropServices.Marshal.Copy(ptr2, rgbvalues, 0, bytes);
System.Runtime.InteropServices.Marshal.Copy(rgbvalues, 0, ptr1, bytes);
//***********************************
//unsafe
//{
// byte* ptr1 = (byte*)bitmapData.Scan0;
// byte* ptr2 = ((byte*)hpoint.I);
// for (int i = 0; i< width * height; i++)
// {
// ptr1 = ptr2;
// }
//}
//***************************************
res.UnlockBits(bitmapData);
}

Criss 发表于 2022-7-9 14:26:11 | 显示全部楼层
virtual 发表于 2022-7-9 14:12
亲测没卵用, 可以转,但转成右边这什么鬼样, 24位图都懒得试了。。代码贴出来了

感觉没有字节对齐!
您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表