CvMat、Mat、IplImage之间的转换详解及实例

article/2025/10/5 11:20:53

IplImage:

在OpenCV中IplImage是表示一个图像的结构体,也是从OpenCV1.0到目前最为重要的一个结构;

在之前的图像表示用IplImage,而且之前的OpenCV是用C语言编写的,提供的接口也是C语言接口;

 

Mat:

Mat是后来OpenCV封装的一个C++类,用来表示一个图像,和IplImage表示基本一致,但是Mat还添加了一些图像函数;

 

 

在OpenCV中, IplImage 与 Mat是可以相互转换的;

 IplImage  转  Mat: 

// extern  IplImage * plpliamge; //假设 IplImage 已经创建;

 cv::Mat * pmatImage = new cv:Mat( IplImage, 0  ): //第二个参数表示不进行像素数据copy;

 

Mat 转 IplImage:

//extern cv:Mat  matImage; //假设已经创建cv:Mat;

IplImage limage = IplImage ( matImage );//不进行数据copy;

 

通常情况对于图像的读取,IplImage 通过 cvLoadImage,   cv:Mat通过 cv::imread;

 

对于内存图像数据创建稍有不同:

IplImage ,通过cvCreateImage, 创建后复制像素到创建的内存,或者cvCreateImageHeader和cvSetImageData创建;

 

cv::Mat,直接可以通过构造函数Mat(int _rows, int _cols, int _type, void* _data, size_t _step=AUTO_STEP); 直接创建;

示例:

cv::Mat * pMat = new cv::Mat( 288, 352,  CV_8UC3, imagebufdata );
IplImage IplImagetmp = IplImage(*pMat);

注意:是前两个参数是图像的height和width,不是width和height;

 

通过上面的描述可以看出,创建内存数据图像,直接通过 cv::Mat类比较简单,然后可以通过Mat获取IplImage,通过cvCreateImage等函数创建内存图像,比较麻烦,而且创建后,还要通过cvReleaseImage等函数释放内存,所以这里建议用cv::Mat创建;

 

 

见原博客:http://blog.sina.com.cn/s/blog_74a459380101obhm.html

OpenCV学习之CvMat的用法详解及实例

    CvMat是OpenCV比较基础的函数。初学者应该掌握并熟练应用。但是我认为计算机专业学习的方法是,不断的总结并且提炼,同时还要做大量的实践,如编码,才能记忆深刻,体会深刻,从而引导自己想更高层次迈进。

1.初始化矩阵: 

方式一、逐点赋值式: 

复制代码

CvMat* mat = cvCreateMat( 2, 2, CV_64FC1 );
cvZero( mat );
cvmSet( mat, 0, 0, 1 );
cvmSet( mat, 0, 1, 2 );
cvmSet( mat, 1, 0, 3 );
cvmSet( mat, 2, 2, 4 );
cvReleaseMat( &mat ); 

复制代码

 

方式二、连接现有数组式: 

double a[] = { 1, 2, 3, 4,    5, 6, 7, 8,    9, 10, 11, 12 };
CvMat mat = cvMat( 3, 4, CV_64FC1, a ); // 64FC1 for double
// 不需要cvReleaseMat,因为数据内存分配是由double定义的数组进行的。 

 

2.IplImage <----->cvMat的转换 

A.CvMat-> IplImage

IplImage* img = cvCreateImage(cvGetSize(mat),8,1);
cvGetImage(matI,img);cvSaveImage("rice1.bmp",img);

 

B.IplImage -> CvMat

复制代码

IplImage* img = cvLoadimage("leda.jpg",1);//法2:
CvMat *mat = cvCreateMat( img->height, img->width, CV_64FC3 );
cvConvert( img, mat );//法1:
CvMat mathdr;
CvMat *mat = cvGetMat( img, &mathdr );

复制代码

 

3.IplImage <--->Mat的转换 

(1)将IplImage----- > Mat类型

Mat::Mat(const IplImage* img, bool copyData=false);

 

默认情况下,新的Mat类型与原来的IplImage类型共享图像数据,转换只是创建一个Mat矩阵头。当将参数copyData设为true后,就会复制整个图像数据。

例:

复制代码

IplImage*iplImg = cvLoadImage("greatwave.jpg", 1);Matmtx(iplImg); // IplImage* ->Mat 共享数据// or : Mat mtx = iplImg;或者是:Mat mtx(iplImg,0); // 0是不复制影像,也就是iplImg的data共用同个记意位置,header各自有

复制代码

 

(2)将Mat类型转换-----> IplImage类型

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

例:

复制代码

IplImage ipl_img = img; // Mat -> IplImageIplImage*-> BYTE*BYTE* data= img->imageData;

复制代码

 

4.CvMat<--->Mat的转换

(1)将CvMat类型转换为Mat类型

B.CvMat->Mat

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

CvMat*m= cvCreatMat(int rows ,int cols , int type);Mat::Mat(const CvMat* m, bool copyData=false);

 

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

但是,CvMat类型与我们在线性代数课程上学的向量概念相比,更抽象,比如CvMat的元素数据类型并不仅限于基础数据类型,比如,下面创建一个二维数据矩阵:

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

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

(2)将Mat类型转换为CvMat类型

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

例:

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

CvMat cvMat = imgMat; // Mat -> CvMat

 

5.cv::Mat--->const cvArr*

cvArr * 数组的指针。就是opencv里面的一种类型。

Mat img;
const CvArr* s=(CvArr*)&img;
上面就可以了,CvArr是Mat的虚基类,所有直接强制转换就可以了

void cvResize( const CvArr*src, CvArr* dst, int interpolation=CV_INTER_LINEAR );// src 就是之前的lplimage类型的一个指针变量

 


6.cvArr(IplImage或者cvMat)转化为cvMat
方式一、cvGetMat方式:

复制代码

int coi = 0;
cvMat *mat = (CvMat*)arr;
if( !CV_IS_MAT(mat) )
{mat = cvGetMat( mat, &matstub, &coi );if (coi != 0) reutn; // CV_ERROR_FROM_CODE(CV_BadCOI);
}

复制代码

 


写成函数为:

复制代码

// This is just an example of function
// to support both IplImage and cvMat as an input
CVAPI( void ) cvIamArr( const CvArr* arr )
{CV_FUNCNAME( "cvIamArr" );__BEGIN__;CV_ASSERT( mat == NULL );CvMat matstub, *mat = (CvMat*)arr;int coi = 0;if( !CV_IS_MAT(mat) ){CV_CALL( mat = cvGetMat( mat, &matstub, &coi ) );if (coi != 0) CV_ERROR_FROM_CODE(CV_BadCOI);}// Process as cvMat__END__;
} 

复制代码

 

7.图像直接操作
方式一:直接数组操作 int col, row, z;

复制代码

uchar b, g, r;
for( row = 0; row < img->height; y++ )
{for ( col = 0; col < img->width; col++ ){b = img->imageData[img->widthStep * row + col * 3]g = img->imageData[img->widthStep * row + col * 3 + 1];r = img->imageData[img->widthStep * row + col * 3 + 2];}
}

复制代码

 


方式二:宏操作:

复制代码

int row, col;
uchar b, g, r;
for( row = 0; row < img->height; row++ )
{for ( col = 0; col < img->width; col++ ){b = CV_IMAGE_ELEM( img, uchar, row, col * 3 );g = CV_IMAGE_ELEM( img, uchar, row, col * 3 + 1 );r = CV_IMAGE_ELEM( img, uchar, row, col * 3 + 2 );}
}

复制代码

 


注:CV_IMAGE_ELEM( img, uchar, row, col * img->nChannels + ch ) 

8.cvMat的直接操作
数组的直接操作比较郁闷,这是由于其决定于数组的数据类型。 

对于CV_32FC1 (1 channel float):

CvMat* M = cvCreateMat( 4, 4, CV_32FC1 );
M->data.fl[ row * M->cols + col ] = (float)3.0; 

 

对于CV_64FC1 (1 channel double):

CvMat* M = cvCreateMat( 4, 4, CV_64FC1 );
M->data.db[ row * M->cols + col ] = 3.0; 

 

一般的,对于1通道的数组:

CvMat* M = cvCreateMat( 4, 4, CV_64FC1 );
CV_MAT_ELEM( *M, double, row, col ) = 3.0;

 


注意double要根据数组的数据类型来传入,这个宏对多通道无能为力。 

对于多通道:
看看这个宏的定义:#define CV_MAT_ELEM_CN( mat, elemtype, row, col ) \
    (*(elemtype*)((mat).data.ptr + (size_t)(mat).step*(row) + sizeof(elemtype)*(col)))
if( CV_MAT_DEPTH(M->type) == CV_32F )
    CV_MAT_ELEM_CN( *M, float, row, col * CV_MAT_CN(M->type) + ch ) = 3.0;
if( CV_MAT_DEPTH(M->type) == CV_64F )
    CV_MAT_ELEM_CN( *M, double, row, col * CV_MAT_CN(M->type) + ch ) = 3.0;
更优化的方法是:

复制代码

   #define CV_8U   0#define CV_8S   1#define CV_16U 2#define CV_16S 3#define CV_32S 4#define CV_32F 5#define CV_64F 6#define CV_USRTYPE1 7 int elem_size = CV_ELEM_SIZE( mat->type );
for( col = start_col; col < end_col; col++ ) {for( row = 0; row < mat->rows; row++ ) {for( elem = 0; elem < elem_size; elem++ ) {(mat->data.ptr + ((size_t)mat->step * row) + (elem_size * col))[elem] =(submat->data.ptr + ((size_t)submat->step * row) + (elem_size * (col - start_col)))[elem];}}
} 

复制代码

 

对于多通道的数组,以下操作是推荐的:

复制代码

for(row=0; row< mat->rows; row++){p = mat->data.fl + row * (mat->step/4);for(col = 0; col < mat->cols; col++){*p = (float) row+col;*(p+1) = (float) row+col+1;*(p+2) =(float) row+col+2;p+=3;}}

复制代码

 


对于两通道和四通道而言:

CvMat* vector = cvCreateMat( 1, 3, CV_32SC2 );
CV_MAT_ELEM( *vector, CvPoint, 0, 0 ) = cvPoint(100,100); CvMat* vector = cvCreateMat( 1, 3, CV_64FC4 );
CV_MAT_ELEM( *vector, CvScalar, 0, 0 ) = cvScalar(0,0,0,0); 

 

9.间接访问cvMat
cvmGet/Set是访问CV_32FC1 和 CV_64FC1型数组的最简便的方式,其访问速度和直接访问几乎相同
cvmSet( mat, row, col, value );
cvmGet( mat, row, col );
举例:打印一个数组

复制代码

inline void cvDoubleMatPrint( const CvMat* mat )
{int i, j;for( i = 0; i < mat->rows; i++ ){for( j = 0; j < mat->cols; j++ ){printf( "%f ",cvmGet( mat, i, j ) );}printf( "\n" );}
} 

复制代码

 

而对于其他的,比如是多通道的后者是其他数据类型的,cvGet/Set2D是个不错的选择
CvScalar scalar = cvGet2D( mat, row, col );
cvSet2D( mat, row, col, cvScalar( r, g, b ) ); 

注意:数据不能为int,因为cvGet2D得到的实质是double类型。
举例:打印一个多通道矩阵:

复制代码

inline void cv3DoubleMatPrint( const CvMat* mat )
{int i, j;for( i = 0; i < mat->rows; i++ ){for( j = 0; j < mat->cols; j++ ){CvScalar scal = cvGet2D( mat, i, j );printf( "(%f,%f,%f) ", scal.val[0], scal.val[1], scal.val[2] );}printf( "\n" );}
} 

复制代码

 

10.修改矩阵的形状——cvReshape的操作
经实验表明矩阵操作的进行的顺序是:首先满足通道,然后满足列,最后是满足行。
注意:这和Matlab是不同的,Matlab是行、列、通道的顺序。
我们在此举例如下:
对于一通道:

复制代码

// 1 channel
CvMat *mat, mathdr;
double data[] = { 11, 12, 13, 14,21, 22, 23, 24,31, 32, 33, 34 };
CvMat* orig = &cvMat( 3, 4, CV_64FC1, data );
//11 12 13 14
//21 22 23 24
//31 32 33 34
mat = cvReshape( orig, &mathdr, 1, 1 ); // new_ch, new_rows
cvDoubleMatPrint( mat ); // above
// 11 12 13 14 21 22 23 24 31 32 33 34
mat = cvReshape( mat, &mathdr, 1, 3 ); // new_ch, new_rows
cvDoubleMatPrint( mat ); // above
//11 12 13 14
//21 22 23 24
//31 32 33 34
mat = cvReshape( orig, &mathdr, 1, 12 ); // new_ch, new_rows
cvDoubleMatPrint( mat ); // above
// 11
// 12
// 13
// 14
// 21
// 22
// 23
// 24
// 31
// 32
// 33
// 34
mat = cvReshape( mat, &mathdr, 1, 3 ); // new_ch, new_rows
cvDoubleMatPrint( mat ); // above
//11 12 13 14
//21 22 23 24
//31 32 33 34
mat = cvReshape( orig, &mathdr, 1, 2 ); // new_ch, new_rows
cvDoubleMatPrint( mat ); // above
//11 12 13 14 21 22
//23 24 31 32 33 34
mat = cvReshape( mat, &mathdr, 1, 3 ); // new_ch, new_rows
cvDoubleMatPrint( mat ); // above
//11 12 13 14
//21 22 23 24
//31 32 33 34
mat = cvReshape( orig, &mathdr, 1, 6 ); // new_ch, new_rows
cvDoubleMatPrint( mat ); // above
// 11 12
// 13 14
// 21 22
// 23 24
// 31 32
// 33 34
mat = cvReshape( mat, &mathdr, 1, 3 ); // new_ch, new_rows
cvDoubleMatPrint( mat ); // above
//11 12 13 14
//21 22 23 24
//31 32 33 34
// Use cvTranspose and cvReshape( mat, &mathdr, 1, 2 ) to get
// 11 23
// 12 24
// 13 31
// 14 32
// 21 33
// 22 34
// Use cvTranspose again when to recover

复制代码

 

对于三通道
 

复制代码

//221 222 223
// channel first, column second, row third
// memorize this transform because this is useful to
// add (or do something) color channels
CvMat* mat2 = cvCreateMat( mat->cols, mat->rows, mat->type );
cvTranspose( mat, mat2 );
cvDoubleMatPrint( mat2 ); // above
//111 121 211 221
//112 122 212 222
//113 123 213 223
cvReleaseMat( &mat2 ); 

复制代码

 

11.计算色彩距离
我们要计算img1,img2的每个像素的距离,用dist表示,定义如下
IplImage *img1 = cvCreateImage( cvSize(w,h), IPL_DEPTH_8U, 3 );
IplImage *img2 = cvCreateImage( cvSize(w,h), IPL_DEPTH_8U, 3 );
CvMat *dist = cvCreateMat( h, w, CV_64FC1 );
比较笨的思路是:cvSplit->cvSub->cvMul->cvAdd
代码如下:

复制代码

IplImage *img1B = cvCreateImage( cvGetSize(img1), img1->depth, 1 );
IplImage *img1G = cvCreateImage( cvGetSize(img1), img1->depth, 1 );
IplImage *img1R = cvCreateImage( cvGetSize(img1), img1->depth, 1 );
IplImage *img2B = cvCreateImage( cvGetSize(img1), img1->depth, 1 );
IplImage *img2G = cvCreateImage( cvGetSize(img1), img1->depth, 1 );
IplImage *img2R = cvCreateImage( cvGetSize(img1), img1->depth, 1 );
IplImage *diff    = cvCreateImage( cvGetSize(img1), IPL_DEPTH_64F, 1 );
cvSplit( img1, img1B, img1G, img1R );
cvSplit( img2, img2B, img2G, img2R );
cvSub( img1B, img2B, diff );
cvMul( diff, diff, dist );
cvSub( img1G, img2G, diff );
cvMul( diff, diff, diff);
cvAdd( diff, dist, dist );
cvSub( img1R, img2R, diff );
cvMul( diff, diff, diff );
cvAdd( diff, dist, dist );
cvReleaseImage( &img1B );
cvReleaseImage( &img1G );
cvReleaseImage( &img1R );
cvReleaseImage( &img2B );
cvReleaseImage( &img2G );
cvReleaseImage( &img2R );
cvReleaseImage( &diff ); 

复制代码

 

比较聪明的思路是

复制代码

int D = img1->nChannels; // D: Number of colors (dimension)
int N = img1->width * img1->height; // N: number of pixels
CvMat mat1hdr, *mat1 = cvReshape( img1, &mat1hdr, 1, N ); // N x D(colors)
CvMat mat2hdr, *mat2 = cvReshape( img2, &mat2hdr, 1, N ); // N x D(colors)
CvMat diffhdr, *diff = cvCreateMat( N, D, CV_64FC1 ); // N x D, temporal buff
cvSub( mat1, mat2, diff );
cvMul( diff, diff, diff );
dist = cvReshape( dist, &disthdr, 1, N ); // nRow x nCol to N x 1
cvReduce( diff, dist, 1, CV_REDUCE_SUM ); // N x D to N x 1
dist = cvReshape( dist, &disthdr, 1, img1->height ); // Restore N x 1 to nRow x nCol
cvReleaseMat( &diff ); #pragma comment( lib, "cxcore.lib" )
#include "cv.h"
#include 
int main()
{
CvMat* mat = cvCreateMat(3,3,CV_32FC1);
cvZero(mat);//将矩阵置0
//为矩阵元素赋值
CV_MAT_ELEM( *mat, float, 0, 0 ) = 1.f;
CV_MAT_ELEM( *mat, float, 0, 1 ) = 2.f;
CV_MAT_ELEM( *mat, float, 0, 2 ) = 3.f;
CV_MAT_ELEM( *mat, float, 1, 0 ) = 4.f;
CV_MAT_ELEM( *mat, float, 1, 1 ) = 5.f;
CV_MAT_ELEM( *mat, float, 1, 2 ) = 6.f;
CV_MAT_ELEM( *mat, float, 2, 0 ) = 7.f;
CV_MAT_ELEM( *mat, float, 2, 1 ) = 8.f;
CV_MAT_ELEM( *mat, float, 2, 2 ) = 9.f;
//获得矩阵元素(0,2)的值
float *p = (float*)cvPtr2D(mat, 0, 2);
printf("%f\n",*p);return 0;
}

http://chatgpt.dhexx.cn/article/86Cardml.shtml

相关文章

VMware 虚拟机 Ubuntu 系统执行 ifconfig 命令 eth0没有IP地址(intet addr、Bcast、Mask) 解决:UP BROADCAST MULTICAST 问题

VMware 虚拟机 ifconfig没有net_addr地址、Bcast、Mask的解决方法 最新更新时间&#xff1a;2018-11-9 02:43:55 使用时间长的虚拟机&#xff0c;会莫名其妙的连接不上网 在终端中&#xff0c;使用ifconfig命令查看Ubuntu系统的IP地址&#xff0c;发现没有分配IP地址。 eth0&a…

FISCO BCOS简介

FISCO BCOS是由国内企业主导研发、对外开源、安全可控的企业级金融联盟链底层平台&#xff0c;由金链盟开源工作组协作打造&#xff0c;并于2017年正式对外开源。 社区以开源链接多方&#xff0c;截止2020年5月&#xff0c;汇聚了超1000家企业及机构、逾万名社区成员参与共建共…

使用MPI实现broadcast、scatter、gather操作

使用MPI实现broadcast、scatter、gather操作 1.MPI_Bcast:广播消息 MPI_Bcast用于将一个进程的buffer中的数据广播到其他进程的相同buffer变量中。 #include "stdio.h" #include "mpi.h" #include "stdlib.h" #define N 10 int main(i…

用MPI进行分布式内存编程(二)MPI_allreduce MPI_scatt MPI_bcast.....

通过上一篇中&#xff0c;知道了基本的MPI编写并行程序&#xff0c;最后的例子中&#xff0c;让使用0号进程做全局的求和的所有工作&#xff0c;而其他的进程却都不工作&#xff0c;这种方式也许是某种特定情况下的方案&#xff0c;但明显不是最好的方案。举个例子&#xff0c;…

MPI编程(4)—集合通信MPI_Bcast、MPI_Gather、MPI_Scatter、MPI_Reduce

1. MPI_Bcast:广播消息 MPI_Bcast用于将一个进程的buffer中的数据广播到其他进程的相同buffer变量中 代码示例如下: int rank, data[10];MPI_Init(0, 0);MPI_Comm_rank(MPI_COMM_WORLD, &rank);if (rank == 0) {for (int i = 0; i < 10; ++i){data[i] = i + 1;}} //…

MPI_Bcast与MPI_Comm_split配合,实现行广播或列广播

15个进程&#xff0c;3行5列&#xff0c;结合MPI_Comm_split函数&#xff0c;MPI_Bcast实现行广播和列广播。 Bcast广播时&#xff0c;如果通讯域是split之后的&#xff0c;则会按照color相同的进行广播&#xff0c;即color相同的为一组&#xff0c;每个组内编号为root的向组内…

VMware 虚拟机 linux执行 ifconfig 命令 eth0没有IP地址(intet addr、Bcast、Mask) UP BROADCAST MULTICAST 问题

VMware 虚拟机 ifconfig没有net_addr地址、Bcast、Mask的解决方法&#xff1a; 在vmvare中&#xff0c;使用ifconfig命令查看linux系统的IP地址&#xff0c;发现没有分配IP地址。 eth0&#xff1a;网络接口 link encap : 网络类型 HWaddr : 网卡物理地址 Inet addr &…

CABAC

CABAC CABAC&#xff08;上下文自适应的二进制算术编码&#xff09;基于算术编码&#xff0c;在HEVC中&#xff0c;除了参数集、SEI和slice头部之外&#xff0c;其余的所有数据都使用CABAC来进行熵编码。1.4.1 原理 主要包括三个步骤&#xff1a; 二进制化&#xff1b; 上下…

【Redis】 - Redis 6.0 新特性之客户端缓存

Redis 6.0 新特性之客户端缓存 1. 为什么需要客户端缓存1.1 低延迟和大规模提供数据服务1.2 其他 cache 层 2. Redis 中的客户端缓存2.1 什么样的数据集应该被客户端缓存2.2 客户端缓存的两个主要优点 3. 缓存的数据一致性问题4. Redis 客户端缓存的实现原理4.1 普通模式4.1.1 …

MCAST是什么?(播协议通信程序)

看海康isapi.pdf文档看到的&#xff0c;不懂什么意思 播协议通信程序&#xff0c;用于测试在局域网或者在三层交换机架构下进行通信测试 Multicast Protocol communications procedures, for testing in the local area network or switches in the three-tier framework for …

一、Broadcast简介

Android广播&#xff08;Broadcast&#xff09; 一、Broadcast简介 Broadcast是android中的四大组件之一&#xff0c;是在组件之间传播数据&#xff08;Intent&#xff09;的一种机制。广播的发送者和接收者事先是不需要知道对方的存在的。这样带来的好处便是&#xff0c;系统的…

BCSP

BCSP 包的类型 有4种类型&#xff0c;Sync,Sync-Resp,Conf,Conf-Resp Sync: {0xda,0xdc,0xed,0xed} Sync-Resp: {0xac,0xaf,0xef,0xee} Conf: {0xad,0xef,0xac,0xed} Conf-Resp: {0xde,0xad,0xd0,0xd0} 上面2图式BCSP的行为和状…

MPI MPI_Bcast (广播)用法详解

函数范式 int MPI_Bcast(void * data_p;int count;MPI_Datatype datatype;int source_proc;MPI_Comm comm; );功能描述&#xff1a; 一个广播发生的时候&#xff0c;一个进程会把同样一份数据传递给一个 communicator 里的所有其他进程。根节点调用 MPI_Bcast 函数的时候&…

关于inet addr(网络地址)、bcast(广播地址)、mask(子网掩码)的学习

int addr:网络地址。IP地址和子网掩码进行相与运算&#xff0c;将运算结果中的网络地址不变&#xff0c;主机地址变为0&#xff0c;即主机号全0是网络地址。示例: 如果是192的C段地址&#xff0c;那么网络地址就是&#xff1a;192.168.1.0&#xff0c;地址掩码是&#xff1a;25…

错误码415

POST请求报错&#xff1a; “status”: 415, “error”: “Unsupported Media Type”, “message”: "Content type app charlse 错误码 415表示不支持内容类型。 错误原因 没有正确设置内容类型标头。 正确做法 检查 content-type

发送HTTP请求返回415状态码的解决办法

1.问题出现&#xff1a; 在用POST方式携带token访问一个API接口时&#xff0c;发现返回状态码为415&#xff0c;错误信息为“Unsupported Media Type” 2.分析原因&#xff1a; 415错误的解释是说&#xff0c;服务器无法处理请求附带的媒体格式&#xff0c;不明白什么意思&am…

http post 415错误

前面在spring boot项目中&#xff0c;进行前后端数据交互时突然遇到了415错误。一时间有点懵&#xff0c;在网上找了一些资料&#xff0c;总算是知道为什么了&#xff0c;不多说&#xff0c;直接上图。 这是正常的form提交的数据。 debug之后能够服务器能够正常的接收数据。 当…

http405错误解决

问题描述&#xff1a;在使用vue框架和spring boot进行前后端分离开发时&#xff0c;出现405错误。 解决思考&#xff1a; 分析&#xff1a;我们知道&#xff0c;一般4开头的错误基本都是前端的问题&#xff0c;或者是浏览器的问题。而且我之前使用了swagger对后端接口进行了测…

415错误如何解决

415错误可能是由于前端传输的格式不对引起的 我这里是因为传的json字符串 更正前 错误 只要加上一行&#xff1a; contentType: application/json;charsetutf-8,问题解决

【前后端异常】axios post请求 解决返回415状态码的错误

错误描述&#xff1a; 进行有文件的表单提交时出现415错误&#xff0c;以前没遇到过记录一下 415错误的解释是说&#xff0c;服务器无法处理请求附带的媒体格式。以下是HTTP的状态码关于415返回码的说明&#xff1a; 415Unsupported Media Type服务器无法处理请求附带的媒体格…