STM32正点原子图片——显示实验

news2024/11/20 12:35:26

目录

一、图片显示部分

GIF

piclib.c介绍

图像显示实验main.c介绍

二、SD卡模块 

1、SD卡基础知识

2、SD卡读操作 

3、SD卡写操作 


一、图片显示部分

GIF

  • GIF(Graphics Interchange Format)的原义是“图像互换格式”,是CompuServe公司在1987年开发的图像文件格式。GIF文件的数据。是一种基于LZW算法的连续色调的无损压缩格式。其压缩率一般在50%左右,它不属于任何应用程序。
  • GIF主要分为两个版本,即GIF 89a和GIF 87a

                GIF 87a:是在1987年制定的版本GIF

                GIF 89a:是1989年制定的版本。

本质上是动态地显示多个连续的图片

piclib.c介绍

piclib.c中定义了LCD液晶显示需要使用的函数

#include "piclib.h"
#include "lcd.h"
//	 
//本程序只供学习使用,未经作者许可,不得用于其它任何用途
//ALIENTEK MiniSTM32开发板
//图片解码 驱动代码	   
//正点原子@ALIENTEK
//技术论坛:www.openedv.com
//修改日期:2014/3/14
//版本:V2.0
//版权所有,盗版必究。
//Copyright(C) 广州市星翼电子科技有限公司 2009-2019
//All rights reserved
//********************************************************************************
//升级说明
//V2.0
//1,将jpeg解码库换成了TJPGD,支持更多的jpg/jpeg文件,支持小尺寸图片快速jpeg显示 
//2,pic_phy里面新增fillcolor函数,用于填充显示,以提高小尺寸jpg图片的显示速度
//3,ai_load_picfile函数,新增一个参数:fast,用于设置是否使能jpeg/jpg快速显示
//注意:这里的小尺寸是指:jpg/jpeg图片尺寸小于等于LCD尺寸.
//

_pic_info picinfo;	 	//图片信息
_pic_phy pic_phy;			//图片显示物理接口	
//
//lcd.h没有提供划横线函数,需要自己实现
void piclib_draw_hline(u16 x0,u16 y0,u16 len,u16 color)
{
	if((len==0)||(x0>lcddev.width)||(y0>lcddev.height))return;
	LCD_Fill(x0,y0,x0+len-1,y0,color);	
}
//填充颜色
//x,y:起始坐标
//width,height:宽度和高度。
//*color:颜色数组
void piclib_fill_color(u16 x,u16 y,u16 width,u16 height,u16 *color)
{  
	LCD_Color_Fill(x,y,x+width-1,y+height-1,color);	
}
//
//画图初始化,在画图之前,必须先调用此函数
//指定画点/读点
void piclib_init(void)
{
	pic_phy.read_point=LCD_ReadPoint;  		//读点函数实现
	pic_phy.draw_point=LCD_Fast_DrawPoint;	//画点函数实现
	pic_phy.fill=LCD_Fill;					//填充函数实现
	pic_phy.draw_hline=piclib_draw_hline;  	//画线函数实现
	pic_phy.fillcolor=piclib_fill_color;  	//颜色填充函数实现 

	picinfo.lcdwidth=lcddev.width;	//得到LCD的宽度像素
	picinfo.lcdheight=lcddev.height;//得到LCD的高度像素

	picinfo.ImgWidth=0;	//初始化宽度为0
	picinfo.ImgHeight=0;//初始化高度为0
	picinfo.Div_Fac=0;	//初始化缩放系数为0
	picinfo.S_Height=0;	//初始化设定的高度为0
	picinfo.S_Width=0;	//初始化设定的宽度为0
	picinfo.S_XOFF=0;	//初始化x轴的偏移量为0
	picinfo.S_YOFF=0;	//初始化y轴的偏移量为0
	picinfo.staticx=0;	//初始化当前显示到的x坐标为0
	picinfo.staticy=0;	//初始化当前显示到的y坐标为0
}
//快速ALPHA BLENDING算法.
//src:源颜色
//dst:目标颜色
//alpha:透明程度(0~32)
//返回值:混合后的颜色.
u16 piclib_alpha_blend(u16 src,u16 dst,u8 alpha)
{
	u32 src2;
	u32 dst2;	 
	//Convert to 32bit |-----GGGGGG-----RRRRR------BBBBB|
	src2=((src<<16)|src)&0x07E0F81F;
	dst2=((dst<<16)|dst)&0x07E0F81F;   
	//Perform blending R:G:B with alpha in range 0..32
	//Note that the reason that alpha may not exceed 32 is that there are only
	//5bits of space between each R:G:B value, any higher value will overflow
	//into the next component and deliver ugly result.
	dst2=((((dst2-src2)*alpha)>>5)+src2)&0x07E0F81F;
	return (dst2>>16)|dst2;  
}
//初始化智能画点
//内部调用
void ai_draw_init(void)
{
	float temp,temp1;	   
	temp=(float)picinfo.S_Width/picinfo.ImgWidth;
	temp1=(float)picinfo.S_Height/picinfo.ImgHeight;						 
	if(temp<temp1)temp1=temp;//取较小的那个	 
	if(temp1>1)temp1=1;	  
	//使图片处于所给区域的中间
	picinfo.S_XOFF+=(picinfo.S_Width-temp1*picinfo.ImgWidth)/2;
	picinfo.S_YOFF+=(picinfo.S_Height-temp1*picinfo.ImgHeight)/2;
	temp1*=8192;//扩大8192倍	 
	picinfo.Div_Fac=temp1;
	picinfo.staticx=0xffff;
	picinfo.staticy=0xffff;//放到一个不可能的值上面			 										    
}   
//判断这个像素是否可以显示
//(x,y) :像素原始坐标
//chg   :功能变量. 
//返回值:0,不需要显示.1,需要显示
u8 is_element_ok(u16 x,u16 y,u8 chg)
{				  
	if(x!=picinfo.staticx||y!=picinfo.staticy)
	{
		if(chg==1)
		{
			picinfo.staticx=x;
			picinfo.staticy=y;
		} 
		return 1;
	}else return 0;
}
//智能画图
//FileName:要显示的图片文件  BMP/JPG/JPEG/GIF
//x,y,width,height:坐标及显示区域尺寸
//fast:使能jpeg/jpg小图片(图片尺寸小于等于液晶分辨率)快速解码,0,不使能;1,使能.
//图片在开始和结束的坐标点范围内显示
u8 ai_load_picfile(const u8 *filename,u16 x,u16 y,u16 width,u16 height,u8 fast)
{	
	u8	res;//返回值
	u8 temp;	
	if((x+width)>picinfo.lcdwidth)return PIC_WINDOW_ERR;		//x坐标超范围了.
	if((y+height)>picinfo.lcdheight)return PIC_WINDOW_ERR;		//y坐标超范围了.  
	//得到显示方框大小	  	 
	if(width==0||height==0)return PIC_WINDOW_ERR;	//窗口设定错误
	picinfo.S_Height=height;
	picinfo.S_Width=width;
	//显示区域无效
	if(picinfo.S_Height==0||picinfo.S_Width==0)
	{
		picinfo.S_Height=lcddev.height;
		picinfo.S_Width=lcddev.width;
		return FALSE;   
	}
	if(pic_phy.fillcolor==NULL)fast=0;//颜色填充函数未实现,不能快速显示
	//显示的开始坐标点
	picinfo.S_YOFF=y;
	picinfo.S_XOFF=x;
	//文件名传递		 
	temp=f_typetell((u8*)filename);	//得到文件的类型
	switch(temp)
	{											  
		case T_BMP:
			res=stdbmp_decode(filename); 				//解码bmp	  	  
			break;
		case T_JPG:
		case T_JPEG:
			res=jpg_decode(filename,fast);				//解码JPG/JPEG	  	  
			break;
		case T_GIF:
			res=gif_decode(filename,x,y,width,height);	//解码gif  	  
			break;
		default:
	 		res=PIC_FORMAT_ERR;  						//非图片格式!!!  
			break;
	}  											   
	return res;
}



_pic_phy是函数指针结构体 

typedef struct 
{
	u16(*read_point)(u16,u16);				//u16 read_point(u16 x,u16 y)						读点函数
	void(*draw_point)(u16,u16,u16);			//void draw_point(u16 x,u16 y,u16 color)		    画点函数
 	void(*fill)(u16,u16,u16,u16,u16);		///void fill(u16 sx,u16 sy,u16 ex,u16 ey,u16 color) 单色填充函数 	 
 	void(*draw_hline)(u16,u16,u16,u16);		//void draw_hline(u16 x0,u16 y0,u16 len,u16 color)  画水平线函数	 
 	void(*fillcolor)(u16,u16,u16,u16,u16*);	//void piclib_fill_color(u16 x,u16 y,u16 width,u16 height,u16 *color) 颜色填充
}_pic_phy; 

ALPHA BLENDING算法是图像透明度处理算法 

//快速ALPHA BLENDING算法.
//src:源颜色
//dst:目标颜色
//alpha:透明程度(0~32)
//返回值:混合后的颜色.
u16 piclib_alpha_blend(u16 src,u16 dst,u8 alpha)
{
	u32 src2;
	u32 dst2;	 
	//Convert to 32bit |-----GGGGGG-----RRRRR------BBBBB|
	src2=((src<<16)|src)&0x07E0F81F;
	dst2=((dst<<16)|dst)&0x07E0F81F;   
	//Perform blending R:G:B with alpha in range 0..32
	//Note that the reason that alpha may not exceed 32 is that there are only
	//5bits of space between each R:G:B value, any higher value will overflow
	//into the next component and deliver ugly result.
	dst2=((((dst2-src2)*alpha)>>5)+src2)&0x07E0F81F;
	return (dst2>>16)|dst2;  
}

is_element_ok主要用于图像压缩显示部分 

//判断这个像素是否可以显示
//(x,y) :像素原始坐标
//chg   :功能变量. 
//返回值:0,不需要显示.1,需要显示
u8 is_element_ok(u16 x,u16 y,u8 chg)
{				  
	if(x!=picinfo.staticx||y!=picinfo.staticy)
	{
		if(chg==1)
		{
			picinfo.staticx=x;
			picinfo.staticy=y;
		} 
		return 1;
	}else return 0;
}

 智能画图函数ai_load_picfile,自动判断文件类型并将文件显示在你所指定的位置上

//智能画图
//FileName:要显示的图片文件  BMP/JPG/JPEG/GIF
//x,y,width,height:坐标及显示区域尺寸
//fast:使能jpeg/jpg小图片(图片尺寸小于等于液晶分辨率)快速解码,0,不使能;1,使能.
//图片在开始和结束的坐标点范围内显示
u8 ai_load_picfile(const u8 *filename,u16 x,u16 y,u16 width,u16 height,u8 fast)
{	
	u8	res;//返回值
	u8 temp;	
	if((x+width)>picinfo.lcdwidth)return PIC_WINDOW_ERR;		//x坐标超范围了.
	if((y+height)>picinfo.lcdheight)return PIC_WINDOW_ERR;		//y坐标超范围了.  
	//得到显示方框大小	  	 
	if(width==0||height==0)return PIC_WINDOW_ERR;	//窗口设定错误
	picinfo.S_Height=height;
	picinfo.S_Width=width;
	//显示区域无效
	if(picinfo.S_Height==0||picinfo.S_Width==0)
	{
		picinfo.S_Height=lcddev.height;
		picinfo.S_Width=lcddev.width;
		return FALSE;   
	}
	if(pic_phy.fillcolor==NULL)fast=0;//颜色填充函数未实现,不能快速显示
	//显示的开始坐标点
	picinfo.S_YOFF=y;
	picinfo.S_XOFF=x;
	//文件名传递		 
	temp=f_typetell((u8*)filename);	//得到文件的类型
	switch(temp)
	{											  
		case T_BMP:
			res=stdbmp_decode(filename); 				//解码bmp	  	  
			break;
		case T_JPG:
		case T_JPEG:
			res=jpg_decode(filename,fast);				//解码JPG/JPEG	  	  
			break;
		case T_GIF:
			res=gif_decode(filename,x,y,width,height);	//解码gif  	  
			break;
		default:
	 		res=PIC_FORMAT_ERR;  						//非图片格式!!!  
			break;
	}  											   
	return res;
}

图像显示实验main.c介绍

pic_get_tnum函数用来得到path路径下存储目标文件的个数,关键是使用了f_readdir函数。此函数来自于FATFS文件操作系统。

//得到path路径下,目标文件的总个数
//path:路径		    
//返回值:总有效文件数
u16 pic_get_tnum(u8 *path)
{	  
	u8 res;
	u16 rval=0;
 	DIR tdir;	 		//临时目录
	FILINFO tfileinfo;	//临时文件信息	
	u8 *fn;	 			 			   			     
    res=f_opendir(&tdir,(const TCHAR*)path); 	//打开目录
  	tfileinfo.lfsize=_MAX_LFN*2+1;				//长文件名最大长度
	tfileinfo.lfname=mymalloc(tfileinfo.lfsize);//为长文件缓存区分配内存
	if(res==FR_OK&&tfileinfo.lfname!=NULL)
	{
		while(1)//查询总的有效文件数
		{
	        res=f_readdir(&tdir,&tfileinfo);       		//读取目录下的一个文件
	        if(res!=FR_OK||tfileinfo.fname[0]==0)break;	//错误了/到末尾了,退出		  
     		fn=(u8*)(*tfileinfo.lfname?tfileinfo.lfname:tfileinfo.fname);			 
			res=f_typetell(fn);	
			if((res&0XF0)==0X50)//取高四位,看看是不是图片文件	
			{
				rval++;//有效文件数增加1
			}	    
		}  
	} 
	return rval;
}

dir_sdi函数用来改变当前目录的索引,同样也是来源于ff.c文件

while(res==FR_OK)//打开成功
	{	
		dir_sdi(&picdir,picindextbl[curindex]);			//改变当前目录索引	   
        res=f_readdir(&picdir,&picfileinfo);       		//读取目录下的一个文件
        if(res!=FR_OK||picfileinfo.fname[0]==0)break;	//错误了/到末尾了,退出
        fn=(u8*)(*picfileinfo.lfname?picfileinfo.lfname:picfileinfo.fname);			 
		strcpy((char*)pname,"0:/PICTURE/");				//复制路径(目录)
		strcat((char*)pname,(const char*)fn);  			//将文件名接在后面
 		LCD_Clear(BLACK);
 		ai_load_picfile(pname,0,0,lcddev.width,lcddev.height,1);//显示图片    
		Show_Str(2,2,240,16,pname,16,1); 				//显示图片名字
		t=0;
		while(1) 
		{
			key=KEY_Scan(0);		//扫描按键
			if(t>250)key=1;			//模拟一次按下KEY0    
			if((t%20)==0)LED0=!LED0;//LED0闪烁,提示程序正在运行.
			if(key==KEY1_PRES)		//上一张
			{
				if(curindex)curindex--;
				else curindex=totpicnum-1;
				break;
			}else if(key==KEY0_PRES)//下一张
			{
				curindex++;		   	
				if(curindex>=totpicnum)curindex=0;//到末尾的时候,自动从头开始
				break;
			}else if(key==WKUP_PRES)
			{
				pause=!pause;
				LED1=!pause; 	//暂停的时候LED1亮.  
			}
			if(pause==0)t++;
			delay_ms(10); 
		}					    
		res=0;  
	} 										

二、SD卡模块 

1、SD卡基础知识

SD卡 (Secure Digital Memory Card)即:安全数码卡,它是在MMC的基础上发展而来,是一种基于半导体快闪记忆器的新一代记忆设备,它被广泛地于便携式装置上使用,例如数码相机、个人数码助理(PDA)和多媒体播放器等。SD卡由日本松下、东芝及美国SanDisk公司于1999年8月共同开发研制。
SD卡按容量分类,可以分为3类:SD卡、SDHC卡、SDXC卡,如下表所示:

容量

命名

简称

0~2G

Standard Capacity SD Memory Card

SDSCSD

2G~32G

High Capacity SD Memory Card

SDHC

32G~2T

Extended Capacity SD Memory Card

SDXC

①初始化SPI接口及相关IO

        通过SPI连接SD卡,所以先要初始化MCUSPI接口,以及相关IO

②上电延时(>74CLK)

③卡复位(CMD0),进入IDLE状态。

        发送CMD0时,CS必须为低电平,使得SD卡进入SPI模式。

④发送CMD8,检查是否支持SD2.0协议。

⑤根据不同协议检查SD卡(相关命令:CMD55CMD41CMD58CMD1等)。

⑥取消片选,发多8CLK,结束初始化 。

下图来自《SD卡2.0协议.pdf》这个文档。

下图是MiniSTM插入卡座 

 

 正点原子提供了SD卡驱动代码

1. SD_Initialize 函数讲解
2. SD_ReadDisk 函数讲解
3. SD_WriteDisk 函数讲解
4. SD_GetSectorCount 函数讲解

SD_Select函数主要用来选定SD卡

//选择sd卡,并且等待卡准备OK
//返回值:0,成功;1,失败;
u8 SD_Select(void)
{
	SD_CS=0;
	if(SD_WaitReady()==0)return 0;//等待成功
	SD_DisSelect();
	return 1;//等待失败
}

SD_SendCmd命令用来向SD卡发送命令,cmd——8位,arg——32位,crc——8位。 

//向SD卡发送一个命令
//输入: u8 cmd   命令 
//      u32 arg  命令参数
//      u8 crc   crc校验值	   
//返回值:SD卡返回的响应															  
u8 SD_SendCmd(u8 cmd, u32 arg, u8 crc)
{
    u8 r1;	
	u8 Retry=0; 
	SD_DisSelect();//取消上次片选
	if(SD_Select())return 0XFF;//片选失效 
	//发送
    SD_SPI_ReadWriteByte(cmd | 0x40);//分别写入命令
    SD_SPI_ReadWriteByte(arg >> 24);
    SD_SPI_ReadWriteByte(arg >> 16);
    SD_SPI_ReadWriteByte(arg >> 8);
    SD_SPI_ReadWriteByte(arg);	  
    SD_SPI_ReadWriteByte(crc); 
	if(cmd==CMD12)SD_SPI_ReadWriteByte(0xff);//Skip a stuff byte when stop reading
    //等待响应,或超时退出
	Retry=0X1F;
	do
	{
		r1=SD_SPI_ReadWriteByte(0xFF);
	}while((r1&0X80) && Retry--);	 
	//返回状态值
    return r1;
}		    															

SD卡的类型也被宏定义后放在了 MMC_SD.h头文件下面

其中SD_TYPE_ERR 表示SD卡类型无效,值为0

// SD卡类型定义  
#define SD_TYPE_ERR     0X00
#define SD_TYPE_MMC     0X01
#define SD_TYPE_V1      0X02
#define SD_TYPE_V2      0X04
#define SD_TYPE_V2HC    0X06	   

 SD卡初始化的时候需要低速模式,正常工作是高速模式。可以设置为4分频。

//SD卡初始化的时候,需要低速
void SD_SPI_SpeedLow(void)
{
 	SPI1_SetSpeed(SPI_BaudRatePrescaler_256);//设置到低速模式	
}
//SD卡正常工作的时候,可以高速了
void SD_SPI_SpeedHigh(void)
{
 	SPI1_SetSpeed(SPI_BaudRatePrescaler_2);//设置到高速模式	
}

2、SD卡读操作 

 SD_ReadDisk用来读取数据,cnt=1表示只读取一个扇区,否则是连续读取。

//读SD卡
//buf:数据缓存区
//sector:扇区
//cnt:扇区数
//返回值:0,ok;其他,失败.
u8 SD_ReadDisk(u8*buf,u32 sector,u8 cnt)
{
	u8 r1;
	if(SD_Type!=SD_TYPE_V2HC)sector <<= 9;//转换为字节地址
	if(cnt==1)
	{
		r1=SD_SendCmd(CMD17,sector,0X01);//读命令
		if(r1==0)//指令发送成功
		{
			r1=SD_RecvData(buf,512);//接收512个字节	   
		}
	}else
	{
		r1=SD_SendCmd(CMD18,sector,0X01);//连续读命令
		do
		{
			r1=SD_RecvData(buf,512);//接收512个字节	 
			buf+=512;  
		}while(--cnt && r1==0); 	
		SD_SendCmd(CMD12,0,0X01);	//发送停止命令
	}   
	SD_DisSelect();//取消片选
	return r1;//
}

if是单块数据块的读取,else是多块的读取。 

if(cnt==1)
else
	{

}

多块数据读取的最后我们要加上发送CMD12指令,结束数据块的读取。

SD_SendCmd(CMD12,0,0X01);	//发送停止命令

SD_GetResponse  用来等待SD卡返回想要的值,1表示返回成功,0表示失败。

//等待SD卡回应
//Response:要得到的回应值
//返回值:0,成功得到了该回应值
//    其他,得到回应值失败
u8 SD_GetResponse(u8 Response)
{
	u16 Count=0xFFFF;//等待次数	   						  
	while ((SD_SPI_ReadWriteByte(0XFF)!=Response)&&Count)Count--;//等待得到准确的回应  	  
	if (Count==0)return MSD_RESPONSE_FAILURE;//得到回应失败   
	else return MSD_RESPONSE_NO_ERROR;//正确回应
}

3、SD卡写操作 

 SD_WriteDisk是为了写入数据,同样也要先判断SD_Type的类型。

//写SD卡
//buf:数据缓存区
//sector:起始扇区
//cnt:扇区数
//返回值:0,ok;其他,失败.
u8 SD_WriteDisk(u8*buf,u32 sector,u8 cnt)
{
	u8 r1;
	if(SD_Type!=SD_TYPE_V2HC)sector *= 512;//转换为字节地址
	if(cnt==1)
	{
		r1=SD_SendCmd(CMD24,sector,0X01);//读命令
		if(r1==0)//指令发送成功
		{
			r1=SD_SendBlock(buf,0xFE);//写512个字节	   
		}
	}else
	{
		if(SD_Type!=SD_TYPE_MMC)
		{
			SD_SendCmd(CMD55,0,0X01);	
			SD_SendCmd(CMD23,cnt,0X01);//发送指令	
		}
 		r1=SD_SendCmd(CMD25,sector,0X01);//连续读命令
		if(r1==0)
		{
			do
			{
				r1=SD_SendBlock(buf,0xFC);//接收512个字节	 
				buf+=512;  
			}while(--cnt && r1==0);
			r1=SD_SendBlock(0,0xFD);//接收512个字节 
		}
	}   
	SD_DisSelect();//取消片选
	return r1;//
}	

SD_GetSectorCount可以得到SD卡的总扇区数量,对于V2.0版本以后的SD卡是固定512Byte(即一个sector)大小。

//获取SD卡的总扇区数(扇区数)   
//返回值:0: 取容量出错 
//       其他:SD卡的容量(扇区数/512字节)
//每扇区的字节数必为512,因为如果不是512,则初始化不能通过.														  
u32 SD_GetSectorCount(void)
{
    u8 csd[16];
    u32 Capacity;  
    u8 n;
	u16 csize;  					    
	//取CSD信息,如果期间出错,返回0
    if(SD_GetCSD(csd)!=0) return 0;	    
    //如果为SDHC卡,按照下面方式计算
    if((csd[0]&0xC0)==0x40)	 //V2.00的卡
    {	
		csize = csd[9] + ((u16)csd[8] << 8) + 1;
		Capacity = (u32)csize << 10;//得到扇区数	 		   
    }else//V1.XX的卡
    {	
		n = (csd[5] & 15) + ((csd[10] & 128) >> 7) + ((csd[9] & 3) << 1) + 2;
		csize = (csd[8] >> 6) + ((u16)csd[7] << 2) + ((u16)(csd[6] & 3) << 10) + 1;
		Capacity= (u32)csize << (n - 9);//得到扇区数   
    }
    return Capacity;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/110494.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

敏捷价值流管理

对团队或企业来说&#xff0c;敏捷能够通过快速迭代、改进来更好地为客户或终端用户交付价值。但有些团队在引入敏捷项目管理模式之后&#xff0c;团队管理层看了看埋头工作的团队&#xff0c;“唉&#xff1f;团队的效率好像并没有提升啊&#xff0c;这不和以前一样吗……”在…

怎样给黑白照片上色?2个技能教你如何给黑白照片上色

大家看过长辈的黑白照片吗&#xff1f;最近我的爷爷翻出了几十年前的老照片&#xff0c;给我细细道来每张照片背后的故事。可惜那个年代的技术水平有限&#xff0c;没办法拍出好看的彩色照片。如今照片修复技术层层递进&#xff0c;我想借助一些图片处理软件&#xff0c;将这些…

Qt QCustomPlot 添加多个坐标系区域

Qt QCustomPlot 添加多个坐标系区域 文章目录Qt QCustomPlot 添加多个坐标系区域摘要1 新建多个坐标系QCPAxisQCPAxisRectQCPLayoutGrid2 多个坐标轴如何更新数据添加数据3 遇到的问题最后关键字&#xff1a; Debian、 Linux、 QCustomPlot、 Qt、 QCPAxisRect内容背景&#xf…

vue3的中间值思维

在用vue框架的开发的时候&#xff0c;经常使用到的一种中间值思维&#xff0c;什么是中间值思维&#xff0c;就是通过一个间接的属性去改变需要渲染的值 我们在传值的时候&#xff0c;如果是用的mitt传值&#xff0c;那传过来的值就是在bus.on函数中&#xff0c;我们就得取出来…

消息中间件RocketMQ快速入门

目录前言消息中间件需要解决哪些问题&#xff1f;Publish/SubscribeMessage PriorityMessage FilterBroker端消息过滤Consumer端消息过滤Message Persistence消息可靠性低延迟消息回溯消费消息堆积定时消息消息重试RocketMQ 物理部署结构RocketMQ 逻辑部署结构RocketMQ 数据存储…

Scala 基础函数

1.前言 为什么要学习Scala 分布式高并发语言Go、R、Erlang等等为何选择Scala&#xff1f; Spark是大数据处理的核心方式&#xff0c;用scala语言编写&#xff01; Kafka分布式发布订阅消息系统&#xff0c;由LinkedIn捐给Apache&#xff0c;以极高的吞吐量著称&#xff0c;是…

人工智能-seaborn单双多变量绘图、两案例:NBA球员数据分析、北京租房数据统

1、 seaborn 作用&#xff1a;更高效地绘图 #安装 pip3 install seaborn#导入 import seaborn as sns单变量&#xff1a;直方图或核密度曲线 双变量&#xff1a;散点图、二维直方图、 主要函数&#xff1a;distplot()与joinplot()函数 1.1 单变量绘图 API import seabor…

cookie, session,redis全解析

cookie session redis 一. 前言 最近在学习node的过程中对于cookie&#xff0c;session&#xff0c;redis有了和之前不一样的理解&#xff0c;记录一下之前不了解的知识点。二.cookie的重点概念 存储在客户端浏览器中的字符串&#xff0c;最大5kb跨域不共享&#xff0c;每一个…

限定城市|临床医生自费赴日本大阪公立大学医学院访学观摩

X医生拟自费访学&#xff0c;目标是日本大阪都市圈&#xff0c;包括大阪、京都、奈良、神户等&#xff0c;优先考虑大阪市及京都市。最终我们申请到大阪公立大学医学院&#xff0c;对方在一周内连续发来两封邀请函&#xff0c;以便于X医生办理护照及单位的审批手续。对于首次办…

Zabbix与乐维监控对比分析(五)——可视化篇

前面我们详细介绍了Zabbix与乐维监控的架构与性能、Agent管理、自动发现、权限管理、对象管理、告警管理方面的对比分析&#xff0c;相信大家对二者的对比分析有了相对深入的了解&#xff0c;接下来我们将对二者的可视化功能进行对比分析。可视化是当代IT监控的一个创举&#x…

java+ssh+mysql客户关系管理系统

项目介绍&#xff1a; 本系统为基于jspsshmysql的客户关系管理系统&#xff0c;系统实现了权限自动化&#xff0c;可以自由创建角色&#xff0c;并为每个角色赋予权限&#xff0c;全部功能如下&#xff1a; 1.我的桌面&#xff1a;列出了一些办公常用快捷方式 2.信息中心&am…

CSDN第17次竞赛题解与总结

前言 临近期末考&#xff0c;博主时间较少&#xff0c;本文质量可能不高&#xff0c;请见谅。 2022/12/21 19:00~21:00 CSDN第17次竞赛开考 本场竞赛由「清华大学出版社 & CSDN」联合主办。 《算法竞赛》 本书解析了算法竞赛考核的数据结构、算法&#xff1b;组织了每个…

Python基础库及机器学习笔记

1.介绍 本节将主要介绍Python中的常用第三方库。这些库都是实现了各种计算功能的开源库&#xff0c;它们极大地丰富了Python的应用场景和计算能力&#xff0c;这里主要介绍NumPy、pandas和Matplotlib三个库的基础使用。其中NumPy是Python用来进行矩阵运算、高维度数组运算的数…

jQuery Ajax

文章目录jQuery Ajax概述load()简单使用加载部分内容传递数据回调函数$.get()$.post()$.getJSON()$.getScript()jQuery Ajax 概述 Ajax&#xff0c;全称“Asynchronous JavaScript and XML”&#xff0c;即“异步的JavaScript和XML”。其核心是通过JavaScript的XMLHttpReques…

分布式开源工作流引擎有什么特点?

在竞争越来越激烈的社会中&#xff0c;拥有提质增效的办公软件&#xff0c;可以为企业带来更可观的市场价值。分布式开源工作流引擎在企业数字化发展进程中深受欢迎&#xff0c;在帮助企业提升办公效率上发挥了重要的作用。今天&#xff0c;我们就一起里盘点下分布式开源工作流…

【轻松掌握C语言】程序环境和预处理

目录 一、程序的翻译和执行环境 1、翻译环境 2、执行环境 二、预处理详解 1、预定义符号 2、#define 3、#undef 4、命令行定义 5、条件编译 6、文件包含 一、程序的翻译和执行环境 1、翻译环境&#xff0c;在这个环境中源代码被转换为可执行的机器指令。 2、执行环境&#xff0…

笔记本怎么录制屏幕?只需2分钟,快速学会

如今&#xff0c;大多数人会在笔记本电脑上使用屏幕录制功能&#xff0c;如&#xff1a;在线直播课程、在线会议、电影和电视剧等场景。笔记本怎么录制屏幕&#xff1f;事实上&#xff0c;用电脑录制视频并不像你想象的那么困难。我们每天使用的电脑都有自己的屏幕录制功能&…

高性能数据分析时代,HPDA平台需要什么样的数据存储?

在海量基因数据中进行全基因数据分析&#xff0c;了解各种疾病与DNA之间的隐秘联系&#xff1b;对海洋气候进行预测&#xff0c;利用强大的数据分析性能&#xff0c;实现分钟级的数据刷新、精准预测海洋气候&#xff1b;利用高速相机模拟人脑上亿个神经元之间联接与工作&#x…

善康医药冲刺科创板上市:计划募资13亿元,上半年亏损5000万元

近日&#xff0c;深圳善康医药科技股份有限公司&#xff08;下称“善康医药”&#xff09;在上海证券交易所递交招股书&#xff0c;准备在科创板上市。本次冲刺上市&#xff0c;善康医药计划募资13.27亿元&#xff0c;将用于新药研发项目、创新药高端制剂生产基地建设项目、营销…

redis学习第二天

Redis事务 Redis事务是一个单独的隔离操作&#xff1a;事务中的所有命令都会序列化、按顺序地执行。事务在执行的过程中&#xff0c;不会被其他客户端发送来的命令插队。 Redis事务的主要作用就是串联多个命令防止别的命令插队。 Multi、Exec、discard 从输入Multi命令开始、…