知道图像的首地址,高度,宽度,怎么保存灰度图片

danran251689 2019-06-28 10:48:36
RT,图像格式是8位灰度图片,现在知道它的首地址,高度,宽度。怎么获取它的灰度图像
...全文
277 6 打赏 收藏 转发到动态 举报
写回复
用AI写文章
6 条回复
切换为时间正序
请发表友善的回复…
发表回复
danran251689 2019-07-02
  • 打赏
  • 举报
回复
  byte[,] Data;//保存像素矩阵
            int width_ = 0;
            int heigth_ = 0;
            int chnum_ = 0;
            long buff_ = 0;
            int tool = axCKVisionCtrl1.GetTool("采集图像");
            buff_ = axCKVisionCtrl1.GetImageBuffer(tool, ref width_, ref heigth_, ref chnum_);
            Bitmap bmp = new Bitmap(width_,heigth_);
            // Lock the bitmap's bits.  
           BitmapData bmpData = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);
            this.Width = bmpData.Width;
            this.Height = bmpData.Height;
            Data = new byte[Height, Width];
            unsafe
            {
                byte* ptr = (byte*)buff_;
                for (int i = 0; i < Height; i++)
                {
                    for (int j = 0; j < Width; j++)
                    {
    //将24位的RGB彩色图转换为灰度图
                        int temp = (int)(0.114 * (*ptr++)) + (int)(0.587 * (*ptr++))+(int)(0.299 * (*ptr++));
                        Data[i, j] = (byte)temp;
                    }
                    ptr += bmpData.Stride - Width * 3;//指针加上填充的空白空间
                }
            }
               bmp.UnlockBits(bmpData);
                pictureBox1.Image = bmp;
我的代码如上所示,width_为获取到的宽度,height_为获取到的高度,buff_为获取到的图像首地址,现在运行到“ int temp = (int)(0.114 * (*ptr++)) + (int)(0.587 * (*ptr++))+(int)(0.299 * (*ptr++));”这句话就报错,提示““System.AccessViolationException”类型的未经处理的异常在 WindowsFormsApplication1.exe 中发生 其他信息: 尝试读取或写入受保护的内存。这通常指示其他内存已损坏。”
danran251689 2019-07-02
  • 打赏
  • 举报
回复
引用 4 楼 wanghui0380 的回复:
[quote=引用 3 楼 danran251689 的回复:] [quote=引用 1 楼 wanghui0380 的回复:] 算出byte[]大小就行,8位灰度表示1点1字节 byte[] buffer=new byte[宽*高] Marshal.Copy(首地址,buffer,0,buffer.length ); //我们不知道,这个首地址指的是什么,我假定这是非托管地址,所以使用 Marshal.Copy
能说得具体一点吗?[/quote] 具体不了了,我们不知道你具体使用环境。只能假定这是调用C++dll的结果。 这样可能对方返回给你了宽,高和一个地址 比如返回 inptr p,int 宽,int 高 。 8位灰度图像,就是一个字节(8bit)代表一个像素点,所以 宽*高 可以得有多少个像素,即有多少个字节。 Marshal.Copy 含义就是从内存中读取多少字节的数据给指定托管数组 有关这东西的解释看msdn把 https://docs.microsoft.com/zh-cn/dotnet/api/system.runtime.interopservices.marshal.copy?redirectedfrom=MSDN&view=netframework-4.8#overloads [/quote] 原来这张图片是通过其他控件显示的,现在我能获取到这张图片的首地址Scan0,宽度和高度还有格式(Format8bppIndexed)。现在想保存成8位深度的BMP格式的图片。
wanghui0380 2019-07-02
  • 打赏
  • 举报
回复
引用 3 楼 danran251689 的回复:
[quote=引用 1 楼 wanghui0380 的回复:] 算出byte[]大小就行,8位灰度表示1点1字节 byte[] buffer=new byte[宽*高] Marshal.Copy(首地址,buffer,0,buffer.length ); //我们不知道,这个首地址指的是什么,我假定这是非托管地址,所以使用 Marshal.Copy
能说得具体一点吗?[/quote] 具体不了了,我们不知道你具体使用环境。只能假定这是调用C++dll的结果。 这样可能对方返回给你了宽,高和一个地址 比如返回 inptr p,int 宽,int 高 。 8位灰度图像,就是一个字节(8bit)代表一个像素点,所以 宽*高 可以得有多少个像素,即有多少个字节。 Marshal.Copy 含义就是从内存中读取多少字节的数据给指定托管数组 有关这东西的解释看msdn把 https://docs.microsoft.com/zh-cn/dotnet/api/system.runtime.interopservices.marshal.copy?redirectedfrom=MSDN&view=netframework-4.8#overloads
danran251689 2019-07-01
  • 打赏
  • 举报
回复
引用 1 楼 wanghui0380 的回复:
算出byte[]大小就行,8位灰度表示1点1字节 byte[] buffer=new byte[宽*高] Marshal.Copy(首地址,buffer,0,buffer.length ); //我们不知道,这个首地址指的是什么,我假定这是非托管地址,所以使用 Marshal.Copy
能说得具体一点吗?
threenewbee 2019-06-28
  • 打赏
  • 举报
回复
byte[] arr = 你的数据.Skip(首地址).ToArray(); Image img = Image.FromStream(new MemoryStream(arr));
wanghui0380 2019-06-28
  • 打赏
  • 举报
回复
算出byte[]大小就行,8位灰度表示1点1字节 byte[] buffer=new byte[宽*高] Marshal.Copy(首地址,buffer,0,buffer.length ); //我们不知道,这个首地址指的是什么,我假定这是非托管地址,所以使用 Marshal.Copy

110,533

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧