搜档网
当前位置:搜档网 › CvArr、Mat、CvMat、IplImage、BYTE转换K

CvArr、Mat、CvMat、IplImage、BYTE转换K

CvArr、Mat、CvMat、IplImage、BYTE转换K
CvArr、Mat、CvMat、IplImage、BYTE转换K

CvArr、Mat、CvMat、IplImage、BYTE转换(总结而来)

分类:OpenCv 2012-02-29 14:165388人阅读评论(2)收藏举报byte优化图像处理数据结构matrixvector

一、Mat类型:矩阵类型,Matrix。

在openCV中,Mat是一个多维的密集数据数组。可以用来处理向量和矩阵、图像、直方图等等常见的多维数据。

Mat有3个重要的方法:

1、Mat mat = imread(const String* filename); 读取图像

2、imshow(const string frameName, InputArray mat); 显示图像

3、imwrite (const string& filename, InputArray img); 储存图像

Mat类型较CvMat与IplImage类型来说,有更强的矩阵运算能力,支持常见的矩阵运算。在计算密集型的应用当中,将CvMat与IplImage类型转化为Mat类型将大大减少计算时间花费。

A.Mat -> IplImage

同样只是创建图像头,而没有复制数据。

例:// 假设Mat类型的imgMat图像数据存在

IplImage pImg= IplImage(imgMat);

B.Mat -> CvMat

与IplImage的转换类似,不复制数据,只创建矩阵头。

例:// 假设Mat类型的imgMat图像数据存在

CvMat cvMat = imgMat;

二、CvMat类型与IplImage类型:“图像”类型

在openCV中,Mat类型与CvMat和IplImage类型都可以代表和显示图像,但是,Mat类型侧重于计算,数学性较高,openCV对Mat类型的计算也进行了优化。而CvMat 和IplImage类型更侧重于“图像”,openCV对其中的图像操作(缩放、单通道提取、图像阈值操作等)进行了优化。

补充:IplImage由CvMat派生,而CvMat由CvArr派生即CvArr -> CvMat -> IplImage CvArr用作函数的参数,无论传入的是CvMat或IplImage,内部都是按CvMat 处理。

1.CvMat

A.CvMat-> IplImage

IplImage* img = cvCreateImage(cvGetSize(mat),8,1);

cvGetImage(matI,img);

cvSaveImage("rice1.bmp",img);

B.CvMat->Mat

与IplImage的转换类似,可以选择是否复制数据。

Mat::Mat(const CvMat* m, bool copyData=false);

在openCV中,没有向量(vector)的数据结构。任何时候,但我们要表示向量时,用矩阵数据表示即可。

但是,CvMat类型与我们在线性代数课程上学的向量概念相比,更抽象,比如CvMat的元

素数据类型并不仅限于基础数据类型,比如,下面创建一个二维数据矩阵:

CvMat* cvCreatMat(int rows ,int cols , int type);

这里的type可以是任意的预定义数据类型,比如RGB或者别的多通道数据。这样我们便可以在一个CvMat矩阵上表示丰富多彩的图像了。

2.IplImage

在类型关系上,我们可以说IplImage类型继承自CvMat类型,当然还包括其他的变量将之解析成图像数据。

IplImage类型较之CvMat多了很多参数,比如depth和nChannels。在普通的矩阵类型当中,通常深度和通道数被同时表示,如用32位表示RGB+Alpha.但是,在图像处理中,我们往往将深度与通道数分开处理,这样做是OpenCV对图像表示的一种优化方案。IplImage的对图像的另一种优化是变量origin----原点。在计算机视觉处理上,一个重要的不便是对原点的定义不清楚,图像来源,编码格式,甚至操作系统都会对原地的选取产生影响。为了弥补这一点,openCV允许用户定义自己的原点设置。取值0表示原点位于图片左上角,1表示左下角。

dataOrder参数定义数据的格式。有IPL_DATA_ORDER_PIXEL和

IPL_DATA_ORDER_PLANE两种取值,前者便是对于像素,不同的通道的数据交叉排列,后者表示所有通道按顺序平行排列。

IplImage类型的所有额外变量都是对“图像”的表示与计算能力的优化。

A.IplImage -> Mat

IplImage* pImg = cvLoadImage("lena.jpg");

Mat img(pImg,0); // 0是不複製影像,也就是pImg與img的data共用同個記憶體位置,header各自有

B.IplImage -> CvMat

法1:CvMat mathdr, *mat = cvGetMat( img, &mathdr );

法2:CvMat *mat = cvCreateMat( img->height, img->width, CV_64FC3 );

cvConvert( img, mat );

C.IplImage*-> BYTE*

BYTE* data= img->imageData;

CvMat和IplImage创建时的一个小区别:

1、建立矩阵时,第一个参数为行数,第二个参数为列数。

CvMat* cvCreateMat( int rows, int cols, int type );

2、建立图像时,CvSize第一个参数为宽度,即列数;第二个参数为高度,即行数。这个和CvMat矩阵正好相反。

IplImage* cvCreateImage(CvSize size, int depth, int channels );

CvSize cvSize( int width, int height );

IplImage内部buffer每行是按4字节对齐的,CvMat没有这个限制

补充:

A.BYTE*-> IplImage*

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

cvSetData(img,data,step);

//首先由cvCreateImageHeader()创建IplImage图像头,制定图像的尺寸,深度和通道数;

//然后由cvSetData()根据BYTE*图像数据指针设置IplImage图像头的数据数据,

//其中step指定该IplImage图像每行占的字节数,对于1通道的IPL_DEPTH_8U图像,step 可以等于width。

IplImage*图像结构指针转换成byte *

最近在封装opencv中一些标定,视觉方面的函数,接口定义为byte*,需要将byte*与iplImage*相互转换。

其中遇到几个小问题,1)当byte*转成IplImage*时setData()接受图像头,故需要createImageHeader().在上篇cvSetData()中已经说明。

2)在IplImage*转成Byte*时,其实就是取IplImage*中的imageData数据区指针,但是要注意几点:

A:IplImage*指针存放图像有两种方式,由originar变量控制,0-left up为起点,1-left down 为起点。所以要根据origial 处理图像情况。看是否需要对图像进行倒置下。

B:IplImage*存放图像根据读人的格式不同,channel不同。即便是8位图像可能存放成3个通道,所以在转化时获取数据需要注意。

代码贴出来:

//////////////////////////////////////////////////////////////////////////

// Name: byte2IplImg

// Function: convert byte* to IplImage format.

// Author: liyy

// Data:2011.05.23

//////////////////////////////////////////////////////////////////////////

IplImage * CconvertImgStruct::Byte2IplImg( byte *pImg,int width,int height,int bitCount ) {

if (!pImg )

{

return NULL;

}

IplImage * pIplImg = cvCreateImage(cvSize(width,height),IPL_DEPTH_8U,bitCount/BITCHAN) ;

long lWidthByte = (width * bitCount+31)/32 *4;

cvSetData(pIplImg,pImg,lWidthByte);

return pIplImg;

}

//////////////////////////////////////////////////////////////////////////

//Name: IplImage2Byte

//Function: convert IplImage to byte*

//Author:liyy

//Date: 2011.05.23

//////////////////////////////////////////////////////////////////////////

byte * CconvertImgStruct::IplImage2Byte( IplImage *IplImg )

{

if (!IplImg)

{

return NULL;

}

int nHeight = IplImg->height;

int nWidth =IplImg->width;

int bitCount = IplImg->depth;

int nChanel = IplImg->nChannels;

byte *pImg = new byte[nHeight*nWidth*nChanel*sizeof(byte)];

if (IplImg->origin == 0)

{ //from left-down

for (int i = 0; i< nHeight;i++)

{

for (int j = 0; j< nWidth;j++)

{

for (int k =0; k < nChanel;k++)

{

//*(pImg+i*nWidth+j*nChanel+k) = *(IplImg->imageData+(nHeight-i-1)*nWidth+j*nChanel+k);

pImg[i*nWidth*nChanel+j*nChanel+k] = IplImg->imageData[(nHeight-i-1)*nWidth*nChanel+j*nChanel+k];

}

}

}

}

else

{ //from left-up

memcpy(pImg,IplImg->imageData,nHeight*nWidth*nChanel*sizeof(byte));

}

//pImg = (byte *)IplImg->imageData;

return pImg;

}

}

//////////////////////////////////////////////////////////////////////////

//Name: IplImage2Byte

//Function: convert IplImage to byte*

//Author:liyy

//Date: 2011.05.23

//////////////////////////////////////////////////////////////////////////

byte * CconvertImgStruct::IplImage2Byte( IplImage *IplImg )

{

if (!IplImg)

{

return NULL;

}

int nHeight = IplImg->height;

int nWidth =IplImg->width;

int bitCount = IplImg->depth;

int nChanel = IplImg->nChannels;

byte *pImg = new byte[nHeight*nWidth*nChanel*sizeof(byte)];

if (IplImg->origin == 0)

{ //from left-down

for (int i = 0; i< nHeight;i++)

{

for (int j = 0; j< nWidth;j++)

{

for (int k =0; k < nChanel;k++)

{

//*(pImg+i*nWidth+j*nChanel+k) = *(IplImg->imageData+(nHeight-i-1)*nWidth+j*nChanel+k);

pImg[i*nWidth*nChanel+j*nChanel+k] = IplImg->imageData[(nHeight-i-1)*nWidth*nChanel+j*nChanel+k];

}

}

}

}

else

{ //from left-up

memcpy(pImg,IplImg->imageData,nHeight*nWidth*nChanel*sizeof(byte));

}

//pImg = (byte *)IplImg->imageData;

return pImg;

}

OpenCV中IplImage图像格式与BYTE图像数据的转换

分类:oencv 2011-04-27 22:33540人阅读评论(1)收藏举报转自

https://www.sodocs.net/doc/a18266129.html,/xiaofengsheng/archive/2009/11/16/4814709.aspx OpenCV中IplImage图像格式与BYTE图像数据的转换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。

1,如果是从新创造一个Iplimage,则用IplImage*

cvCreateImage( CvSize size, int depth, int

channels ),它创建头并分配数据。

注:当不再使用这个新图像时,要调用void

cvReleaseImage( IplImage** image )将它的头和图像数

据释放!

2,如果有图像数据没有为图像头分配存储空间(即,没有为IplImage* 指针分配动态存储空间),则

先调用IplImage* cvCreateImageHeader( CvSize size, int depth, int channels )创建图像头,再

调用void cvSetData( CvArr* arr, void* data, int step )指定图像数据,可以理解为将这个新图

像的数据指针指向了一个已存在的图像数据上,不存在图像数据存储空间的分配操作。

注:当不再使用这个新图像时,要调用void cvReleaseImageHeader( IplImage** image )将它的图像

头释放!

3,如果有图像数据也有图像头(用于IplImage为静态分配存储空间的情况),则先调用IplImage*

cvInitImageHeader( CvSize size, int depth, int channels )更改图像头,

再调用void

cvSetData( CvArr* arr, void* data, int step )指定图像数据。

注:因为这个新图像使用的是其它图像的数据和已有的图像头,所以不能使用cvReleaseImage将它的

头和图像数据释放,也不能使用cvReleaseData将它的图像数据释放!

4,如果从已有的一个图像创建,则用IplImage* cvCloneImage( const IplImage* image ),它制作

图像的完整拷贝包括头、ROI和数据。

注:当不再使用这个新图像时,要调用void

cvReleaseImage( IplImage** image )将它的头和图像数

据释放!

图像分割:

概念:

图像分割是将图像划分成若干个互不相交的小区域的过程,所谓小区域是某种意义下具有共同属性的像素的连通集合。

从集合的观点看:它应该是具有如下性质的一种点集,集合R代表整个区域,对R的分割可看作将R分成N个满足以下五个条件的非空子集R1,R2,…,RN:

目的:

无论是图像处理、分析、理解与识别,其基础工作一般都建立在图像分割的基础上;

将图像中有意义的特征或者应用所需要的特征信息提取出来;

图像分割的最终结果是将图像分解成一些具有某种特征的单元,称为图像的基元;

相对于整幅图像来说,这种图像基元更容易被快速处理。

图像分割的特征:

分割出来的各区域对某种性质例如灰度,纹理而言具有相似性,区域内部是连通的的且没有过多小孔。

区域边界是明确的

相邻区域对分割所依据的性质有明显的差异

图像分割的方法:

一、基于像素灰度值的分割方法:阈值(门限)方法

二、基于区域的分割方法:通过直接确定区域间的边界来实现分割的边界方法;

三、基于边缘的分割技术:首先检测边缘像素,再将边缘像素连接起来构成边界形成分割。

图像分割包含的内容:

边缘检测

边缘跟踪:

从图像中一个边缘点出发,然后根据某种判别准则搜索下一个边缘点以此跟踪出目标边界。

阈值分割:

原始图像——f(x,y)

灰度阈值——T

阈值运算得二值图像——g(x,y)

区域分割:

阈值分割法由于没有或很少考虑空间关系,使多阈值选择受到限制于区域的分割方法可以弥补这点不足,它利用的是图像的空间性质,该方法认为分割

出来的属于同一区域的像素应具有相似的性质,其概念是相当直观的。

传统的区域分割算法有区域增长法和区域分裂合并法。该类方法在没有先验知识可以利用时,对含有复杂场景

或自然景物等先验知识不足的图像进行分割, 也可以取得较好的性能。但是,空间和时间开销都比较大。

区域生长法主要考虑象素及其空间邻域象素之间的关系

开始时确定一个或多个象素点作为种子,然后按某种相似性准则增

长区域,逐步生成具有某种均匀性的空间区域,将相邻的具有相似性质的象素或区域归并从而逐步增长区域,直至没有可以归并的点或其它小区域为止。

区域内象素的相似性度量可以包括平均灰度值、纹理、颜色等信息。

主要步骤:

选择合适的种子点

确定相似性准则(生长准则)

确定生长停止条件

区域分裂:

条件:如果区域的某些特性不满足一致性准则

开始:从图像的最大区域开始,一般情况下,是从整幅图像开始

注意:

确定分裂准则(一致性准则)

确定分裂方法,即如何分裂区域,使得分裂后的子区域的特性尽可能都满足一致性准则值

图像分割的基本原理:

图像分割是将图像划分成若干个互不相交的小区域的过程,小区域是某种意义下具有共同属性的像素的连通集合。

?如不同目标物体所占的图像区域、前景所占的图像区域等;

?连通是指集合中任意两个点之间都存在着完全属于该集合的连通路径;

?对于离散图像而言,连通有4连通和8连通之分。

图像分割有三种不同的途径:

1.是将各像素划归到相应物体或区域的像素聚类方法, 即区域法;

2.是通过直接确定区域间的边界来实现分割的边界方法;

3.是首先检测边缘像素,再将边缘像素连接起来构成边界形成分割。

在图像分割技术中,最常用的是利用阈值化处理进行的图像分割。

在图像的阈值化处理过程中,选用不同的阈值其处理结果差异很大;

阈值过大,会提取多余的部分;

阈值过小,又会丢失所需的部分;

因此,阈值的选取非常重要。

边缘检测和图像分割的联系:

边缘检测后的图像是二值图像,对二值图像可以运用形态学操作来分割目标,

所以边缘检测是图像分割的一个前提。但分割不一定非要用边缘检测。

==================================

图像特征:

?图像特征是指图像中可用作标志的属性,它可以分为统计特征和视觉特征两类。

?图像的统计特征是指一些人为定义的特征,通过变换才能得到,如图像的直方图、

矩、频谱等;

?图像的视觉特征是指人的视觉可直接感受到的自然特征,如区域的亮度、纹理或轮廓等

轮廓提取:

二值图像轮廓提取的算法非常简单,就是掏空内部点:如果原图像中有一点为黑,且它

的8个邻点都是黑色时,说明该点是内部点,将该点删除(置为白色像素值255)。对

图像中所有像素点执行该操作便可完成图像轮廓的提取。

模板匹配:

模板匹配是指用一个较小的图像,即模板与源图像进行比较,以确定在源图像中是否

存在与该模板相同或相似的区域,若该区域存在,还可确定其位置并提取该区域。

形状匹配:

形状也是描述图像内容的一个重要特征,利用形状进行匹配需要考虑三个问题。

首先,形状常与目标联系在一起,所以相对于颜色,形状特征可以看作是更高层次的

图像特征。要获得有关目标的形状参数,常常要先对图像进行分割,所以形状特征会

受图像分割效果的影响。其次,目标形状的描述是一个非常复杂的问题,至今还没有

找到能与人的感觉相一致的图像形状的确切数学定义。最后,从不同视角获取的图像中

目标形状可能会有很大差别,为准确进行形状匹配,需要解决平移、尺度、旋转变换

不变性的问题。

标的形状常常可以用目标的轮廓来表示,而轮廓是由一系列边界点所组成的。一般认为,

在较大尺度下常常能较可靠地消除误检并检测到真正的边界点,但在大尺度下对边界的

定位不易准确。相反,在较小尺度下对真正边界点的定位常比较准确,但在小尺度下

误检的比例会增加。所以,可考虑先在较大尺度下检测出真正的边界点,再在较小尺度

下对真正边界点进行较精确的定位。小波变换和分析作为一种多尺度、多通道分析工具,

比较适合对图像进行多尺度的边界检测。

图片与字节数组相互转换的方法

图片与字节数组相互转换的方法 图片与字节数组相互转换的方法 aspx.cs   using System;using System.IO; using System.Drawing; using System.Drawing.Imaging;public partial class _2Stream : System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e) {}protected void FileToStream(object sender, EventArgs e) { //将JPG图片转化成字节数组 Image image = Image.FromFile("E:/1.jpg"); //或者使用Server.MapPath MemoryStream ms =

new MemoryStream(); image.Save(ms, ImageFormat.Jpeg); ms.Flush(); ms.Seek(0, SeekOrigin.Begin); byte[] buffer = new byte[ms.Length]; ms.Read(buffer, 0, (int)ms.Length);//遍历字节数组 for (int i = 0; i < buffer.LongLength; i++) { message.Text += buffer[i].ToString(); }//将字节数组转化成图像文件(自定义格式)并保存MemoryStream ms2 = new MemoryStream(buffer, 0, buffer.Length); ms2.Seek(0, SeekOrigin.Begin); Image image2 = Image.FromStream(ms2); image2.Save("E:\\2.gif", ImageFormat.Gif);

java整型数与网络字节序的 byte[] 数组转换关系

java整型数与网络字节序的byte[] 数组转换关系 工作项目需要在java和c/c++之间进行socket通信,socket通信是以字节流或者字节包进行的,socket发送方须将数据转换为字节流或者字节包,而接收方则将字节流和字节包再转换回相应的数据类型。如果发送方和接收方都是同种语言,则一般只涉及到字节序的调整。而对于java和c/c++的通信,则情况就要复杂一些,主要是因为java中没有unsigned类型,并且java和c在某些数据类型上的长度不一致。 本文就是针对这种情况,整理了java数据类型和网络字节流或字节包(相当于java的byte 数组)之间转换方法。实际上网上这方面的资料不少,但往往不全,甚至有些有错误,于是就花了点时间对java整型数和网络字节序的byte[]之间转换的各种情况做了一些验证和整理。整理出来的函数如下: public class ByteConvert { // 以下是整型数和网络字节序的byte[] 数组之间的转换 public static byte[] longToBytes(long n) { byte[] b = new byte[8]; b[7] = (byte) (n & 0xff); b[6] = (byte) (n >> 8 & 0xff); b[5] = (byte) (n >> 16 & 0xff); b[4] = (byte) (n >> 24 & 0xff); b[3] = (byte) (n >> 32 & 0xff); b[2] = (byte) (n >> 40 & 0xff); b[1] = (byte) (n >> 48 & 0xff); b[0] = (byte) (n >> 56 & 0xff); return b; } public static void longT oBytes( long n, byte[] array, int offset ){ array[7+offset] = (byte) (n & 0xff); array[6+offset] = (byte) (n >> 8 & 0xff); array[5+offset] = (byte) (n >> 16 & 0xff); array[4+offset] = (byte) (n >> 24 & 0xff); array[3+offset] = (byte) (n >> 32 & 0xff); array[2+offset] = (byte) (n >> 40 & 0xff); array[1+offset] = (byte) (n >> 48 & 0xff); array[0+offset] = (byte) (n >> 56 & 0xff); } public static long bytesToLong( byte[] array ) { return ((((long) array[ 0] & 0xff) << 56) | (((long) array[ 1] & 0xff) << 48)

15-Excel中日期格式转换问题

Excel中日期格式转换问题 1.数字格式转年月日格式 工作表中出生年月日格式格式是如:198707141987090620090902如果想改成1987-7-14或改成1987年7月14日。 1、就用此函数插入一列如B列,B1=(LEFT(A1,4)&"-"&MID(A1,5,2)&"-"&RIGHT(A1,2));其它单元格可以用此公式自动填充,然后把此单元格设置成日期1987-7-14; 2、插入一列如B列,B1=(LEFT(A1,4)&"年"&MID(A1,5,2)&"月"&RIGHT(A1,2)&"日");其它单元格可以用此公式自动填充,然后把此单元格设置成日期1987年7月14日。 把这种格式2009.9.2转换成2009-09-02这样的格式:假如原始数据在A列从A1开始,则在B1输入公式=TEXT(SUBSTITUTE(A1,".","-"),"yyyy-mm-dd"),然后下拉复制公式即可。 2.在Excel中将非日期格式数据转换为日期格式 如果Excel表格中有大量的类似“19841006”、“19841029”非日期格式的数据要转换为日期格式,如“1984-10-6”,可以用分列的方法: 1).选择需要转换单元格或区域,单击菜单“数据→分列”,弹出“文本分列向导-3之步骤1”对话框。如果是Excel2007,则在功能区中选择“数据”选项卡,在“数据工具”组中,单击“分列”按钮。

2).单击两次“下一步”,在“文本分列向导-3之步骤3”中,在“列数据格式”中选择“日期”。还可以根据需要,在其后的下拉列表中选择一种日期格式。本例为默认的“YMD”格式。 3).单击“完成”按钮,Excel会在原单元格或区域中将数值格式的“19841006”和文本格式的“1984.10.6”转换为日期格式“1984-10-6”。 另外,对于“1984.10.6”文本格式的数据,还可以将“.”替换为“-”,也可以转换为日期格式。 3.将日期格式转换为数字格式 在日期后插入一列取函数=text(a1,"yyyymmddhhmm")yyyy表示年mm表示月dd表示日hh表示时mm表示分a1表示日期位置(第一行第一列),然后向下拖曳填充即可改变其他各行日期 4.Excel文本日期转换为日期格式 什么是序列号? Excel可将日期存储为可用于计算的序列号。默认情况下,1900年1月1日的序列号为1,2008年1月1日的序列号为39,448,这是因为它距1900年1月1日有39,448天。 2、若要将转换公式复制到相邻单元格的区域中,请选择在其中键入公式的单元格,然后拖动填充柄,使之覆盖大小与包含文本日期的单元格区域匹配的空单元格区域。 拖动填充柄之后,应有序列号与包含文本日期的单元格区域相对应的单元格区域。

C#数组、字节数组、转换等

C#数组、字节数组、转换等 在System名称空间里面有许多跟Array操作相关的类。其中System.Array 类里面就提供了以下常用的方法: BinarySearch: 使用二进制搜索算法在一维的排序Array中搜索值。 Copy: 将一个Array的一部分元素复制到另一个Array中,并根据需要执行类型强制转换和装箱。 CopyTo: 将当前一维Array的所有元素复制到指定的一维Array中。 Resize: 将数组的大小更改为指定的新大小。 Sort: 对一维Array对象中的元素进行排序。 与大多数类不同,Array提供CreateInstance方法,以便允许后期绑定访问,而不是提供公共构造函数。 Array.Copy方法不仅可在同一类型的数组之间复制元素,而且可在不同类型的标准数组之间复制元素;它会自动处理强制类型转换。有些方法,如CreateInstance、Copy、CopyTo、GetValue和SetValue,提供重载(接受64位整数作为参数),以适应大容量数组。LongLength和GetLongLength返回指示数组长度的64位整数。在执行需要对Array进行排序的操作(如BinarySearch)之前,必须对Array进行排序。

ArrayList跟Array不同,前者是集合对象,ArrayList的ToArray方法可以直接将ArrayList里面的全部元素导出到一个数组里,而不需用循环逐个元素地复制到一个数组。 ToArray的使用方法如下: ArrayList ay = new ArrayList(); ay.Add("sheep"); ay.Add("cat"); ay.Add("dog"); string[] al= (string[])ay.ToArray(typeof(string)); Console.WriteLine(al[0]); 关键的地方在于ToArray的参数,这里应该用反射中的typeof获取arraylist 里面元素的原始数据类型。 在数组中有一种比较特殊的: 字节数组,即byte[]。内存、文件中的数据都是以字节数组的形式储存的,如果程序需要对数据进行操作的话,或多或少都会使用到byte[]。 对于byte[]跟其他类型的相互转换问题,在C++中,使用Memorycopy函数即可完成,虽然在C#里面也有类似MemoryCopy的函数: Buffer.BlockCopy,但由于强类型的特性,在C#里它并实现不了字节数组跟其他类型转换的功能。 为了解决这个问题,需要手工写将其他类型的数据通过位运算和逻辑运算而得到字节数组。如下面的代码: //整型转换为字节数组 int i = ; //对应的十六进制是:0012D687

Excel中如何将日期格式进行转换

在EXCEL中如何将日期格式转换 如何将格式转换成1900-01-01的格式? 如果日期所在单元格在A列,并从A1开始。 1、插入一辅助列B列, 2、在B1输入:=MID(A1,1,4)&-MID(A1,5,2)&-MID(A1,7,2)回车, 3、向下填充该公式。 4、选中B列→复制→粘贴→选择性粘贴→数值→确定 5、删除A列 在EXCEL中如何利用身份证号码提取出生时间 假设身份证号在A1,时间格式为1900-1-1 =IF(LEN(A1)=15,"19"&MID(A1,7,2)&"-"&MID(A1,9,2)&"-"&MID(A1,11,2),MID(A1,7,4)&"-"&MID(A1 ,11,2)&"-"&MID(A1,13,2)) 在EXCEL中如何利用身份证号码提取性别 =IF(LEN(A1)=15,IF(MOD(MID(A1,15,1),2)=1,"男","女") , IF(MOD(MID(A1,17,1),2)=1,"男","女") ) 在EXCEL中如何利用身份证号码计算周岁 假设身份证号在C1,时间格式为1900-1-1,出生时间为X 答案1: =DATEDIF(IF(LEN(A1)=15,"19"&MID(A1,7,2)&"-"&MID(A1,9,2)&"-"&MID(A1,11,2),MID(A1,7,4)&"-" &MID(A1,11,2)&"-"&MID(A1,13,2)),TODAY(),”y”) 简化之:=DATEDIF(X,TODAY(),”y”) 答案2: =TEXT(TODAY()-IF(LEN(C1)=15,"19"&MID(C1,7,2)&"-"&MID(C1,9,2)&"-"&MID(C1,11,2),MID(C1,7,4) &"-"&MID(C1,11,2)&"-"&MID(C1,13,2 )),"yy") 简化之:=TEXT(TODAY()-X,”yy”) 在EXCEL中如何利用身份证号码计算周岁 假设身份证号在C1: =IF(C1="","",IF(IF(LEN(C1)=15,"19"&MID(C1,7,2)&"-"&MID(C1,9,2)&"-"&MID(C1,11,2),MID(C1,7,4) &"-"&MID(C1,11,2)&"-"&MID(C1,13,2))>"2009-12-31","",TEXT(TODAY()-IF(LEN(C1)=15,"19"&MID( C1,7,2)&"-"&MID(C1,9,2)&"-"&MID(C1,11,2),MID(C1,7,4)&"-"&MID(C1,11,2)&"-"&MID(C1,13,2))," yy")))

byte数组转化成16进制字符串用法分析

byte数组转化成16进制字符串,C#中的overload,overwrite,override的区别 C++ 实现Single Sever Simulation AFNetworking 更改请求时间iOS chrome插件,二维码自动生成,C编程方式进行控制台输入 maven jar shade assembly配置[XML] Maven pom.xml public: double angle; QPen ang_info_pen; }; #endif [文件] MainWindow.cpp ~ 28KB [文件] MainWindow.h ~ 3KB //AngularJS 绑定鼠标左键、右键单击事件 //API权限设计总结系统sign验证规则 //Apriopri算法的简单实现 #ifndef __MAINWINDOW_H__ #define __MAINWINDOW_H__ #include "ui_MainWindow.h" #include "Shape.h" #include class CDockWin; class CDrawWin:public QMainWindow, public Ui_Mainwin { Q_OBJECT public: CDrawWin(QWidget *parent = NULL); // 画图状态定义 enum DRAW_STATUS{ // 无画图状态 DRAW_STATUS_NONE = 0, // 绘画当中 DRAW_STATUS_DRAWING, // 移动 DRAW_STATUS_DRAG, // 改变图元 DRAW_STATUS_CHANGE }; // 当前的菜单选择 enum MENU_STATUS{

Excel中日期格式转换问题

Excel中日期格式转换问题 1.数字格式转年月日格式 工作表中出生年月日格式格式是如:19870714 19870906 20090902如果想改成1987-7-14或改成1987年7月14日。 1、就用此函数插入一列如B列, B1=(LEFT(A1,4)&"-"&MID(A1,5,2)&"-"&RIGHT(A1,2)); 其它单元格可以用此公式自动填充,然后把此单元格设置成日期1987-7-14 ; 2、插入一列如B列,B1=(LEFT(A1,4)&"年"&MID(A1,5,2)&"月"&RIGHT(A1,2)&"日"); 其它单元格可以用此公式自动填充,然后把此单元格设置成日期1987年7月14 日。 把这种格式2009.9.2转换成2009-09-02这样的格式:假如原始数据在A列从 A1开始,则在B1输入公式=TEXT(SUBSTITUTE(A1,".","-"),"yyyy-mm-dd"),然后下拉复制公式即可。 2.在Excel中将非日期格式数据转换为日期格式 如果Excel表格中有大量的类似“19841006”、“19841029”非日期格式的数据要转换为日期格式,如“1984-10-6”,可以用分列的方法: 1).选择需要转换单元格或区域,单击菜单“数据→分列”,弹出“文本分列向导- 3之步骤1”对话框。如果是Excel 2007,则在功能区中选择“数据”选项卡,在“数据工具”组中,单击“分列”按钮。 2).单击两次“下一步”,在“文本分列向导- 3之步骤3”中,在“列数据格式”中选择“日期”。还可以根据需要,在其后的下拉列表中选择一种日期格式。本例为默认的“YMD”格式。 3).单击“完成”按钮,Excel会在原单元格或区域中将数值格式的“19841006”和文本格式的“1984.10.6”转换为日期格式“1984-10-6”。 另外,对于“1984.10.6”文本格式的数据,还可以将“.”替换为“-”,也可以转换为日期格式。 3.将日期格式转换为数字格式 在日期后插入一列取函数 =text(a1,"yyyymmddhhmm") yyyy表示年mm表示月dd表示日hh表示时mm表示分 a1表示日期位置(第一行第一列),然后向下拖曳填充即可改变其他各行日期 4.Excel文本日期转换为日期格式

字符串和字符数组之间的转换

字符串和字符数组之间的转换 2010-11-02 16:53:00| 分类: |举报|字号订阅 字符串类提供了一个void ToCharArray() 方法,该方法可以实现字符串到字符数组的转换。如下例: private void TestStringChars() { string str = "mytest"; char[] chars = (); = ""; "Length of \"mytest\" is " + + "\n"); "Length of char array is " + + "\n"); "char[2] = " + chars[2] + "\n"); } 例中以对转换转换到的字符数组长度和它的一个元素进行了测试,结果如下: Length of "mytest" is 6 Length of char array is 6 char[2] = t 可以看出,结果完全正确,这说明转换成功。那么反过来,要把字符数组转换成字符串又该如何呢? 我们可以使用类的构造函数来解决这个问题。类有两个构造函数是通过字符数组来构造的,即 String(char[]) 和String[char[], int, int)。后者之所以多两个参数,是因为可以指定用字符数组中的哪一部分来构造字符串。而前者则是用字符数组的全部元素来构造字符串。我们以前者为例, 在 TestStringChars() 函数中输入如下语句: char[] tcs = {'t', 'e', 's', 't', ' ', 'm', 'e'}; string tstr = new String(tcs); "tstr = \"" + tstr + "\"\n"); 运行结果输入 tstr = "test me",测试说明转换成功。 实际上,我们在很多时候需要把字符串转换成字符数组只是为了得到该字符串中的某个字符。如果只是为了这个目的,那大可不必兴师动众的去进行转换,我们

Excel中 的日期格式转换问题

Excel中日期格式转换问题 工作表中出生年月格式格式是如:19870705 19861106 19881109如果想改成1987-7-5或改成1987年7月7日。1、就用此函数插入一列如B列,B1=(LEFT(A1,4)&"-"&MID(A1,5,2)&"-"&RIGHT(A1,2))+0 其它单元格可以用此公式自动填充。然后把此单元格设置成日期2001-3-14 ;2、插入一列如B列 B1=(LEFT(A1,4)&"年"&MID(A1,5,2)&"月"&RIGHT(A1,2)&"日")+0 其它单元格可以用此公式自动填充。然后把此单元格设置成日期2001年3月14 日。 把这种格式2009.2.22转换成2009-02这样的格式:假如原始数据在A列从A1开始,则在B1输入公式=TEXT(SUBSTITUTE(A1,".","-"),"yyyy-mm"),然后下拉复制公式即可。 在Excel中将非日期格式数据转换为日期格式 如果Excel表格中有大量的类似“20090510”、“2009.5.10”非日期格式的数据要转换为日期格式,如“2009-5-10”,可以用分列的方法: 1.选择需要转换单元格或区域,单击菜单“数据→分列”,弹出“文本分列向导- 3之步骤1”对话框。如果是Excel 2007,则在功能区中选择“数据”选项卡,在“数据工具”组中,单击“分列”按钮。 2.单击两次“下一步”,在“文本分列向导- 3之步骤3”中,在“列数据格式”中选择“日期”。还可以根据需要,在其后的下拉列表中选择一种日期格式。本例为默认的“YMD”格式。 3.单击“完成”按钮,Excel会在原单元格或区域中将数值格式的“20090510”和文本格式的 “2009.5.10”转换为日期格式“2009-5-10”。 另外,对于“2009.5.10”文本格式的数据,还可以将“.”替换为“-”,也可以转换为日期格式。 在EXCEL中如何利用身份证号码计算出生年月年龄及性别 1、身份证号码简介(18位): 1~6位为地区代码;7~10位为出生年份;11~12位为出生月份;13~14位为出生日期;15~17位为顺序号,并能够判断性别,奇数为男,偶数为男;第18位为校验码。 2、确定“出生日期”: 18位身份证号码中的生日是从第7位开始至第14位结束。提取出来后为了计算“年龄”应该将“年”“月”“日”数据中添加一个“/”或“-”分隔符。 ①正确输入了身份证号码。(假设在D2单元格中) ②将光标定位在“出生日期”单元格(E2)中,然后在单元格中输入函数公式 “=MID(D2,7,4)&"-"&MID(D2,11,2)&"-"&MID(D2,13,2)”即可计算出“出生日期”。

inputStream和String,Byte之间的转换

1.import java.io.ByteArrayInputStream; 2.import java.io.ByteArrayOutputStream; 3.import java.io.IOException; 4.import java.io.InputStream; 5. 6./** 7. * 8. * @author Andy.Chen 9. * @mail Chenjunjun.ZJ@https://www.sodocs.net/doc/a18266129.html, 10. * 11. */ 12.public class InputStreamUtils { 13. 14. final static int BUFFER_SIZE = 4096; 15. 16. /** 17. * 将InputStream转换成String 18. * @param in InputStream 19. * @return String 20. * @throws Exception 21. * 22. */ 23. public static String InputStreamTOString(InputStream in) throws Ex ception{ 24. 25. ByteArrayOutputStream outStream = new ByteArrayOutputStream(); 26. byte[] data = new byte[BUFFER_SIZE]; 27. int count = -1; 28. while((count = in.read(data,0,BUFFER_SIZE)) != -1) 29. outStream.write(data, 0, count); 30. 31.data = null; 32. return new String(outStream.toByteArray(),"ISO-8859-1"); 33. } 34. 35. /** 36. * 将InputStream转换成某种字符编码的String 37. * @param in 38. * @param encoding 39. * @return 40. * @throws Exception 41. */

short,int,long与byte数组之间的转换

1. 2.package com.test; 3. 4.import java.nio.ByteBuffer; 5. 6.public class ByteUtil { 7. 8./** 9. * @param args 10. */ 11. public static void main(String[] args) { 12. test2(); 13. } 14. public static void test2() 15. { 16. short s = -20; 17. byte[] b = new byte[2]; 18. putReverseBytesShort(b, s, 0); 19. ByteBuffer buf = ByteBuffer.allocate(2); 20. buf.put(b); 21. buf.flip(); 22. System.out.println(getReverseBytesShort(b, 0)); 23. System.out.println(Short.reverseBytes(buf.getShort())); 24. System.out.println("***************************"); 25. int i = -40; 26. b = new byte[4]; 27. putReverseBytesInt(b, i, 0); 28. buf = ByteBuffer.allocate(4); 29. buf.put(b); 30. buf.flip(); 31. System.out.println(getReverseBytesInt(b, 0)); 32. System.out.println(Integer.reverseBytes(buf.getInt())); 33. System.out.println("***************************"); 34. long l = -50; 35. b = new byte[8]; 36. putReverseBytesLong(b, l, 0); 37. buf = ByteBuffer.allocate(8); 38. buf.put(b); 39. buf.flip(); 40. System.out.println(getReverseBytesLong(b, 0)); 41. System.out.println(Long.reverseBytes(buf.getLong())); 42. System.out.println("***************************"); 43. } 44. public static void test1()

JAVA二进制字节数组字符十六进制BCD编码转换

JAVA二进制字节数组字符十六进制BCD编码转换; import java.io.*; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; public class DataConverter { /* 把16进制字符串转换成字节数组 * @param hex * @return */ public static byte[] hexStringToByte(String hex) { int len = (hex.length() / 2); byte[] result = new byte[len]; char[] achar = hex.toCharArray(); for (int i = 0; i < len; i++) { int pos = i * 2; result[i] = (byte) (toByte(achar[pos]) << 4 | toByte(achar[pos + 1])); } return result; } private static byte toByte(char c) { byte b = (byte) "0123456789ABCDEF".indexOf(c); return b; } /** *//** * 把字节数组转换成16进制字符串 * @param bArray * @return */ public static final String bytesToHexString(byte[] bArray) { StringBuffer sb = new StringBuffer(bArray.length); String sTemp; for (int i = 0; i < bArray.length; i++) { sTemp = Integer.toHexString(0xFF & bArray[i]); if (sTemp.length() < 2) sb.append(0); sb.append(sTemp.toUpperCase()); }

EXCEL日期与时间函数大全

1.DATE 用途:返回代表特定日期的序列号。 语法:DATE(year,month,day) 参数:year为一到四位,根据使用的日期系统解释该参数。默认情况下,Excel for Windows使用1900日期系统,而Excel for Macintosh使用1904日期系统。Month代表每年中月份的数字。如果所输入的月份大于12,将从指定年份的一月份执行加法运算。Day 代表在该月份中第几天的数字。如果day 大于该月份的最大天数时,将从指定月份的第一天开始往上累加。 注意:Excel按顺序的序列号保存日期,这样就可以对其进行计算。如果工作簿使用的是1900日期系统,则Excel会将1900年1月1日保存为序列号1。同理,会将1998年1月1日保存为序列号35796,因为该日期距离1900年1月1日为35795天。 实例:如果采用1900日期系统(Excel默认),则公式“=DATE(2001,1,1)”返回36892。 2.DATEVaLUE 用途:返回date_text所表示的日期的序列号。该函数的主要用途是将文字表示的日期转换成一个序列号。 语法:DATEVaLUE(date_text) 参数:Date_text是用Excel日期格式表示日期的文本。在使用1900日期系统中,date_text必须是1900年1月1日到9999年12月31日之间的一个日期;而在1904日期系统中,date_text必须是1904年1月1日到9999年12月31日之间的一个日期。如果date_text超出上述范围,则函数DATEVaLUE返回错误值#value!。 如果省略参数date_text中的年代,则函数DATEVaLUE使用电脑系统内部时钟的当前年代,且date_text中的时间信息将被忽略。 实例:公式“=DATEVaLUE("2001/3/5")”返回36955,DATEVaLUE("2-26")返回36948。 3.DAY 用途:返回用序列号(整数1到31)表示的某日期的天数,用整数1 到31 表示。 语法:DAY(serial_number) 参数:Serial_number是要查找的天数日期,它有多种输入方式:带引号的文本串(如"1998/01/30")、序列号(如1900日期系统的35825表示的1998年1月30日),以及其他公式或函数的结果(如DATEVaLUE("1998/1/30"))。 实例:公式“=DAY("2001/1/27")”返回27,=DAY(35825)返回30, =DAY(DATEVaLUE("2001/1/25"))返回25。 4.DAYS360 用途:按照一年360天的算法(每个月30天,一年共计12 个月),返回两日期间相差的天数。 语法:DAYS360(start_date,end_date,method)

JAVA里面关于byte数组和String之间的转换问题

JAVA里面关于byte数组和String之间的转换问题把byte转化成string,必须经过编码。 例如下面一个例子: import java.io.UnsupportedEncodingException; public class test{ public static void main(String g[]) { String s = "12345abcd"; byte b[] = s.getBytes(); String t = b.toString(); System.out.println(t); } } 输出字符串的结果和字符串s不一样了. 经过以下方式转码就可以正确转换了: public class test{ public static void main(String g[]) { String s = "12345abcd"; byte b[] = s.getBytes(); try { String t = new String(b); System.out.print(t); } catch (Exception e) { e.printStackTrace(); } } } String str = "String"; byte[] byte1 = str.getBytes(); String str1 = new String(byte1); byte[] byte2 = str1.getBytes(); String str2 = new String(byte2); System.out.println("str<<<" + str); System.out.println("byte1<<<" + byte1); System.out.println("str1<<<" + str1); System.out.println("byte2<<<" + byte2); System.out.println("str2<<<" + str2); ------------------------------------- 输出结果 str<<

C#中将byte数组转换为8bit灰度图像

类似的文章在网上可以看到不少,但多多少少都存在一些问题。这两天做实验室的项目用到这个功能,我从头把它整理了一遍。 在看代码之前,首先解释几个问题。 byte数组存放的是图像每个像素的灰度值,byte类型正好是从0~255,存放8bit灰度图像的时候,一个数组元素就是一个像素的灰度值。仅有这个数组还不足以恢复出原来的图像,还必须事先知道图像的长、宽值; 创建Bitmap类的时候必须指定PixelFormat为Format8bppIndexed,这样才最符合图像本身的特性; Bitmap类虽然提供了GetPixel()、SetPixel()这样的方法,但我们绝对不能用这两个方法来进行大规模的像素读写,因为它们的性能实在很囧; 托管代码中,能不用unsafe就尽量不用。在.NET 2.0中已经提供了BitmapData类及其LockBits()、UnLockBits()操作,能够安全地进行内存读写; 图像的width和它存储时的stride是不一样的。位图的扫描线宽度一定是4的倍数,因此图像在内存中的大小并不是它的显示大小; Format8bppIndexed类型的PixelFormat是索引格式,其调色板并不是灰度的而是伪彩,因此需要我们对其加以修改。 代码如下,解说写在注释里了: 1 ///

2 /// 将一个字节数组转换为8bit灰度位图 3 /// 4 /// 显示字节数组 5 /// 图像宽度 6 /// 图像高度 7 /// 位图 8 public static Bitmap ToGrayBitmap(byte[] rawValues, int width, int height) 9 { 10 //// 申请目标位图的变量,并将其内存区域锁定 11 Bitmap bmp = new Bitmap(width, height, PixelFormat.Format8bppIndexed); 12 BitmapData bmpData = bmp.LockBits(new Rectangle(0, 0, width, height), 13 ImageLockMode.WriteOnly, PixelFormat.Format8bppIndexed); 14 15 //// 获取图像参数

javascript字节数组转换为16进制

javascript字节数组转换为16进制/** * byte数组转换成16进制字符串 * @param src * @return */ bytesToHexString(byte[] src){ public static String StringBuilder stringBuilder = new StringBuilder(); if (src == null || src.length <= 0) { return null; } for (int i = 0; i < src.length; i++) { int v = src[i] & 0xFF; String hv = Integer.toHexString(v); if (hv.length() < 2) { stringBuilder.append(0); } stringBuilder.append(hv); } return stringBuilder.toString(); } /** * 根据文件流读取图片文件真实类型 * @param is

* @return */ public static String getTypeByStream(FileInputStream is){ byte[] b = new byte[4]; try { is.read(b, 0, b.length); } catch (IOException e) { e.printStackTrace(); } String type = bytesToHexString(b).toUpperCase(); if(type.contains("FFD8FF")){ return "jpg"; }else if(type.contains("89504E47")){ return "png"; }else if(type.contains("47494638")){ return "gif"; }else if(type.contains("49492A00")){ return "tif"; }else if(type.contains("424D")){ return "bmp"; } return type; } public static void main(String[] args) throws Exception {

Excel中如何将日期格式进行转换

在 EXCEL中如何将日期格式转换 如何将 19000101格式转换成 1900-01-01 的格式? 如果日期所在单元格在 A 列,并从 A1 开始。 1、插入一辅助列 B 列, 2、在 B1 输入: =MID(A1,1,4)&-MID(A1,5,2)&-MID(A1,7,2)回车, 3、向下填充该公式。 4、选中 B 列→复制→粘贴→选择性粘贴→数值→确定 5、删除 A 列 在 EXCEL中如何利用身份证号码提取出生时间 假设身份证号在A1,时间格式为 1900-1-1 =IF(LEN(A1)=15,"19"&MID(A1,7,2)&"-"&MID(A1,9,2)&"-"&MID(A1,11,2),MID(A1,7,4)&"- "&MID(A1 ,11,2)&"-"&MID(A1,13,2)) 在 EXCEL中如何利用身份证号码提取性别 =IF(LEN(A1)=15,IF(MOD(MID(A1,15,1),2)=1,"男 "," 女") , IF(MOD(MID(A1,17,1),2)=1,"男 "," 女") ) 在 EXCEL中如何利用身份证号码计算周岁 假设身份证号在 C1,时间格式为 1900-1-1,出生时间为 X 答案 1: =DATEDIF(IF(LEN(A1)=15,"19"&MID(A1,7,2)&"-"&MID(A1,9,2)&"-"&MID(A1,11,2),MID(A1,7,4)&"-" &MID(A1,11,2)&"-"&MID(A1,13,2)),TODAY(),”y”) 简化之: =DATEDIF(X,TODAY(),”y”) 答案 2: =TEXT(TODAY()-IF(LEN(C1)=15,"19"&MID(C1,7,2)&"-"&MID(C1,9,2)&"-"&MID(C1,11,2),MID(C1,7,4) &"-"&MID(C1,11,2)&"-"&MID(C1,13,2 )),"yy") 简化之: =TEXT(TODAY()-”X,yy”) 在 EXCEL中如何利用身份证号码计算周岁 假设身份证号在C1: =IF(C1="","",IF(IF(LEN(C1)=15,"19"&MID(C1,7,2)&"-"&MID(C1,9,2)&"-"&MID(C1,11,2),MID(C1,7,4) &"-"&MID(C1,11,2)&"-"&MID(C1,13,2))>"2009-12-31","",TEXT(TODAY()- IF(LEN(C1)=15,"19"&MID( C1,7,2)&"-"&MID(C1,9,2)&"-"&MID(C1,11,2),MID(C1,7,4)&"- "&MID(C1,11,2)&"-"&MID(C1,13,2))," yy")))

相关主题