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

news2024/11/30 8:38:06

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;  // 保留,设置为0
    unsigned short bfReserved2;  // 保留,设置为0
    unsigned int   bfOffBits;  // 从文件头到实际的图像数据之间的字节的偏移量(没调色板的话是54)
} __attribute__((packed));
// 信息头
struct tagBITMAPINFOHEADER {
    unsigned int biSize;      // 此结构体的大小
    unsigned int biWidth;     // 图像的宽
    unsigned int biHeight;    // 图像的高
    unsigned short biPlanes;  // 颜色平面数 恒为1
	
    unsigned short biBitCount;  // 一像素所占的位数 Windows系统有8,16,24
    unsigned int biCompression;  // 说明图象数据压缩的类型,0为不压缩
    unsigned int biSizeImage;  // 图像大小, 值等于上面文件头结构中bfSize-bfOffBits
    int biXPelsPerMeter;  // 说明水平分辨率,用像素/米表示 一般为0
    int biYPelsPerMeter;  // 说明垂直分辨率,用像素/米表示 一般为0
    unsigned 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图片文本标识符0x4d42
    unsigned 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 = 3
                 newsize = 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;  // 保留,设置为0
    unsigned short bfReserved2;  // 保留,设置为0
    unsigned int   bfOffBits;  // 从文件头到实际的图像数据之间的字节的偏移量(没调色板的话是54)
} __attribute__((packed));
// 信息头
struct tagBITMAPINFOHEADER {
    unsigned int biSize;      // 此结构体的大小
    unsigned int biWidth;     // 图像的宽
    unsigned int biHeight;    // 图像的高
    unsigned short biPlanes;  // 颜色平面数 恒为1
	
    unsigned short biBitCount;  // 一像素所占的位数 Windows系统有8,16,24
    unsigned int biCompression;  // 说明图象数据压缩的类型,0为不压缩
    unsigned int biSizeImage;  // 图像大小, 值等于上面文件头结构中bfSize-bfOffBits
    int biXPelsPerMeter;  // 说明水平分辨率,用像素/米表示 一般为0
    int biYPelsPerMeter;  // 说明垂直分辨率,用像素/米表示 一般为0
    unsigned 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图片文本标识符0x4d42
    unsigned 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 = 3
                 newsize = 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 = 3
                newsize = 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.coloradmin.cn/o/1529550.html

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

相关文章

【Leetcode】1793. 好子数组的最大分数

文章目录 题目思路代码复杂度分析时间复杂度空间复杂度 结果总结 题目 题目链接&#x1f517; 给你一个整数数组 n u m s nums nums &#xff08;下标从 0 0 0 开始&#xff09;和一个整数 k k k 。 一个子数组 ( i , j ) (i, j) (i,j) 的 分数 定义为 m i n ( n u m s …

Livox激光雷达 mid360 跑 fastlio2 - 流程记录

mid360 跑 fastlio2 一、配置 mid360 环境1.1、主机配置静态IP为192.168.1.501.2、Livox-SDK21.3、Livox_ros_driver2二、Fast-lio22.1、下载源码2.2、修改代码2.3、编译、运行 提示一下&#xff0c;如果在一些板上&#xff08;比如rk3399&#xff0c;或者是树莓派 &#xff0…

蓝桥杯java组 螺旋折线

题目描述 如图所示的螺旋折线经过平面上所有整点恰好一次。 对于整点(X, Y)&#xff0c;我们定义它到原点的距离dis(X, Y)是从原点到(X, Y)的螺旋折线段的长度。 例如dis(0, 1)3, dis(-2, -1)9 给出整点坐标(X, Y)&#xff0c;你能计算出dis(X, Y)吗&#xff1f; 【输入格…

Spring-AOP面相切面编程示例(有详细注释)

前提知识Spring-IOC容器注解方式使用https://blog.csdn.net/m0_61160520/article/details/136784799?spm1001.2014.3001.5501切点表达式https://blog.csdn.net/m0_61160520/article/details/136782885?spm1001.2014.3001.5501 案例 1.创建项目 2.导入依赖 <dependencie…

CSS 三大特性 详细讲解

CSS 三大特性及代码解释 层叠性 当相同选择器设置相同样式且发生冲突时&#xff0c;此时后者的样式会覆盖&#xff08;层叠&#xff09;前者冲突样式。CSS的层叠性就是用于解决样式冲突问题。 Input&#xff1a; <style>div {color: red;}div { color: blue; <!-…

webconfig-boot分布式项目Web一站式配置

1、前言 最近利用空余时间写了一个项目webconfig-boot 。该项目主要配置了web项目常用的一些配置&#xff0c;如统一参数校验、统一异常捕获、统一日期的处理、常用过滤器、常用注解等。引入依赖接口完成常规的web配置。 这里也是总结了笔者在项目开发中遇到的一些常用的配置…

springboot项目讲解

技术栈 vue(前端) springboot(后端主框架) mybatis&#xff08;ORM&#xff0c;用于后端和数据库的映射&#xff0c;即java对象转换成表&#xff09; mysql (关系型数据库) 顶层结构 .idea&#xff1a; idea缓存文件(不需要管) src&#xff1a;代码核心文件夹 —main&#xf…

Windows Terminal配置 美化

Windows 终端自定义提示符设置 | Microsoft Learn 安装PowerShell7 在 Windows 上安装 PowerShell - PowerShell | Microsoft Learn 设置默认为 PowerShell7 安装 在powerShell 开启远程权限 Set-ExecutionPolicy RemoteSigned -scope CurrentUserscoop 执行 iwr -useb ht…

王道机试C++续第6章 数学问题 贪心算法和蓝桥杯真题Day37倒计时24天

6.4 分解质因数 上一节讨论了素数的问题&#xff0c;而素数常用于分解质因数。每个数都可以写成一个或几个质数相乘的形式&#xff0c;其中每个质数都是这个数的质因数。把一个数用质因数相乘的形式表示出来&#xff0c;就称为分解质因数。例如&#xff0c;对一个数 x 分解素…

Centos7没有可用软件包 ifconfig问题解决

问题描述 在Centos7中查看ip没有ifconfig&#xff0c;使用yum安装ifconfig报错没有可用软件包 ifconfig问题解决 [rootlocalhost etc]# yum -y install ifconfig 已加载插件&#xff1a;fastestmirror base …

进程间通信 之 共享内存

目录 什么是共享内存&#xff1f; 共享内存的系统调用接口 共享内存 进程间通信的本质及前提&#xff1a;让不同的进程看到同一份资源&#xff01; 共享内存区是最快的IPC形式。一旦这样的内存映射到共享它的进程的地址空间&#xff0c;这些进程间数据传递不再涉及到内核&a…

鸿蒙开发实战:【网络管理-Socket连接】

介绍 本示例主要演示了Socket在网络通信方面的应用&#xff0c;展示了Socket在两端设备的连接验证、聊天通信方面的应用。 效果预览 使用说明 1.打开应用&#xff0c;点击用户文本框选择要登录的用户&#xff0c;并输入另一个设备的IP地址&#xff0c;点击确定按钮进入已登录…

【毛毛讲书】【好运】为什么有些人天生就有好运眷顾?

重磅专栏推荐&#xff1a; 《大模型AIGC》 《课程大纲》 《知识星球》 本专栏致力于探索和讨论当今最前沿的技术趋势和应用领域&#xff0c;包括但不限于ChatGPT和Stable Diffusion等。我们将深入研究大型模型的开发和应用&#xff0c;以及与之相关的人工智能生成内容&#xff…

什么是web组态?Web组态软件哪个好用?

随着工业4.0的到来&#xff0c;物联网、大数据、人工智能等技术的融合应用&#xff0c;使得工业领域正在经历一场深刻的变革。在这个过程中&#xff0c;Web组态技术以其独特的优势&#xff0c;正在逐渐受到越来越多企业的关注和认可。那么&#xff0c;什么是Web组态&#xff1f…

轻巧的elasticsearch可视化工具

一、概述 常见的ES可视化工具有&#xff1a; kibanaelasticsearch-headElasticHDDejavucerebroelasticview 一、安装elasticview 在众多ES可视化龚居中&#xff0c;elasticview是一款比较轻量简洁&#xff0c;兼容性较好&#xff0c;可以兼容多个ES版本&#xff0c;不但可以进…

[蓝桥杯 2020 省 AB3] 限高杆

分层图建图典题 #include<bits/stdc.h> using namespace std; using ll long long; #define int long long const int N 6e510; const int inf 0x3f3f3f3f; const int mod 1e97; int e[N],ne[N],w[N],h[N],idx; void add(int a,int b,int c){e[idx] b,ne[idx] h[a]…

外键约束

目录 外键约束 对数据表进行初期设计&#xff0c;暂时不使用外键 验证限制三 验证级联删除 设置级联更新 Oracle从入门到总裁:​​​​​​https://blog.csdn.net/weixin_67859959/article/details/135209645 外键约束 外键约束主要是在父子表关系中体现的一种约束操作。…

【二叉树】算法例题

目录 九、二叉树 68. 二叉树的最大深度 ① 69. 相同的树 ① √ 70. 翻转二叉树 ① 71. 对称二叉树 ① 72. 从前序与中序遍历序列构造二叉树 ② 73. 从中序与后续遍历序列构造二叉树 ② 74. 填充每个节点的下一个右侧节点指针 II ② 75. 二叉树展开为链表 ② 76.…

鸿蒙实战开发:【FaultLoggerd组件】讲解

简介 Faultloggerd部件是OpenHarmony中C/C运行时崩溃临时日志的生成及管理模块。面向基于 Rust 开发的部件&#xff0c;Faultloggerd 提供了Rust Panic故障日志生成能力。系统开发者可以在预设的路径下找到故障日志&#xff0c;定位相关问题。 架构 Native InnerKits 接口 Si…

Marin说PCB之电源完整性之直流压降仿真CST--03

本期内容主要讲解的是关于在CST软件上电源直流压降仿真VRM的一些相关参数设置&#xff0c;小编我在之前文章中有说到过如何利用CST仿真电源信号的直流压降&#xff0c;不过有一些问题我这边再去补充一些。 首先就是VRM芯片的设置了&#xff0c;小编我还是按照之前那样设置&…