数码相框-显示JPG图片

news2024/11/28 8:46:34

LCD控制器会将LCD上的屏幕数据映射在相应的显存位置上。

在这里插入图片描述

通过libjpeg把jpg图片解压出来RGB原始数据。

libjpeg是使用c语言实现的读写jpeg文件的库。

使用libjpeg的应用程序是以"scanline"为单位进行图像处理的。

libjpeg解压图片的步骤:
在这里插入图片描述

libjpeg的使用

Directory Listing of /files (ijg.org)

bleaaach@bleaaach-virtual-machine:~/linux/IMX6ULL/frame/04_libjpeg$ tar -vxzf jpegsrc.v9f.tar.gz

生成配置文件:

bleaaach@bleaaach-virtual-machine:~/linux/IMX6ULL/frame/04_libjpeg$ ls
jpeg-9f  jpegsrc.v9f.tar.gz
bleaaach@bleaaach-virtual-machine:~/linux/IMX6ULL/frame/04_libjpeg$ cd jpeg-9f/
bleaaach@bleaaach-virtual-machine:~/linux/IMX6ULL/frame/04_libjpeg/jpeg-9f$ mkdir tmp
bleaaach@bleaaach-virtual-machine:~/linux/IMX6ULL/frame/04_libjpeg/jpeg-9f$ ./configure --prefix=/home/bleaaach/linux/IMX6ULL/frame/04_libjpeg/jpeg-9f/tmp/ --host=arm-gnueabihf-linux
bleaaach@bleaaach-virtual-machine:~/linux/IMX6ULL/frame/04_libjpeg/jpeg-9f$ sudo make install
bleaaach@bleaaach-virtual-machine:~/linux/IMX6ULL/frame/04_libjpeg/jpeg-9f$ ls tmp
bin  include  lib  share

今天仔细看了一下arm-linux-gnueabihf的头文件在/usr/local/arm/gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-gnueabihf/arm-linux-gnueabihf/include/

bleaaach@bleaaach-virtual-machine:/usr/local/include$ ls
freetype2  jconfig.h  jerror.h  jmorecfg.h  jpeglib.h
bleaaach@bleaaach-virtual-machine:~/linux/IMX6ULL/frame/04_libjpeg/jpeg-9f/tmp/lib$ sudo cp * /usr/local/arm/gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-gnueabihf/arm-linux-gnueabihf/lib -rf
bleaaach@bleaaach-virtual-machine:~/linux/IMX6ULL/frame/04_libjpeg/jpeg-9f/tmp/lib$ sudo cp ../include/* /usr/local/arm/gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-gnueabihf/arm-linux-gnueabihf/include/ -rf

输出图像信息

把韦东山老师写的代码拷进来:
在这里插入图片描述

编译1th:

#include <stdio.h>
#include "jpeglib.h"
#include <setjmp.h>


/*
Allocate and initialize a JPEG decompression object    // 分配和初始化一个decompression结构体
Specify the source of the compressed data (eg, a file) // 指定源文件
Call jpeg_read_header() to obtain image info		   // 用jpeg_read_header获得jpg信息
Set parameters for decompression					   // 设置解压参数,比如放大、缩小
jpeg_start_decompress(...); 						   // 启动解压:jpeg_start_decompress
while (scan lines remain to be read)
	jpeg_read_scanlines(...);						   // 循环调用jpeg_read_scanlines
jpeg_finish_decompress(...);						   // jpeg_finish_decompress
Release the JPEG decompression object				   // 释放decompression结构体
*/

/* Uage: jpg2rgb <jpg_file>
 */

int main(int argc, char **argv)
{
	struct jpeg_decompress_struct cinfo;
	struct jpeg_error_mgr jerr;
	FILE * infile;

	// 分配和初始化一个decompression结构体
	cinfo.err = jpeg_std_error(&jerr);
	jpeg_create_decompress(&cinfo);

	// 指定源文件
	if ((infile = fopen(argv[1], "rb")) == NULL) {
		fprintf(stderr, "can't open %s\n", argv[1]);
		return -1;
	}
	jpeg_stdio_src(&cinfo, infile);

	// 用jpeg_read_header获得jpg信息
	jpeg_read_header(&cinfo, TRUE);
	/* 源信息 */
	printf("image_width = %d\n", cinfo.image_width);
	printf("image_height = %d\n", cinfo.image_height);
	printf("num_components = %d\n", cinfo.num_components);

	// 设置解压参数,比如放大、缩小

	// 启动解压:jpeg_start_decompress
	jpeg_start_decompress(&cinfo);

	/* 输出的图象的信息 */
	printf("output_width = %d\n", cinfo.output_width);
	printf("output_height = %d\n", cinfo.output_height);
	printf("output_components = %d\n", cinfo.output_components);


	// 循环调用jpeg_read_scanlines来一行一行地获得解压的数据

	jpeg_finish_decompress(&cinfo);
	jpeg_destroy_decompress(&cinfo);

	return 0;
}
bleaaach@bleaaach-virtual-machine:~/linux/IMX6ULL/frame/04_libjpeg/1th$ arm-linux-gnueabihf-gcc -o jpg2rgb jpg2rgb.c -ljpeg

把文件拷贝到开发板:
在这里插入图片描述

在开发板上测试:

在这里插入图片描述

调整压缩比

// 设置解压参数,比如放大、缩小
printf("enter M/N:\n");
scanf("%d/%d", &cinfo.scale_num, &cinfo.scale_denom);
printf("scale to : %d/%d\n", cinfo.scale_num, cinfo.scale_denom);

在这里插入图片描述

在这里插入图片描述

有些缩放比例并没有实现,所以没有效果。

输出JPG图片

#include <stdio.h>
#include "jpeglib.h"
#include <setjmp.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <linux/fb.h>
#include <string.h>
#include <stdlib.h>

#define FB_DEVICE_NAME "/dev/fb0"
#define DBG_PRINTF printf

static int g_fd;

static struct fb_var_screeninfo g_tFBVar;
static struct fb_fix_screeninfo g_tFBFix;	
static unsigned char *g_pucFBMem;
static unsigned int g_dwScreenSize;

static unsigned int g_dwLineWidth;
static unsigned int g_dwPixelWidth;

static int FBDeviceInit(void)
{
	int ret;

	g_fd = open(FB_DEVICE_NAME, O_RDWR);
	if (0 > g_fd)
	{
		DBG_PRINTF("can't open %s\n", FB_DEVICE_NAME);
	}

	ret = ioctl(g_fd, FBIOGET_VSCREENINFO, &g_tFBVar);
	if (ret < 0)
	{
		DBG_PRINTF("can't get fb's var\n");
		return -1;
	}

	ret = ioctl(g_fd, FBIOGET_FSCREENINFO, &g_tFBFix);
	if (ret < 0)
	{
		DBG_PRINTF("can't get fb's fix\n");
		return -1;
	}

	g_dwScreenSize = g_tFBVar.xres * g_tFBVar.yres * g_tFBVar.bits_per_pixel / 8;
	g_pucFBMem = (unsigned char *)mmap(NULL , g_dwScreenSize, PROT_READ | PROT_WRITE, MAP_SHARED, g_fd, 0);
	if (0 > g_pucFBMem)
	{
		DBG_PRINTF("can't mmap\n");
		return -1;
	}

	g_dwLineWidth  = g_tFBVar.xres * g_tFBVar.bits_per_pixel / 8;
	g_dwPixelWidth = g_tFBVar.bits_per_pixel / 8;

	return 0;
}


static int FBShowPixel(int iX, int iY, unsigned int dwColor)
{
	unsigned char *pucFB;
	unsigned short *pwFB16bpp;
	unsigned int *pdwFB32bpp;
	unsigned short wColor16bpp; /* 565 */
	int iRed;
	int iGreen;
	int iBlue;

	if ((iX >= g_tFBVar.xres) || (iY >= g_tFBVar.yres))
	{
		DBG_PRINTF("out of region\n");
		return -1;
	}

	pucFB      = g_pucFBMem + g_dwLineWidth * iY + g_dwPixelWidth * iX;
	pwFB16bpp  = (unsigned short *)pucFB;
	pdwFB32bpp = (unsigned int *)pucFB;

	switch (g_tFBVar.bits_per_pixel)
	{
		case 8:
		{
			*pucFB = (unsigned char)dwColor;
			break;
		}
		case 16:
		{
			iRed   = (dwColor >> (16+3)) & 0x1f;
			iGreen = (dwColor >> (8+2)) & 0x3f;
			iBlue  = (dwColor >> 3) & 0x1f;
			wColor16bpp = (iRed << 11) | (iGreen << 5) | iBlue;
			*pwFB16bpp	= wColor16bpp;
			break;
		}
		case 32:
		{
			*pdwFB32bpp = dwColor;
			break;
		}
		default :
		{
			DBG_PRINTF("can't support %d bpp\n", g_tFBVar.bits_per_pixel);
			return -1;
		}
	}

	return 0;
}

static int FBCleanScreen(unsigned int dwBackColor)
{
	unsigned char *pucFB;
	unsigned short *pwFB16bpp;
	unsigned int *pdwFB32bpp;
	unsigned short wColor16bpp; /* 565 */
	int iRed;
	int iGreen;
	int iBlue;
	int i = 0;

	pucFB      = g_pucFBMem;
	pwFB16bpp  = (unsigned short *)pucFB;
	pdwFB32bpp = (unsigned int *)pucFB;

	switch (g_tFBVar.bits_per_pixel)
	{
		case 8:
		{
			memset(g_pucFBMem, dwBackColor, g_dwScreenSize);
			break;
		}
		case 16:
		{
			iRed   = (dwBackColor >> (16+3)) & 0x1f;
			iGreen = (dwBackColor >> (8+2)) & 0x3f;
			iBlue  = (dwBackColor >> 3) & 0x1f;
			wColor16bpp = (iRed << 11) | (iGreen << 5) | iBlue;
			while (i < g_dwScreenSize)
			{
				*pwFB16bpp	= wColor16bpp;
				pwFB16bpp++;
				i += 2;
			}
			break;
		}
		case 32:
		{
			while (i < g_dwScreenSize)
			{
				*pdwFB32bpp	= dwBackColor;
				pdwFB32bpp++;
				i += 4;
			}
			break;
		}
		default :
		{
			DBG_PRINTF("can't support %d bpp\n", g_tFBVar.bits_per_pixel);
			return -1;
		}
	}

	return 0;
}

static int FBShowLine(int iXStart, int iXEnd, int iY, unsigned char *pucRGBArray)
{
	int i = iXStart * 3;
	int iX;
	unsigned int dwColor;
  //边界处理
	if (iY >= g_tFBVar.yres)
		return -1;

	if (iXStart >= g_tFBVar.xres)
		return -1;

	if (iXEnd >= g_tFBVar.xres)
	{
		iXEnd = g_tFBVar.xres;
	}

	for (iX = iXStart; iX < iXEnd; iX++)
	{
		/* 0xRRGGBB */
		dwColor = (pucRGBArray[i]<<16) + (pucRGBArray[i+1]<<8) + (pucRGBArray[i+2]<<0);
		i += 3;
		FBShowPixel(iX, iY, dwColor);
	}
	return 0;
}


/*
Allocate and initialize a JPEG decompression object    // 分配和初始化一个decompression结构体
Specify the source of the compressed data (eg, a file) // 指定源文件
Call jpeg_read_header() to obtain image info		   // 用jpeg_read_header获得jpg信息
Set parameters for decompression					   // 设置解压参数,比如放大、缩小
jpeg_start_decompress(...); 						   // 启动解压:jpeg_start_decompress
while (scan lines remain to be read)
	jpeg_read_scanlines(...);						   // 循环调用jpeg_read_scanlines
jpeg_finish_decompress(...);						   // jpeg_finish_decompress
Release the JPEG decompression object				   // 释放decompression结构体
*/

/* Uage: jpg2rgb <jpg_file>
 */

int main(int argc, char **argv)
{
	struct jpeg_decompress_struct cinfo;
	struct jpeg_error_mgr jerr;
	FILE * infile;
	int row_stride;
	unsigned char *buffer;

	if (argc != 2)
	{
		printf("Usage: \n");
		printf("%s <jpg_file>\n", argv[0]);
		return -1;
	}

	if (FBDeviceInit())
	{
		return -1;
	}

	FBCleanScreen(0);

	// 分配和初始化一个decompression结构体
	cinfo.err = jpeg_std_error(&jerr);
	jpeg_create_decompress(&cinfo);

	// 指定源文件
	if ((infile = fopen(argv[1], "rb")) == NULL) {
		fprintf(stderr, "can't open %s\n", argv[1]);
		return -1;
	}
	jpeg_stdio_src(&cinfo, infile);

	// 用jpeg_read_header获得jpg信息
	jpeg_read_header(&cinfo, TRUE);
	/* 源信息 */
	printf("image_width = %d\n", cinfo.image_width);
	printf("image_height = %d\n", cinfo.image_height);
	printf("num_components = %d\n", cinfo.num_components);

	// 设置解压参数,比如放大、缩小
	printf("enter scale M/N:\n");
	scanf("%d/%d", &cinfo.scale_num, &cinfo.scale_denom);
	printf("scale to : %d/%d\n", cinfo.scale_num, cinfo.scale_denom);

	// 启动解压:jpeg_start_decompress
	jpeg_start_decompress(&cinfo);

	/* 输出的图象的信息 */
	printf("output_width = %d\n", cinfo.output_width);
	printf("output_height = %d\n", cinfo.output_height);
	printf("output_components = %d\n", cinfo.output_components);

	// 一行的数据长度
	row_stride = cinfo.output_width * cinfo.output_components;
	buffer = malloc(row_stride);

	// 循环调用jpeg_read_scanlines来一行一行地获得解压的数据
	while (cinfo.output_scanline < cinfo.output_height) 
	{
		(void) jpeg_read_scanlines(&cinfo, &buffer, 1);

		// 写到LCD去
		FBShowLine(0, cinfo.output_width, cinfo.output_scanline, buffer);
	}

	free(buffer);
	jpeg_finish_decompress(&cinfo);
	jpeg_destroy_decompress(&cinfo);

	return 0;
}


这段代码使用libjpeg库将一个JPEG格式的图片文件解码并显示到Linux系统的Framebuffer设备上。以下是详细的代码功能解读:

  1. 包含头文件与定义常量

    • 引入了stdio.hjpeglib.hsetjmp.h等C标准库头文件以及sys/types.hsys/stat.hfcntl.hsys/ioctl.hsys/mman.hlinux/fb.h等系统相关头文件。
    • 定义了Framebuffer设备名FB_DEVICE_NAME、调试打印宏DBG_PRINTF以及全局变量g_fdg_tFBVarg_tFBFixg_pucFBMemg_dwScreenSizeg_dwLineWidthg_dwPixelWidth
  2. Framebuffer设备初始化函数

    • FBDeviceInit()函数负责打开Framebuffer设备文件、获取其变量信息(g_tFBVar)和固定信息(g_tFBFix),计算屏幕尺寸、内存映射,并初始化行宽和像素宽度。
  3. Framebuffer显示相关函数

    • FBShowPixel()函数根据给定的颜色值和坐标,在Framebuffer上显示一个像素。

    • FBCleanScreen()函数清除整个Framebuffer,用指定颜色填充。

    • FBShowLine()函数接收一个RGB数据数组,将该数组表示的一行像素数据按照指定坐标写入Framebuffer。

      • int iXStart: 要绘制的线条起点的 x 坐标。
      • int iXEnd: 要绘制的线条终点的 x 坐标。
      • int iY: 线条在屏幕上的固定 y 坐标。
      • unsigned char *pucRGBArray: 指向一个包含 RGB 像素值的字节数组,数组中的每个连续三个字节表示一个像素的 R、G、B 分量(各占 8 位)。

      在这里插入图片描述

  4. JPEG解码相关函数

    • 这部分代码未直接定义JPEG解码函数,而是使用libjpeg库提供的接口。
    • main()函数中,首先检查命令行参数是否正确(需要提供一个JPEG文件路径),然后调用FBDeviceInit()初始化Framebuffer设备。
    • 初始化jpeg_decompress_struct结构体cinfo和错误处理结构体jerr,并关联标准错误处理方法。
    • 打开指定的JPEG文件,将其作为解码源设置到cinfo结构体中。
    • 调用jpeg_read_header()读取JPEG文件头信息,获取原始图像尺寸、颜色组件数等。
    • 提示用户输入缩放比例(M/N),并设置到cinfo结构体中。
    • 调用jpeg_start_decompress()启动解码过程。
  5. JPEG图像解码与显示

    • 根据解码后输出的图像尺寸分配临时缓冲区buffer,用于存放一行像素数据。

    • 使用循环调用jpeg_read_scanlines(),每次读取一行像素数据并将其存储在buffer中。

      buffer是一个指针数组,存储一行数据的起始位置。

      在这里插入图片描述

      我们要把buffer传入到这个typedef unsiged char** JSAMPARRAY变量里,buffer[0]实际上是一个unsigned char *地址的指针,是指针的指针。

    • 对于每一行解码得到的像素数据,调用FBShowLine()将其显示到Framebuffer对应行上。

    • 解码完成后,释放buffer,调用jpeg_finish_decompress()jpeg_destroy_decompress()完成解码过程的清理工作。
      综上所述,这段代码的主要目的是将一个JPEG格式的图片文件解码,根据用户指定的缩放比例调整图像尺寸,然后逐行将解码后的像素数据写入Linux系统的Framebuffer设备,最终在连接到该设备的屏幕上显示解码后的图像。

测试

在这里插入图片描述

在这里插入图片描述

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

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

相关文章

FPGA:图像数字细节增强算法(工程+仿真+实物,可用毕设)

目录 日常唠嗑一、视频效果二、硬件及功能1、硬件选择2、功能3、特点 未完、待续……四、工程设计五、板级验证六、工程获取 日常唠嗑 有2个多月没写文章了&#xff0c;又是老借口&#xff1a;“最近实在是很忙”&#x1f923;&#xff0c;不过说真&#xff0c;确实是比较忙&am…

AWS服务器有哪些优势?

作为一家总部在美国的公司&#xff0c;AWS为什么会受到中国企业的喜爱&#xff1f;他有什么优势&#xff1f;九河云作为AWS合作伙伴&#xff0c;将会带读者展现使用AWS的优势。 首先是作为跨国企业&#xff0c;AWS在全球有数十个区域节点&#xff0c;这种广泛的地域覆盖不仅有…

【简单讲解下Kotlin】

&#x1f3a5;博主&#xff1a;程序员不想YY啊 &#x1f4ab;CSDN优质创作者&#xff0c;CSDN实力新星&#xff0c;CSDN博客专家 &#x1f917;点赞&#x1f388;收藏⭐再看&#x1f4ab;养成习惯 ✨希望本文对您有所裨益&#xff0c;如有不足之处&#xff0c;欢迎在评论区提出…

[大模型]基于 ChatGLM3 和 LangChain 搭建知识库助手

基于 ChatGLM3 和 LangChain 搭建知识库助手 环境配置 在已完成 ChatGLM3 的部署基础上&#xff0c;还需要安装以下依赖包&#xff1a; pip install langchain0.0.292 pip install gradio4.4.0 pip install chromadb0.4.15 pip install sentence-transformers2.2.2 pip inst…

详解TCP和UDP协议的区别

一、前言 TCP和UDP协议是TCP/IP协议的核心。TCP 传输协议&#xff1a;TCP 协议是一TCP (Transmission Control Protocol)和UDP(User Datagram Protocol)协议属于传输层协议。其中TCP提供IP环境下的数据可靠传输&#xff0c;它提供的服务包括数据流传送、可靠性、有效流控、全双…

实时时钟模块RX8900CE为电子产品设备提供精准时间,能够适应极度紧凑的空间

随着电子技术飞速发展&#xff0c;越来越多的设备需要用到实时时钟电路。而过往的实时时钟电路&#xff0c;大多是分立式的架构&#xff0c;外围有不少的元器件&#xff0c;不但成本高昂&#xff0c;而且稳定性也不高&#xff0c;在严苛的工作条件下就显得有点力不从心。作为设…

ARM单片机的GPIO口在控制不同LED、按键时的设置

个人备忘&#xff0c;不喜勿喷。 GPIO口在驱动共阴极、共阳极LED灯时需要不同的初始化设置 对于这一类的led灯&#xff1a; 最好选择推挽、上拉、高速输出&#xff0c;同时IO口初始化时需要拉高。 上面这种需要下拉输入&#xff1b; 上图这种需要上拉输入&#xff0c;这样才…

聊一聊一些关于npm、pnpm、yarn的事

前言 整理了最近的闲聊&#xff0c;话题是前端各个包管理器&#xff0c;如果分享的不对或者有异议的地方&#xff0c;麻烦请及时告诉我~ 耐心看完&#xff0c;也许你会有所收获~ 概述 本文阅读时间&#xff1a;10-15分钟左右&#xff1b; 难度&#xff1a;初级&#xff0c…

LeetCode 2529. 正整数和负整数的最大计数——每日一题

上一篇博客&#xff1a;LeetCode 993. 二叉树的堂兄弟节点——每日一题 写在前面&#xff1a;大家好&#xff01;我是晴空๓。如果博客中有不足或者的错误的地方欢迎在评论区或者私信我指正&#xff0c;感谢大家的不吝赐教。我的唯一博客更新地址是&#xff1a;https://ac-fun.…

【计算机考研】408网课汇总+资源分享

王道的四件套无疑是大多数同学的首选。相比其他课程来说&#xff0c;也是属于市面上最好的408课程了。 从今年的难度来看选择题部分和计网&#xff0c;比起往年来看是有很多偏题&#xff0c;大题除了计网的冷门外&#xff0c;其他倒是中规中矩。总体来看24考研的408难度是非常…

Win11 使用 WSL2 安装 linux 子系统 ubuntu

Win11 使用 WSL2 安装 linux 子系统 ubuntu 段子手168 1、用 部署映像服务和管理工具 dism.exe 命令&#xff0c;开启 WSL2 按【WIN R】&#xff0c;打开【运行】&#xff0c;输入&#xff1a;【cmd】&#xff0c;管理员打开【命令行提示符】。 启用适用于 Linux 的 Windo…

单例模式(饿汉模型,懒汉模型)

在着里我们先了解什么是单例模式。 就是某个类在进程中只能有单个实例&#xff0c;这里的单例模式需要一定的编程技巧&#xff0c;做出限制&#xff0c;一旦程序写的有问题&#xff0c;创建了多个实例&#xff0c;编程就会报错。 如果我们学会了单例模式&#xff0c;这种模式…

ORAN C平面 Section Extension 22

ORAN C平面Section扩展22用于ACK/NACK请求。除section type 7外&#xff0c;section扩展22可以用于从O-DU发送到O-RU的所有section type和section扩展。 对于一个section描述&#xff0c;O-DU可以使用section扩展22要求O-RU使用section type 8 C平面消息进行ACK/NACK反馈。关于…

Spring Validation解决后端表单校验

NotNull&#xff1a;从前台传递过来的参数不能为null,如果为空&#xff0c;会在控制台日志中把message打印出来 Range&#xff1a;范围&#xff0c;最大多少&#xff0c;最小多少 Patten&#xff0c;标注的字段值必须符合定义的正则表达式&#xff08;按照业务规则&#xff0…

智慧公厕是智慧城市建设中不可或缺的一部分

智慧城市的数字化转型正在取得显著成效&#xff0c;各项基础设施的建设也在迅速发展&#xff0c;其中智慧公厕成为了智慧城市体系中不可或缺的一部分。作为社会生活中必要的设施&#xff0c;公共厕所的信息化、数字化、智慧化升级转型能够实现全区域公共厕所管理的横向打通和纵…

T527 Qt 触摸 ----- TSLIB

一、调试 1、驱动路径 bsp/drivers/input/ctp/gt9xx/gt9xx_ts.c 2、硬件接口 挂载在TWI0下 3、中断复位脚 4、设备树 &twi0 {clock-frequency <400000>;pinctrl-0 <&twi0_pins_default>;pinctrl-1 <&twi0_pins_sleep>;pinctrl-names &quo…

vue通过echarts实现数据可视化

1、安装echarts cnpm install echarts -Sechart官方图表示例大全&#xff1a;https://echarts.apache.org/examples/zh/index.html#chart-type-line 2、代码实现 <template><div><div class"box" ref"zhu"></div><div class&…

设计模式之创建型模式---建造者模式

文章目录 建造者模式概述经典的建造者模式建造者模式的变种总结 建造者模式概述 建造者模式是一种广泛使用的设计模式&#xff0c;在三方开源库和各种SDK中经常见到。建造者设计模式在四人帮的经典著作《设计模式&#xff1a;可复用面向对象软件基础》中被提及&#xff0c;它的…

赛氪网|2024中国翻译协会年会“AI科技时代竞赛与就业”分论坛

在2024年中国翻译协会年会期间&#xff0c;赛氪网与中西部翻译协会共同体多边合作平台共同承办&#xff0c;于3月30日下午在长沙成功举办了“AI科技时代竞赛与就业分论坛”。该论坛汇聚了众多翻译界、科技界和教育界的专家学者&#xff0c;共同探讨科技、实践、就业与竞赛人才培…

五、Redis 集群搭建

目录 一、redis集群搭建&#xff08;3台机器、6个节点&#xff09; 1、在安装目录下创建7001、7002文件夹&#xff0c;把之前的redis.conf配置文件复制到7001文件夹中&#xff0c;进行编辑 2、传到其他服务器的文件要记得修改端口和集群节点信息和pidfile,不然redis 起不来 …