加载中…
个人资料
  • 博客等级:
  • 博客积分:
  • 博客访问:
  • 关注人气:
  • 获赠金笔:0支
  • 赠出金笔:0支
  • 荣誉徽章:
正文 字体大小:

C#中Image类与byte[]之间的转换

(2014-08-31 21:06:44)
标签:

iplimage

image

bmp头文件格式

c与c

数据接口

分类: 编程小记
遇到此问题是因为在编程中提示用到C++与C#,需要将C++中的OpenCV库中的IplImage类与C#中Image类转换,以实现数据接口。
解决我的问题主要通过Image→byte[]→IplImage,反之亦然。
注:问题各部分解决方法来自网络

关于此问题的解决主要分为三部分:
1. Image→byte[]
2. byte[]→IplImage
3. bmp的文件头格式(连接上述两个问题需要知晓的结构)

1. Image→byte[]
此部分在C#平台中实现:
以下这段代码的意义在于将Image类直接转化为byte数组流
        //将image转化为二进制 
        public byte[] GetByteImage(Image img)
        {
            byte[] bt = null;
            if (!img.Equals(null))
            {
                using (MemoryStream mostream = new MemoryStream())
                {
                    Bitmap bmp = new Bitmap(img);
                    bmp.Save(mostream, System.Drawing.Imaging.ImageFormat.Bmp);//将图像以指定的格式存入缓存内存流
                    bt = new byte[mostream.Length];
                    mostream.Position = 0;//设置留的初始位置
                    mostream.Read(bt, 0, Convert.ToInt32(bt.Length));
                }
            }
            return bt;
        }

反之,将byte[]转化为Image类型数据:
        public static Image GetImageByBytes(byte[] bytes)
        {
            Image photo = null;
            using (MemoryStream ms = new MemoryStream(bytes))
            {
                ms.Write(bytes, 0, bytes.Length);
                photo = Image.FromStream(ms, true);
            }
            return photo;
        }

注意以上转换,byte[]数组数据均包含bmp头文件信息(关于此,会在第三部分中详述)。

2. byte[]→IplImage
此部分在C++平台中实现。

       OpenCVIplImage图像格式与byte[]的转换(注:在C++中没有byte类型,其等价于unsigned char

       IplImage* iplImage

       BYTE* data

       1) IplImage*得到BYTE*图像数据:

       data = iplImage->imageDataOrigin; //未对齐的原始图像数据

       或者

       data = iplImage->imageData; //已对齐的图像数据

       2) BYTE*得到IplImage*图像数据

       iplImage = cvCreateImageHeader(cvSize(width,height),depth,channels);

       cvSetData(iplImage,data,step);

       首先由cvCreateImageHeader()创建IplImage图像头,制定图像的尺寸,深度和通道数;然后由cvSetData()根据 BYTE*图像数据指针设置IplImage图像头的数据数据,其中step指定该IplImage图像每行占的字节数,对于1通道的 IPL_DEPTH_8U图像,step可以等于width



3. bmp的文件头格式

       下面我们来看看位图文件(*.BMP)的格式。

位图文件主要分为如下3个部分:

块名称

对应Windows结构体定义

大小(Byte

文件信息头

BITMAPFILEHEADER

14

位图信息头

BITMAPINFOHEADER

40

RGB颜色阵列

BYTE*

由图像长宽尺寸决定

 

1) 文件信息头BITMAPFILEHEADER

结构体定义如下:

typedef struct tagBITMAPFILEHEADER {

       UINT bfType;  
       DWORD bfSize; 
       UINT bfReserved1; 
       UINT bfReserved2; 
       DWORD bfOffBits;

} BITMAPFILEHEADER;

       其中:

bfType

说明文件的类型,该值必需是0x4D42,也就是字符'BM'

bfSize

说明该位图文件的大小,用字节为单位

bfReserved1

保留,必须设置为0

bfReserved2

保留,必须设置为0

bfOffBits

说明从文件头开始到实际的图象数据之间的字节的偏移量。这个参数是非常有用的,因为位图信息头和调色板的长度会根据不同情况而变化,所以你可以用这个偏移值迅速的从文件中读取到位数据。

 

2) 位图信息头BITMAPINFOHEADER

结构体定义如下:

typedef struct tagBITMAPINFOHEADER {

DWORD biSize; 
LONG biWidth; 
LONG biHeight; 
WORD biPlanes; 
WORD biBitCount; 
DWORD biCompression; 
DWORD biSizeImage; 
LONG biXPelsPerMeter; 
LONG biYPelsPerMeter; 
DWORD biClrUsed; 
DWORD biClrImportant;

} BITMAPINFOHEADER;

其中:

biSize

说明BITMAPINFOHEADER结构所需要的字数。

biWidth

说明图象的宽度,以象素为单位。

biHeight

说明图象的高度,以象素为单位。注:这个值除了用于描述图像的高度之外,它还有另一个用处,就是指明该图像是倒向的位图,还是正向的位图。如果该值是一个正数,说明图像是倒向的,如果该值是一个负数,则说明图像是正向的。大多数的BMP文件都是倒向的位图,也就是时,高度值是一个正数。

biPlanes

为目标设备说明位面数,其值将总是被设为1

biBitCount

说明比特数/象素,其值为1481624、或32。但是由于我们平时用到的图像绝大部分是24位和32位的,所以我们讨论这两类图像。

biCompression

说明图象数据压缩的类型,同样我们只讨论没有压缩的类型:BI_RGB

biSizeImage

说明图象的大小,以字节为单位。当用BI_RGB格式时,可设置为0

biXPelsPerMeter

说明水平分辨率,用象素/米表示。

biYPelsPerMeter

说明垂直分辨率,用象素/米表示。

biClrUsed

说明位图实际使用的彩色表中的颜色索引数(设为0的话,则说明使用所有调色板项)。

biClrImportant

说明对图象显示有重要影响的颜色索引的数目,如果是0,表示都重要。

3) RGB颜色阵列

有关RGB三色空间我想大家都很熟悉,这里我想说的是在Windows下,RGB颜色阵列存储的格式其实BGR。也就是说,对于24位的RGB位图像素数据格式是:

蓝色B

绿色G

红色R

对于32位的RGB位图像素数据格式是:

蓝色B

绿色G

红色R

透明通道A

 

透明通道也称Alpha通道,该值是该像素点的透明属性,取值在0(全透明)到255(不透明)之间。对于24位的图像来说,因为没有Alpha通道,故整个图像都不透明。

0

阅读 收藏 喜欢 打印举报/Report
  

新浪BLOG意见反馈留言板 欢迎批评指正

新浪简介 | About Sina | 广告服务 | 联系我们 | 招聘信息 | 网站律师 | SINA English | 产品答疑

新浪公司 版权所有