ARM开发板实现24位BMP图片缩放

ARM开发板实现24位BMP图片缩放

一、linux平台bmp图片缩放

最近想在ARM开发板实现BMP图片的缩放,查看了一些资料,大家部分理论知识可参考:
akynazh博主 ,这位博主程序以window平台为主进行显示,发现在linux平台下编译时有些错误,经过疯狂的修改好,终于能在linux下运行,并实现了缩放。

先放代码吧,代码就看注释了,代码名字:test.c

#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>// 文件头
struct tagBITMAPFILEHEADER {unsigned short bfType;	  //// 保存图片类型,读取时需要注释掉,文本标识符只能单独进行读写unsigned int bfSize;         // 文件大小unsigned short bfReserved1;  // 保留,设置为0unsigned short bfReserved2;  // 保留,设置为0unsigned int   bfOffBits;  // 从文件头到实际的图像数据之间的字节的偏移量(没调色板的话是54)
} __attribute__((packed));
// 信息头
struct tagBITMAPINFOHEADER {unsigned int biSize;      // 此结构体的大小unsigned int biWidth;     // 图像的宽unsigned int biHeight;    // 图像的高unsigned short biPlanes;  // 颜色平面数 恒为1unsigned short biBitCount;  // 一像素所占的位数 Windows系统有8,16,24unsigned int biCompression;  // 说明图象数据压缩的类型,0为不压缩unsigned int biSizeImage;  // 图像大小, 值等于上面文件头结构中bfSize-bfOffBitsint biXPelsPerMeter;  // 说明水平分辨率,用像素/米表示 一般为0int biYPelsPerMeter;  // 说明垂直分辨率,用像素/米表示 一般为0unsigned int biClrUsed;  // 说明位图实际使用的彩色表中的颜色索引数(设为0的话,则说明使用所有调色板项)unsigned int biClrImportant;  // 说明对图象显示有重要影响的颜色索引的数目// 如果是0表示都重要
} __attribute__((packed));
// 调色板
struct tagRGBQUAND {unsigned char r;unsigned char g;unsigned char b;unsigned char rgbReserved;
} __attribute__((packed));int main(int argc, char *argv[]) 
{// 打开图片char *oldPhoto = argv[1], *newPhoto = argv[3];FILE *fp1 = fopen(oldPhoto, "r+");double pzoom = atof(argv[2]);printf("pzoom:%f\n", pzoom);if (fp1 == NULL ) {printf("Opening photos failed!\n");if (fp1 == NULL) fclose(fp1);return -1;}// 单独读取bmp图片文本标识符0x4d42unsigned short fileType;fread(&fileType, sizeof(unsigned short), 1, fp1);if (fileType != 0x4d42) {  // 如果不是的话证明不是bmp图片printf("The photo is not of bmp type!\n");return -1;}fseek(fp1, 0, SEEK_SET);// 读取原图信息struct tagBITMAPFILEHEADER fileHeader;  // 原图文件头struct tagBITMAPINFOHEADER infoHeader;  // 原图消息头fread(&fileHeader, sizeof(struct tagBITMAPFILEHEADER), 1, fp1);fread(&infoHeader, sizeof(struct tagBITMAPINFOHEADER), 1, fp1);int byte = infoHeader.biBitCount / 8;  // 每个像素的字节数struct tagRGBQUAND *palette = (struct tagRGBQUAND *)malloc((int)pow(2, infoHeader.biBitCount) *4);  // 分配调色板空间if (infoHeader.biBitCount != 24)  // 如果是24位图的没有调色板fread(palette, sizeof(struct tagRGBQUAND), (int)pow(2, infoHeader.biBitCount),fp1);// 得到原图宽高和修改后的宽高unsigned int oldWidth, oldHeight, newWidth, newHeight;oldWidth = infoHeader.biWidth;oldHeight = infoHeader.biHeight;printf("Oldphoto's height:%d\n", oldHeight);printf("Oldphoto's width:%d\n", oldWidth);// 图像显示不出来原因在于图像长或宽不是4的倍数// 下面这一步可以保证得到的宽高是4的倍数newHeight = ((int)(oldHeight * pzoom) + 3) / 4 * 4;newWidth = ((int)(oldWidth * pzoom) + 3) / 4 * 4;//newHeight = (int)(oldHeight * pzoom);//newWidth = (int)(oldWidth * pzoom);printf("Newphoto's height:%d\n", newHeight);printf("Newphoto's width:%d\n", newWidth);unsigned int oldsize = oldWidth * oldHeight * byte,  //byte = 3newsize = newWidth * newHeight * byte;// 获取原图位图数据unsigned char *sourceData = (unsigned char *)malloc(oldsize);if (infoHeader.biBitCount == 24) {  // 无调色板时fseek(fp1, 54, SEEK_SET);  // 文件指针指向文件的第54个字节fread(sourceData, oldsize, 1, fp1);} else if (infoHeader.biBitCount ==8) {  // 有调色板是要加上分配调色板所需要的空间fseek(fp1, 1078, SEEK_SET);  // 文件指针指向文件的第54+2^8*4=1078个字节fread(sourceData, oldsize, 1, fp1);}// 修改两个header的数据并把修改后的header(及调色板信息)写入新图片中infoHeader.biWidth = newWidth;infoHeader.biHeight = newHeight;if (infoHeader.biBitCount == 24) {fileHeader.bfSize = 54 + newsize;infoHeader.biSizeImage = newsize;printf("fileHeader.bfSize:%#x\n", fileHeader.bfSize);} else if (infoHeader.biBitCount == 8) {fileHeader.bfSize = 1078 + newsize;infoHeader.biSizeImage = newsize;}FILE *fp2 = fopen(newPhoto, "w+");	fseek(fp2, 0, SEEK_SET);// fwrite(&fileType, sizeof(unsigned short), 1, fp2);fwrite(&fileHeader, sizeof(struct tagBITMAPFILEHEADER), 1, fp2);fwrite(&infoHeader, sizeof(struct tagBITMAPINFOHEADER), 1, fp2);if (infoHeader.biBitCount != 24){fwrite(palette, sizeof(struct tagRGBQUAND), pow(2, infoHeader.biBitCount), fp2);printf("error\n");}// 使用双线性差值法进行图片缩放double p, q;unsigned int x1, y1, x2, y2;  // 原图所在像素点的宽高unsigned int X, Y;unsigned char *pDestination;  // 修改像素的位置(即字节偏移量)unsigned char a, b, c;unsigned char *pSource1=&a, *pSource2=&b;  // 获取像素的位置(即字节偏移量)unsigned char *destinationData =(unsigned char *)malloc(newsize);  // 开好新图片的位图数据所需空间for (Y = 0; Y < newHeight; Y++) {y1 = Y / pzoom;y2 = Y / pzoom + 1;q = Y / pzoom - y1;pDestination = destinationData + Y * newWidth * byte;pSource1 = sourceData + y1 * oldWidth * byte;pSource2 = sourceData + y2 * oldWidth * byte;for (X = 0; X < newWidth; X++) {x1 = X / pzoom;x2 = X / pzoom + 1;p = X / pzoom - x1;if (byte == 3) {*(pDestination + X * byte) =*(pSource1 + x1 * byte) * (1 - p) * (1 - q) +*(pSource1 + x2 * byte) * p * (1 - q) +*(pSource2 + x1 * byte) * (1 - p) * q +*(pSource2 + x2 * byte) * p * q;*(pDestination + X * byte + 1) =*(pSource1 + x1 * byte + 1) * (1 - p) * (1 - q) +*(pSource1 + x2 * byte + 1) * p * (1 - q) +*(pSource2 + x1 * byte + 1) * (1 - p) * q +*(pSource2 + x2 * byte + 1) * p * q;*(pDestination + X * byte + 2) =*(pSource1 + x1 * byte + 2) * (1 - p) * (1 - q) +*(pSource1 + x2 * byte + 2) * p * (1 - q) +*(pSource2 + x1 * byte + 2) * (1 - p) * q +*(pSource2 + x2 * byte + 2) * p * q;} else if (byte == 1) {*(pDestination + X * byte) =*(pSource1 + x1 * byte) * (1 - p) * (1 - q) +*(pSource1 + x2 * byte) * p * (1 - q) +*(pSource2 + x1 * byte) * (1 - p) * q +*(pSource2 + x2 * byte) * p * q;}}}// 将位图数据写入新的图片并进行后续处理fwrite(destinationData, newsize, 1, fp2);printf("success!\n");free(destinationData);free(sourceData);free(palette);fclose(fp1);fclose(fp2);return 0;
}

编译时记得加上链接上数学库,编译如下:

gcc test.c -o test -lm

执行

./test aa.bmp 1.5 bb.bmp

aa.bmp:原图
1.5:放大1.5位
bb.生成的新图

原图
在这里插入图片描述
放大1.5倍
在这里插入图片描述

二、ARM开板显示bmp图片缩放

功能实现:通过点击Y轴坐标,实现(0.1~1倍的缩放),想要实现缩放,先了解硬件平台信息
屏幕坐标:800480
触摸屏坐标:1024
600

接上来放一张800*480的24位bmp图片。
在这里插入图片描述
代码部分加入了触摸屏,事个程序做了较大的改变,代码proiect.c如下

#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <linux/input.h>
#include <unistd.h>#define LCD_PATH  "/dev/fb0" //屏幕文件#define TS_PATH  "/dev/input/event0"  //触摸屏文件unsigned char *mmap_p;
int lcd_fd;
int ts_fd;// 文件头
struct tagBITMAPFILEHEADER {unsigned short bfType;	  //// 保存图片类型,读取时需要注释掉,文本标识符只能单独进行读写unsigned int bfSize;         // 文件大小unsigned short bfReserved1;  // 保留,设置为0unsigned short bfReserved2;  // 保留,设置为0unsigned int   bfOffBits;  // 从文件头到实际的图像数据之间的字节的偏移量(没调色板的话是54)
} __attribute__((packed));
// 信息头
struct tagBITMAPINFOHEADER {unsigned int biSize;      // 此结构体的大小unsigned int biWidth;     // 图像的宽unsigned int biHeight;    // 图像的高unsigned short biPlanes;  // 颜色平面数 恒为1unsigned short biBitCount;  // 一像素所占的位数 Windows系统有8,16,24unsigned int biCompression;  // 说明图象数据压缩的类型,0为不压缩unsigned int biSizeImage;  // 图像大小, 值等于上面文件头结构中bfSize-bfOffBitsint biXPelsPerMeter;  // 说明水平分辨率,用像素/米表示 一般为0int biYPelsPerMeter;  // 说明垂直分辨率,用像素/米表示 一般为0unsigned int biClrUsed;  // 说明位图实际使用的彩色表中的颜色索引数(设为0的话,则说明使用所有调色板项)unsigned int biClrImportant;  // 说明对图象显示有重要影响的颜色索引的数目// 如果是0表示都重要
} __attribute__((packed));
// 调色板
struct tagRGBQUAND {unsigned char r;unsigned char g;unsigned char b;unsigned char rgbReserved;
} __attribute__((packed));void Lcd_Init(void);
void Lcd_Uninit(void);
void TS_Init(void);
void TS_UnInit(void);
void Get_XY(int *X, int *Y);
void Show_bmp(const char *pathname);void Lcd_Init(void)
{lcd_fd = open(LCD_PATH, O_RDWR);if(lcd_fd == -1){printf("open lcd failure\n");}//lcd映射mmap_p = (unsigned char *)mmap(NULL,800*480*4, PROT_READ|PROT_WRITE, MAP_SHARED, lcd_fd, 0);if(mmap == MAP_FAILED){printf("mmap failure\n");close(lcd_fd);return ;}
}
void Lcd_Uninit(void)
{//撤消映射munmap(mmap_p, 800*480*4);close(lcd_fd);
}void TS_Init(void)
{ts_fd = open(TS_PATH, O_RDWR);if(ts_fd == -1){printf("open ts failure\n");}	}void TS_UnInit(void)
{close(ts_fd);}int main(int argc, char *argv[]) 
{Lcd_Init();TS_Init();//24位bmp格式图片。Show_bmp("aa.bmp");Lcd_Uninit();TS_UnInit();return 0;
}void Get_XY(int *X, int *Y)
{int xx, yy;struct input_event ts;//松开触摸后,再打印while (1){read(ts_fd, &ts, sizeof(struct input_event));//判断类型if(ts.type == EV_ABS && ts.code == ABS_X){xx = ts.value;}if(ts.type == EV_ABS && ts.code == ABS_Y){yy = ts.value;}//判断按下if(ts.type == EV_KEY && ts.code ==  BTN_TOUCH && ts.value == 1){}	//判断是否松开if(ts.type == EV_KEY && ts.code ==  BTN_TOUCH && ts.value == 0){//开发板坐标为800*480, 点击时得到的坐标是:1024*600,所以按比例做了缩放																			*X = xx*(800.0/1024.0);      *Y = yy*(480.0/600.0);break;}           }printf("X:%d, Y:%d\n", *X, *Y);	}void Show_bmp(const char *pathname)
{int XX, YY; //X与Y轴坐标// 打开图片FILE *fp1 = fopen(pathname, "r+");if (fp1 == NULL ) {printf("Opening photos failed!\n");if (fp1 == NULL) fclose(fp1);return ;}// 单独读取bmp图片文本标识符0x4d42unsigned short fileType;fread(&fileType, sizeof(unsigned short), 1, fp1);if (fileType != 0x4d42) {  // 如果不是的话证明不是bmp图片printf("The photo is not of bmp type!\n");return ;}fseek(fp1, 0, SEEK_SET);// 读取原图信息struct tagBITMAPFILEHEADER fileHeader;  // 原图文件头struct tagBITMAPINFOHEADER infoHeader;  // 原图消息头fread(&fileHeader, sizeof(struct tagBITMAPFILEHEADER), 1, fp1);fread(&infoHeader, sizeof(struct tagBITMAPINFOHEADER), 1, fp1);int byte = infoHeader.biBitCount / 8;  // 每个像素的字节数struct tagRGBQUAND *palette = (struct tagRGBQUAND *)malloc((int)pow(2, infoHeader.biBitCount) *4);  // 分配调色板空间if (infoHeader.biBitCount != 24)  // 如果是24位图的没有调色板fread(palette, sizeof(struct tagRGBQUAND), (int)pow(2, infoHeader.biBitCount),fp1);// 得到原图宽高和修改后的宽高unsigned int oldWidth, oldHeight, newWidth, newHeight;oldWidth = infoHeader.biWidth;oldHeight = infoHeader.biHeight;printf("Oldphoto's height:%d\n", oldHeight);printf("Oldphoto's width:%d\n", oldWidth);unsigned int oldsize = oldWidth * oldHeight * byte,  //byte = 3newsize = newWidth * newHeight * byte;	// 获取原图位图数据unsigned char *sourceData = (unsigned char *)malloc(oldsize);if (infoHeader.biBitCount == 24) {  // 无调色板时fseek(fp1, 54, SEEK_SET);  // 文件指针指向文件的第54个字节fread(sourceData, oldsize, 1, fp1);} else if (infoHeader.biBitCount ==8) {  // 有调色板是要加上分配调色板所需要的空间fseek(fp1, 1078, SEEK_SET);  // 文件指针指向文件的第54+2^8*4=1078个字节fread(sourceData, oldsize, 1, fp1);}//unsigned char *destinationData;  // 开好新图片的位图数据所需空间	while(1){//获取坐标Get_XY(&XX, &YY);//先黑屏for(int i=0; i<800*480; i++){mmap_p[4*i+0] = 0x00;mmap_p[4*i+1] = 0x00;mmap_p[4*i+2] = 0x00;}//点击右上角,退出图片绽放if(XX > 700 && XX<800 && YY>0 && YY<100)break;//计算放大倍数,以YY轴坐标做为倍数,y轴坐标:0~480//由于暂定设置的图片全屏,所以图片只能设置为缩小显示,编放比例:double pzoom = YY/480.0;printf("点击后的Y轴坐标:%d, 放大的倍:%0.1f\n", YY, pzoom);if(pzoom < 0.1)pzoom = 0.1; //最低缩小为0.1倍// 图像显示不出来原因在于图像长或宽不是4的倍数// 下面这一步可以保证得到的宽高是4的倍数newHeight = ((int)(oldHeight * pzoom) + 3) / 4 * 4;newWidth = ((int)(oldWidth * pzoom) + 3) / 4 * 4;int start_x = (800-newWidth)/2;int start_y = (480-newHeight)/2;printf("start_x:%d\n", start_x);printf("start_y:%d\n", start_y);//newHeight = (int)(oldHeight * pzoom);//newWidth = (int)(oldWidth * pzoom);printf("Newphoto's height:%d\n", newHeight);printf("Newphoto's width:%d\n", newWidth);unsigned int oldsize = oldWidth * oldHeight * byte;  //byte = 3newsize = newWidth * newHeight * byte;// 使用双线性差值法进行图片缩放double p, q;unsigned int x1, y1, x2, y2;  // 原图所在像素点的宽高unsigned int X, Y;unsigned char a, b, c;unsigned char *pDestination = &a;  // 修改像素的位置(即字节偏移量)unsigned char *pSource1 = &b, *pSource2 = &c;  // 获取像素的位置(即字节偏移量)//destinationData = (unsigned char *)malloc(newsize);  // 开好新图片的位图数据所需空间	unsigned char destinationData[newsize];printf("newsize:%d\n", newsize);for (Y = 0; Y < newHeight; Y++) {y1 = Y / pzoom;y2 = Y / pzoom + 1;q = Y / pzoom - y1;pDestination = destinationData + Y * newWidth * byte;pSource1 = sourceData + y1 * oldWidth * byte;pSource2 = sourceData + y2 * oldWidth * byte;for (X = 0; X < newWidth; X++) {x1 = X / pzoom;x2 = X / pzoom + 1;p = X / pzoom - x1;if (byte == 3) {*(pDestination + X * byte) =*(pSource1 + x1 * byte) * (1 - p) * (1 - q) +*(pSource1 + x2 * byte) * p * (1 - q) +*(pSource2 + x1 * byte) * (1 - p) * q +*(pSource2 + x2 * byte) * p * q;*(pDestination + X * byte + 1) =*(pSource1 + x1 * byte + 1) * (1 - p) * (1 - q) +*(pSource1 + x2 * byte + 1) * p * (1 - q) +*(pSource2 + x1 * byte + 1) * (1 - p) * q +*(pSource2 + x2 * byte + 1) * p * q;*(pDestination + X * byte + 2) =*(pSource1 + x1 * byte + 2) * (1 - p) * (1 - q) +*(pSource1 + x2 * byte + 2) * p * (1 - q) +*(pSource2 + x1 * byte + 2) * (1 - p) * q +*(pSource2 + x2 * byte + 2) * p * q;} else if (byte == 1) {*(pDestination + X * byte) =*(pSource1 + x1 * byte) * (1 - p) * (1 - q) +*(pSource1 + x2 * byte) * p * (1 - q) +*(pSource2 + x1 * byte) * (1 - p) * q +*(pSource2 + x2 * byte) * p * q;}}}printf("zoom finish\n");for(int yyy=0; yyy<newHeight; yyy++){for(int xxx=0; xxx<newWidth; xxx++){//mmap_p[(start_y+y)*800+start_x+x] = buff[(high-y)*width+x];mmap_p[(start_y+yyy)*800*4 + 4*start_x+4*xxx + 0] = destinationData[(newHeight-1-yyy)*newWidth*3+3*xxx+2];mmap_p[(start_y+yyy)*800*4 + 4*start_x+4*xxx + 1] = destinationData[(newHeight-1-yyy)*newWidth*3+3*xxx+1];mmap_p[(start_y+yyy)*800*4 + 4*start_x+4*xxx + 2] = destinationData[(newHeight-1-yyy)*newWidth*3+3*xxx+0];}}}// free(destinationData);free(sourceData);free(palette);fclose(fp1);}

三、验证

0.4倍缩放效果
在这里插入图片描述

在这里插入图片描述
缩放0.8倍效果
在这里插入图片描述

在这里插入图片描述
就写到这里吧,程序由于要先刷新黑屏再显示图片,看起来不是很流畅,需要加入帧缓冲与多线程协同处理可解决问题。如果需要的这种写的话,看评论来吧,多了就写下。

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

云手机在海外电商中的应用优势

随着海外市场的不断拓展&#xff0c;电商行业对于高效、安全的工具需求日益增长。在这一背景下&#xff0c;云手机作为一种新型服务&#xff0c;为海外电商提供了强大的支持和便利。云手机对传统物理手机起到了非常好的延展和补充作用&#xff0c;拓展了更广泛的应用场景&#…

【滑动窗口、矩阵】算法例题

目录 三、滑动窗口 30. 长度最小的子数组 ② 31. 无重复字符的最长子串 ② 32. 串联所有单词的子串 ③ 33. 最小覆盖子串 ③ 四、矩阵 34. 有效的数独 ② 35. 螺旋矩阵 ② 36. 旋转图像 ② 37. 矩阵置零 ② 38. 生命游戏 ② 三、滑动窗口 30. 长度最小的子数组 ② 给…

备战蓝桥杯---牛客寒假训练营2VP

题挺好的&#xff0c;收获了许多 1.暴力枚举&#xff08;许多巧妙地处理细节方法&#xff09; n是1--9,于是我们可以直接暴力&#xff0c;对于1注意特判开头0但N&#xff01;1&#xff0c;对于情报4&#xff0c;我们可以把a,b,c,d的所有取值枚举一遍&#xff0c;那么如何判断有…

低功耗设计

前面已经介绍过低功耗相关概念【IC】低功耗设计理论知识&#xff0c;这里主要分享下RTL级的常用低功耗设计&#xff0c;欢迎讨论交流。 一、时钟门控clock gating 毫无疑问&#xff0c;时钟门控是前端设计中最有效的低功耗设计。 时钟门控的基本思想是在寄存器不工作的时候&am…

NLP---Bert分词

目录&#xff1a; Q&#xff1a;bert分词步骤1&#xff1a;构建N * N 的相关性矩阵&#xff0c;计算相邻两个字的相关性&#xff0c;低的话&#xff08;<阈值&#xff09;就切割。2&#xff1a;将A词进行mask计算出A的embedding&#xff0c;然后将AB两个词一起mask&#xff…

微信小程序的配置文件使用说明:

在上一文中学习开发小程序的起航日记&#xff0c;我们准备好了开发小程序时所需的环境和准备工作&#xff0c;同时也简单的了解了一下小程序的项目结构组成。 这一章&#xff0c;我们主要对小程序的配置文件进行学习。 文章目录 小程序_配置文件1.json2.app.jsonpages 属性wind…

springboot283图书商城管理系统

图书商城管理系统 摘 要 现代经济快节奏发展以及不断完善升级的信息化技术&#xff0c;让传统数据信息的管理升级为软件存储&#xff0c;归纳&#xff0c;集中处理数据信息的管理方式。本图书商城管理系统就是在这样的大环境下诞生&#xff0c;其可以帮助管理者在短时间内处理…

【linux】Debian访问Debian上的共享目录

要在Debian系统上访问共享目录&#xff0c;通常意味着要访问通过网络共享的文件夹&#xff0c;比如通过SMB/CIFS&#xff08;Server Message Block/Common Internet File System&#xff09;协议共享的Windows共享文件夹。以下是访问共享目录的步骤&#xff1a; 1. 安装必要的…

MyBatis记录

目录 什么是MyBatis MyBatis的优点和缺点 #{}和${}的区别 Mybatis是如何进行分页的&#xff0c;分页插件的原理 Mybatis是如何将sql执行结果封装为目标对象并返回的 MyBatis实现一对一有几种方式 Mybatis设计模式 什么是MyBatis &#xff08;1&#xff09;Mybatis是一个…

[Qt学习笔记]QT下获取Halcon图形窗口鼠标事件并执行相应操作

目录 1、背景2、参考信息3、目标4、步骤4.1 Halcon库的配置4.2 读取图像&#xff0c;并实现图像自适应窗体控件大小4.3 主要的图形绘制和贴图操作见如下代码&#xff0c;其中重点为全局函数的创建来实现选择Select、拖拽Drag和尺寸Resize事件响应。 5、总结 1、背景 在视觉项目…

【SpringSecurity】十三、基于Session实现授权认证

文章目录 1、基于session的认证2、Demosession实现认证session实现授权 1、基于session的认证 流程&#xff1a; 用户认证成功后&#xff0c;服务端生成用户数据保存在session中服务端返回给客户端session id (sid&#xff09;&#xff0c;被客户端存到自己的cookie中客户端下…

k8s详细教程

Kubernetes详细教程 1. Kubernetes介绍 1.1 应用部署方式演变 在部署应用程序的方式上&#xff0c;主要经历了三个时代&#xff1a; 传统部署&#xff1a;互联网早期&#xff0c;会直接将应用程序部署在物理机上 优点&#xff1a;简单&#xff0c;不需要其它技术的参与 缺点…

4.线性数据结构——3.栈及例题

标准库的栈 定义&#xff1a;stack<typename> myStack;大小&#xff1a;size()压栈&#xff1a;push()弹栈&#xff1a;pop()栈顶&#xff1a;top()判空&#xff1a;empty() #include <cstdio> #include <string> #include <map> #include <algor…

HarmonyOS NEXT应用开发之搜索页一镜到底案例

介绍 本示例介绍使用bindContentCover、transition、animateTo实现一镜到底转场动画&#xff0c;常用于首页搜索框点击进入搜索页场景。 效果图预览 使用说明 点击首页搜索框跳转到搜索页面显式一镜到底转场动画 实现思路 通过点击首页搜索框改变bindContentCover全屏模态…

大数据面试题 —— HBase

目录 什么是HBase简述HBase 的数据模型HBase 的读写流程HBase 在写的过程中的region的split的时机HBase 和 HDFS 各自的使用场景HBase 的存储结构HBase 中的热现象&#xff08;数据倾斜&#xff09;是怎么产生的&#xff0c;以及解决办法有哪些HBase rowkey的设计原则HBase 的列…

[Qt学习笔记]QGraphicsView实现背景的绘制和前景图像的绘制

1、介绍 Qt中使用QGraphicsScene重写drawBackGround绘制背景&#xff0c;就是使用自定义的Scene类来重写drawBackGround的函数来重新绘制背景&#xff0c;这里需要注意的是自定义的Scene类要继承QGraphicsScene类&#xff0c;因为drawBackGround是一个虚函数&#xff0c;相当于…

【鸿蒙系统】 ---Harmony 鸿蒙编译构建指导(一)

&#x1f48c; 所属专栏&#xff1a;【鸿蒙系统】 &#x1f600; 作  者&#xff1a;我是夜阑的狗&#x1f436; &#x1f680; 个人简介&#xff1a;一个正在努力学技术的CV工程师&#xff0c;专注基础和实战分享 &#xff0c;欢迎咨询&#xff01; &#x1f496; 欢…

【python】爬取杭州市二手房销售数据做数据分析【附源码】

一、背景 在数据分析和市场调研中&#xff0c;获取房地产数据是至关重要的一环。本文介绍了如何利用 Python 中的 requests、lxml 库以及 pandas 库&#xff0c;结合 XPath 解析网页信息&#xff0c;实现对链家网二手房销售数据的爬取&#xff0c;并将数据导出为 Excel 文件的过…

服务器端(Debian 12)配置jupyter与R 语言的融合

融合前&#xff1a; 服务器端Debian 12,域名&#xff1a;www.leyuxy.online 1.安装r-base #apt install r-base 2.进入R并安装IRkernel #R >install.packages(“IRkernel”) 3.通过jupyter notebook的Terminal执行&#xff1a; R >IRkernel::installspec() 报错 解决办…

Qt笔记 信号和槽

在Qt中&#xff0c;如何将两个对象进行关联&#xff0c;让一个对象发出信号&#xff0c;然后另外一个对象接收到信号后&#xff0c;执行该对象的一个方法&#xff0c;要实现这种方式&#xff0c;则需要使用到信号和槽机制。 信号&#xff1a; 信号一定是一个没有返回值的函数…