DI Blackfin DSP处理器-BF533的开发详解47:图像处理专题-Resize (图像缩放处理)(含源码)

news2024/11/27 21:00:25

硬件准备

ADSP-EDU-BF533:BF533开发板
AD-HP530ICE:ADI DSP仿真器

软件准备

Visual DSP++软件

硬件链接

在这里插入图片描述

功能介绍

代码实现了图像缩放处理,代码运行时,会通过文件系统打开工程文件根目下" …/ImageView"路径中的 testin.bmp 文件,进行图像的缩放处理后把图片保存到工程文件根目下" …/ImageView"路径中的 testout.bmp 文件,并且将处理后的图片显示到液晶屏上。例子中的算法只支持尺寸为 480*272 的 24bit 的 bmp 图片,可以根据自己的需要自行调整。

代码使用说明
funct.c 中的 Resize(BMPIMAGE* img,float fXZoomRatio, floatfYZoomRatio)
该函数是将读取的图像进行缩放处理。

BMPIMAGE * 图像结构体指针
float fXZoomRatio 水平缩放系数 大于 1 放大,小于 1 缩小
float fYZoomRatio 垂直缩放系数 大于 1 放大,小于 1 缩小

在 main.c 文件中定义了一个#define LCD_VIEW_ENABLE 宏开关,如果不需要将处理后的图片显示在液晶屏上,只需将这个宏开关注释掉

代码实验步骤

  1. 将工程文件根目下的 ImageView 文件夹内存放一个名为 testin.bmp 的图像文件,该文件尺寸为 480*272 的24bit 的 bmp 图片(默认已存一幅测试图片)。
  2. 打开工程文件 BF53x_Resize.dpj,编译并运行代码
  3. 等待图像处理,处理完成之后会在液晶屏上显示处理后的图片,并在工程文件根目下的 ImageView 文件夹内生成一个处理后名为 testout.bmp 图片。

代码实验结果

1.液晶屏上显示处理后的图片,缩小后的图片显示在液晶屏的中心位置,放大后在图片的中心位置取液晶屏一样的图片显示,在液晶屏上显示的前提是 fXZoomRatio fYZoomRatio 同时大于 1 或者同时小于 1, 否则不会在液晶屏上显示, 只能通过文件查看处理后的图片。

2.在工程文件根目下的 ImageView 文件夹中查看处理后名为 testout.bmp 图片。

程序源码

bmp.c

#include<stdio.h>
#include “bmp.h”

/********************************************************

  • 函数名 : OpenBmpFile
  • 函数功能 : 以二进制形式打开计算机硬盘BMP图像文件
  • 函数参数 : const char * 图像文件名称
  •   			BMPIMAGE *			  图像结构体指针
    
  • 函数返回值 :FALSE 打开图像文件失败
  •   			TRUE	打开图像文件成功
    

/
int OpenBmpFile(const char
filename, BMPIMAGE
img) {
if((img->bmpfile = fopen(filename, “rb”)) == NULL)
{
printf(“open file is Failure\n\r”);
return FALSE;
}
return TRUE;
}
/
**

  • 函数名 : writeBmpFile
  • 函数功能 : 将二进制图像数据保存到计算机硬盘中
  • 函数参数 : const char * 图像文件名称
  •   			BMPIMAGE *			  图像结构体指针
    
  • 函数返回值 :FALSE 保存图像文件失败
  •   			TRUE	保存图像文件成功
    

******************************************************/
int writeBmpFile(const char
filename,const BMPIMAGE
img) {

FILE *fp;
unsigned int i,j;
unsigned char tempData, *pData;
unsigned int tempHeight;
unsigned int tempWidth;
tempHeight = img->infohead.BiHeight>>1;
tempWidth = img->infohead.BiWidth*3;
pData = img->imgbuf;
for(i = 0; i < img->imagesize; i = i + 3) {
	tempData = pData[i];
	pData[i] = pData[i + 2];
	pData[i + 2] = tempData;
}

for(i=0;i<tempHeight;i++)
{
	for(j=0;j<tempWidth;j++)
	{
		tempData = pData[(img->infohead.BiHeight-1-i)*tempWidth+j];
		pData[(img->infohead.BiHeight-1-i)*tempWidth+j] = pData[i*tempWidth+j];
		pData[i*tempWidth+j] = tempData;
	}
}

if((fp = fopen(filename, "wb")) == NULL)
{
	printf("seek file is Failure\n\r");
	return FALSE;
}	
fwrite(&img->filehead, 1, 2, fp);
fwrite(&img->filehead.bfSize, 1, 12, fp);
fwrite(&img->infohead, 1, 40, fp);
fwrite(img->imgbuf, 1, img->imagesize, fp);
fclose(fp);
fclose(img->bmpfile);
return TRUE;

}
/********************************************************

  • 函数名 : GetBmpHeader
  • 函数功能 : 读取BMP文件头
  • 函数参数 : BMPIMAGE * 图像结构体指针
  • 函数返回值 :FALSE 读取BMP文件头失败
  •   			TRUE	读取BMP文件头成功
    

*******************************************************/
int GetBmpHeader(BMPIMAGE
img) {
unsigned char headbuffer[INFOHEADSIZE];
BMPFILEHEAD filehead = &img->filehead;
BMPINFOHEAD infohead = &img->infohead;
if (fread(headbuffer, 1, FILEHEADSIZE, img->bmpfile) != FILEHEADSIZE) {
return FALSE;
}
img->filehead.bfType[0] = headbuffer[0];
img->filehead.bfType[1] = headbuffer[1];
if (
(unsigned short )&filehead->bfType[0] != (0x4D42)) { / ‘BM’ /
printf(“file is not bmp\n\r”);
return FALSE; /
not bmp image
/
}
memcpy(&filehead->bfSize, &headbuffer[2], 4);
memcpy(&filehead->bfOffBits, &headbuffer[10], 4);
if(fseek(img->bmpfile, FILEHEADSIZE, SEEK_SET)) {
return FALSE;
}
if (fread(headbuffer, 1, INFOHEADSIZE, img->bmpfile) != INFOHEADSIZE) {
return FALSE;
}
memcpy(&infohead->BiSize, &headbuffer[0], 4);
memcpy(&infohead->BiWidth, &headbuffer[4], 4);
memcpy(&infohead->BiHeight, &headbuffer[8], 4);
memcpy(&infohead->BiPlanes, &headbuffer[12], 2);
memcpy(&infohead->BiBitCount, &headbuffer[14], 2);
memcpy(&infohead->BiCompression, &headbuffer[16], 4);
memcpy(&infohead->BiSizeImage, &headbuffer[20], 4);
memcpy(&infohead->BiXpelsPerMeter, &headbuffer[24], 4);
memcpy(&infohead->BiYpelsPerMeter, &headbuffer[28], 4);
memcpy(&infohead->BiClrUsed, &headbuffer[32], 4);
memcpy(&infohead->BiClrImportant, &headbuffer[36], 4);
if(infohead->BiPlanes != 1) {
return FALSE;
}
if(infohead->BiBitCount !=24) {
return FALSE;
}
if(infohead->BiCompression != BI_RGB) {
return FALSE;
}
GetImageSize(img);
return TRUE;
}

/********************************************************

  • 函数名 : GetImageSize
  • 函数功能 : 获取BMP文件大小
  • 函数参数 : BMPIMAGE * 图像结构体指针
  • 函数返回值 :void
    ********************************************************/
    void GetImageSize(BMPIMAGE *img) {
    img->imagesize = img->infohead.BiHeight * WIDTHBYTES(img->infohead.BiWidth * img->infohead.BiBitCount);
    }

/********************************************************

  • 函数名 : ReadBMPData
  • 函数功能 : 读取BMP数据缓冲区
  • 函数参数 : BMPIMAGE * 图像结构体指针
  • 函数返回值 :FALSE 读取BMP数据失败
  •   			TRUE	读取BMP数据成功
    

*******************************************************/
int ReadBMPData(const BMPIMAGE
img) {
unsigned int pitch = WIDTHBYTES(img->infohead.BiWidth * img->infohead.BiBitCount);
unsigned int readnum = 0;
int i, j, k;
unsigned char m_temp;
unsigned char *p_tmp, *p_tmp_cur;
unsigned char tempData, pData;
unsigned int index_data;
pData = img->imgbuf;
if(fseek(img->bmpfile, img->filehead.bfOffBits, SEEK_SET)) {
return FALSE;
}
p_tmp = NULL;
p_tmp = (unsigned char )malloc(pitch * img->infohead.BiHeight);
if(p_tmp != NULL) {
readnum = fread(p_tmp, 1, pitch * img->infohead.BiHeight, img->bmpfile);
p_tmp_cur = p_tmp;
for(i = img->infohead.BiHeight - 1; i >= 0; i–, p_tmp_cur += pitch) {
memcpy(&img->imgbuf[i
pitch], p_tmp_cur, pitch);
}
}
else {
for(i = img->infohead.BiHeight - 1; i >= 0; i–) {
readnum += fread(&img->imgbuf[i
pitch], 1, pitch, img->bmpfile);
}
}
for(index_data = 0; index_data < img->imagesize; index_data = index_data + 3) {
tempData = pData[index_data];
pData[index_data] = pData[index_data + 2];
pData[index_data + 2] = tempData;
}
if(p_tmp != NULL) {
free(p_tmp);
}
return (readnum == img->imagesize);
}

/********************************************************

  • 函数名 : Allocbuf
  • 函数功能 : 分配图像缓冲区
  • 函数参数 : BMPIMAGE * 图像结构体指针
  • 函数返回值 :FALSE 分配图像缓冲区失败
  •   			TRUE	分配图像缓冲区成功
    

/
int Allocbuf(BMPIMAGE
img) {
if((img->imgbuf = malloc(img->imagesize)) == NULL)
return FALSE;
return TRUE;
}
/
*

  • 函数名 : Freebuf
  • 函数功能 : 释放图像缓冲区
  • 函数参数 : BMPIMAGE * 图像结构体指针
  • 函数返回值 :void
    *******************************************************/
    void Freebuf(BMPIMAGE
    img) {
    if(img->imgbuf != NULL)
    free(img->imgbuf);
    img->imgbuf = NULL;
    }

cpu.c

#include <cdefBF533.h>
#include “cpu.h”

void Init_Timers0(int dat)
{
*pTIMER0_CONFIG = 0x0019;
*pTIMER0_WIDTH = dat;
*pTIMER0_PERIOD = 2000;
}

void Enable_Timers0(void)
{
*pTIMER_ENABLE|= 0x0001;
asm(“ssync;”);
}

void Disable_Timers0(void)
{
*pTIMER_DISABLE |= 0x0001;
}

void Set_PLL(int pmsel,int pssel)
{
int new_PLL_CTL;
*pPLL_DIV = pssel;
asm(“ssync;”);
new_PLL_CTL = (pmsel & 0x3f) << 9;
*pSIC_IWR |= 0xffffffff;
if (new_PLL_CTL != *pPLL_CTL)
{
*pPLL_CTL = new_PLL_CTL;
asm(“ssync;”);
asm(“idle;”);
}
}

void Init_SDRAM(void)
{
*pEBIU_SDRRC = 0x00000817;
*pEBIU_SDBCTL = 0x00000013;
*pEBIU_SDGCTL = 0x0091998d;
ssync();
}

void Init_EBIU(void)
{
*pEBIU_AMBCTL0 = 0x7bb07bb0;
*pEBIU_AMBCTL1 = 0x7bb07bb0;
*pEBIU_AMGCTL = 0x000f;
}

fun.c

#include “bmp.h”

/********************************************************

  • 函数名 : Resize
  • 函数功能 : 图像缩放处理
  • 函数参数 : BMPIMAGE * 图像结构体指针
    float fXZoomRatio 水平缩放系数
    float fYZoomRatio 垂直缩放系数
  • 函数返回值 :FALSE 处理失败
  •   			TRUE	处理成功
    

*******************************************************/
int Resize(BMPIMAGE
img,float fXZoomRatio, float fYZoomRatio)
{
// 源图像的宽度和高度
long lWidth;
long lHeight;

// 缩放后图像的宽度和高度
long	lNewWidth;
long	lNewHeight;

// 缩放后图像的宽度(lNewWidth',必须是4的倍数)
long	lNewLineBytes;


// 指向源象素的指针
unsigned char	*lpSrc;	
// 指向缩放图像对应象素的指针
unsigned char	*lpDst;

unsigned char *lpDIBBits = img->imgbuf;
unsigned char *lpNewDIBBits;	// 循环变量(象素在新DIB中的坐标)	

long	i,k,j;

// 象素在源DIB中的坐标
long	i0;
long	j0;

// 图像每行的字节数
long lLineBytes;

lWidth = img->infohead.BiWidth;


// 获取图像的高度
lHeight = img->infohead.BiHeight;
lLineBytes= WIDTHBYTES(lWidth * 24);
// 计算缩放后的图像实际宽度
// 此处直接加0.5是由于强制类型转换时不四舍五入,而是直接截去小数部分
lNewWidth = (long) (lWidth * fXZoomRatio + 0.5);

// 计算新图像每行的字节数
lNewLineBytes = WIDTHBYTES(lNewWidth * 8*3);

// 计算缩放后的图像高度
lNewHeight = (long) (lHeight * fYZoomRatio + 0.5);

lpNewDIBBits = (unsigned char*)malloc(lNewLineBytes*lNewHeight);
if(lpNewDIBBits == NULL)
	return FALSE;	

// 针对图像每行进行操作
for(i = 0; i < lNewHeight; i++)
{
	// 针对图像每列进行操作
	for(j = 0; j < lNewWidth; j++)
	{
		for(k=0;k<3;k++)
		{
			// 指向新DIB第i行,第j个象素的指针
			// 注意此处宽度和高度是新DIB的宽度和高度
			lpDst = (unsigned char *)lpNewDIBBits + lNewLineBytes * (lNewHeight - 1 - i) + 3*j + k;
		
			// 计算该象素在源DIB中的坐标
			i0 = (long) (i / fYZoomRatio + 0.5);
			j0 = (long) (j / fXZoomRatio + 0.5);
			//判断是否在源图范围内
			if( (j0 >= 0) && (j0 < lWidth) && (i0 >= 0) && (i0 < lHeight))
			{
				// 指向源DIB第i0行,第j0个象素的指针
				lpSrc = (unsigned char *)lpDIBBits + lLineBytes * (lHeight - 1 - i0) + 3*j0 + k;
				// 复制象素
				*lpDst = *lpSrc;
			}
			else
			{
				// 对于源图中没有的象素,直接赋值为255
				* ((unsigned char*)lpDst) = 255;
			}
		}
	}		
}

free(img->imgbuf);
img->imgbuf = lpNewDIBBits;
img->infohead.BiWidth = lNewWidth;
img->infohead.BiHeight = lNewHeight;
img->imagesize = lNewLineBytes*lNewHeight;
return TRUE;

}

main.c

#include <cdefBF533.h>
#include “cpu.h”
#include “tftlcd.h”
#include “bmp.h”
#include “funct.h”

#define INFILEADDR “…/ImageView/testin.bmp”
#define OUTFILEADDR “…/ImageView/testout.bmp”
#define LCD_VIEW_ENABLE
/在液晶屏上显示必须xzoom yzoom同时大于1或者同时小于1,
否则不会在液晶屏上显示,但是可以输出处理后的图像
/
float xzoom = 2; //水平缩放系数
float yzoom = 2; //垂直缩放系数

int main(void)
{
BMPIMAGE bmpimage;
Set_PLL(16,4);
Init_EBIU();
Init_SDRAM();
LCDBK_Disable();
if(!OpenBmpFile(INFILEADDR,&bmpimage))
return FALSE;
if(!GetBmpHeader(&bmpimage))
return FALSE;
if(!Allocbuf(&bmpimage))
return FALSE;
if(!ReadBMPData(&bmpimage))
return FALSE;

/* 图像缩放处理			*/
if(!Resize(&bmpimage,xzoom,yzoom))
	return FALSE;	

#ifdef LCD_VIEW_ENABLE
Enable_Timers0();
RGB888_RGB565(&bmpimage,(void*)DisplayBuffer_565,xzoom,yzoom);
#endif

if(!writeBmpFile(OUTFILEADDR,&bmpimage))
	return FALSE;

#ifdef LCD_VIEW_ENABLE
InitDMA();
InitPPI();
InitTimer();
PPI_TMR_DMA_Enable();
LCD_Enable();
LCDBK_Enable();
Init_Timers0(1999);//1~1999 控制背光亮度
Enable_Timers0();
while(1);
#endif
}

lcd.c

#include <cdefBF533.h>
#include “tftlcd.h”
#include “cpu.h”

section(“sdram0_bank1”) unsigned char DisplayBuffer_565[272][1440] ;

void InitDMA(void)
{
int addr;
addr = &DisplayBuffer_565;
addr -= 1920;
*pDMA0_START_ADDR = addr;

*pDMA0_X_COUNT = 480;
*pDMA0_X_MODIFY = 2;
*pDMA0_Y_COUNT = 286;
*pDMA0_Y_MODIFY = 2;	
*pDMA0_CONFIG = 0x1034;

}

void InitPPI(void)
{
*pPPI_CONTROL = 0x781e;
*pPPI_DELAY = 0;
*pPPI_COUNT = 479;
*pPPI_FRAME = 286;
}

void InitTimer(void)
{
*pTIMER1_PERIOD = 525;
*pTIMER1_WIDTH = 41;
*pTIMER1_CONFIG = 0x00a9;
*pTIMER2_PERIOD = 150150;
*pTIMER2_WIDTH = 5250;
*pTIMER2_CONFIG = 0x00a9;
}

void PPI_TMR_DMA_Enable(void)
{
*pDMA0_CONFIG |= 0x1;
asm(“ssync;”);
InitTimer();
*pPPI_CONTROL |= 0x1;
asm(“ssync;”);
*pTIMER_ENABLE|= 0x0006;
asm(“ssync;”);
}

void PPI_TMR_DMAR_Disable(void)
{
*pDMA0_CONFIG &= (~0x1);
*pPPI_CONTROL &= (~0x1);
}

void RGB888_RGB565( BMPIMAGE* img, unsigned char dst,float zox,float zoy)
{
int i = 0;
int j = 0;
int m=0;
int oxsize;
int oysize;
int tempsize;
if((zox>=1)&&(zoy>=1))
{
oxsize = (3
(img->infohead.BiWidth-480))/2;
oysize = (img->infohead.BiHeight-272)/2;
tempsize = img->infohead.BiWidth3;
oysize = oysize
tempsize;
for(i=0;i<272;i++)
{
for(j=0;j<1440;j+=3)
{
dst[m+1] = img->imgbuf[oxsize+oysize+itempsize+j+2] &0xf8;
dst[m+1] |= ((img->imgbuf[oxsize+oysize+i
tempsize+j+1]>>5) & 0x07);//GH
dst[m] = ((img->imgbuf[oxsize+oysize+itempsize+j+1]<<3) & 0xe0); //GL
dst[m] |= ((img->imgbuf[oxsize+oysize+i
tempsize+j]>>3) &0x1f); //r
m += 2;
}
}
}
else if(zox<1&&zoy<1)
{
oxsize = 480-img->infohead.BiWidth;
tempsize = img->infohead.BiWidth*3;
oysize = 272 - img->infohead.BiHeight;
oysize = oysize/2;
for(i=0;iinfohead.BiHeight;i++)
{
m=0;
for(j=0;j<tempsize;j+=3)
{
dst[(oysize+i)960+m+oxsize+1] = img->imgbuf[itempsize+j+2]&0xf8;
dst[(oysize+i)960+m+oxsize+1] |=((img->imgbuf[itempsize+j+1]>>5) & 0x07);
dst[(oysize+i)960+m+oxsize] = ((img->imgbuf[itempsize+j+1]<<3) & 0xe0); //GL
dst[(oysize+i)960+m+oxsize] |= ((img->imgbuf[itempsize+j]>>3) &0x1f); //r
m += 2;
}
}
}
else
{
printf(“LCD view Failure\n\r”);
LCDBK_Disable();

}

}

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

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

相关文章

JUnit 测试框架

JUnit注解test 注解BeforeEach 注解BeforeAll AfterEachAfterAll断言assertEqualsassertNotEqualsassertTrue用例执行顺序测试套件指定类&#xff0c;添加到套件中并执行一次添加一个包的类参数化单参数多参数借助文件动态参数注解 test 注解 通过对方法加上 test 注解&#…

[附源码]计算机毕业设计二手书店设计论文Springboot程序

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; Springboot mybatis MavenVue等等组成&#xff0c;B/S模式…

DocArray 0.20.0 发布!新增 Milvus 后端支持,更好地嵌套数据搜索,新增 RGB-D 格式的 3D 模型表示

DocArray 是一个用于处理、传输和存储多模态数据的 Python 工具包。DocArray 提供便捷的多模态数据处理功能&#xff0c;具备基于 Protobuf 提供高性能的网络传输性能&#xff0c;同时也为多种向量存储方案提供统一的 API 接口。 GitHub&#xff1a;github.com/docarray/docar…

外包公司面试门槛高吗?软件测试员进外包公司容易吗?

虽然很多测试人员都抵制外包&#xff0c;但实际情况则是依旧有大量软件测试员&#xff0c;选择加入到外包这个圈子。外包公司面试门槛高吗?外包公司容易进吗?本篇来解答一下这个问题。 外包公司面试门槛高吗&#xff1f; 外包的面试门槛&#xff0c;相对大厂要低很多。尤其…

二、Docker 阿里云镜像加速

1、为什么需要增加镜像加速 咱们先看运行 hello word 都干了哪些事情 "Unable to find image hello-world:latest locally" 是说本地没有hello-world 这个images(镜像) "latest: Pulling from library/hello-world" 本地没有那就得去拉取 这段是拉取 i…

尚医通-MyBatisPlus:查询-删除(四)

&#xff08;1&#xff09;MyBatis-简单查询-分页查询 &#xff08;2&#xff09;MyBatisPlus删除与逻辑删除 &#xff08;1&#xff09;MyBatis-简单查询-分页查询 1.1通过多个id批量查询 完成了动态sql的foreach的功能 //多个id批量查询Testpublic void testSelect1() { …

C++ 入门篇之类 对象的关系

&#x1f4d2;博客主页&#xff1a; ​​开心档博客主页​​ &#x1f389;欢迎关注&#x1f50e;点赞&#x1f44d;收藏⭐留言&#x1f4dd; &#x1f4cc;本文由开心档原创&#xff01; &#x1f4c6;51CTO首发时间&#xff1a;&#x1f334;2022年12月12日&#x1f334; ✉…

docker(3):镜像分层原理

目录UnionFS&#xff08;联合文件系统&#xff09;docker镜像加载原理分层理解commit镜像docker中&#xff0c;镜像是一种轻量级、可执行的独立软件包&#xff0c;用来打包软件运行环境和基于运行环境开发的软件&#xff0c;它包含运行某个软件所需的所有内容、包括代码、运行时…

【计算机网络】HTTP首部详解

HTTP首部详解HTTP 协议的请求和响应报文中必定包含 HTTP 首部。首部内容为客户端和服务端分别处理请求和响应提供所需要的信息。对于客户端用户来说&#xff0c;这些信息中的大部分内容都无需亲自查看。 1.HTTP请求报文 2.HTTP响应报文 3.首部字段类型 3.1 通用首部字段 首部…

在线CAD-梦想云图Node.JS服务

说明 后台提供梦想Node.JS服务&#xff0c;方便调用控件后台功能&#xff0c;Bin/MxDrawServer的安装目录中有Linux和Windows两个文件夹&#xff0c;用户可以根据自己的操作系统下载对应的程序。 启动服务 Windows:进入Bin\MxDrawServer\Windows目录&#xff0c;运行start.ba…

大数据毕业设计 新闻分类算法实现

文章目录1 简介1.1 本文章博主将介绍:2 参与及比较算法3 先说结论4 实现过程4.1 数据爬取4.2 数据预处理5 CNN文本分类6 最后1 简介 &#x1f525; Hi&#xff0c;大家好&#xff0c;这里是丹成学长的毕设系列文章&#xff01; &#x1f525; 对毕设有任何疑问都可以问学长哦…

JUC并发编程详解

JUC并发编程详解一、Callable接口二、ReentrantLock类三、原子类四、线程池五、信号量Semaphore六、闭锁CountDownLatch七、线程安全的集合类7.1 多线程环境使用 ArrayList7.2 多线程环境使用队列7.3 多线程环境使用哈希表JUC > java.util.concurrent&#xff0c;这个包里放…

【AI with ML】第 1 章 :TensorFlow 简介

&#x1f50e;大家好&#xff0c;我是Sonhhxg_柒&#xff0c;希望你看完之后&#xff0c;能对你有所帮助&#xff0c;不足请指正&#xff01;共同学习交流&#x1f50e; &#x1f4dd;个人主页&#xff0d;Sonhhxg_柒的博客_CSDN博客 &#x1f4c3; &#x1f381;欢迎各位→点赞…

python使用bs模块爬取小说数据

目录 一、BS模块介绍 二、分析页面架构 三、代码实现 四、结果展示 五、总结思路 一、BS模块介绍 Beautiful Soup提供一些简单的、python式的函数用来处理导航、搜索、修改分析树等功能。它是一个工具箱&#xff0c;通过解析文档为用户提供需要抓取的数据…

【云计算与大数据技术】Hadoop MapReduce的讲解(图文解释,超详细必看)

一、Hadoop MapReduce架构 MapReduce 是一种分布式计算框架,能够处理大量数据 ,并提供容错 、可靠等功能 , 运行部署在大规模计算集群中&#xff0c;MapReduce计算框架采用主从架构&#xff0c;由 Client、JobTracker、TaskTracker组成 Client的作用 用户编写 MapReduce程序…

Debye-Wolf积分计算器

摘要 众所周知&#xff0c;Debye-Wolf积分可用于以半解析方式计算焦平面附近的矢量场。Debye-Wolf积分通常用作分析高数值孔径显微镜成像情况的基本工具。它是基于理想模型&#xff0c;因此不需要待求镜头精确规格的知识。该用例将解释如何在VirtualLab Fusion中使用Debye-Wolf…

Guitar Pro8更新了多达30项功能优化

很多人在听到Guitar Pro这个名词时&#xff0c;本能反应就是跟吉他有关的软件吧&#xff0c;但是具体是什么样子&#xff0c;有什么功能我们却不一定知道的那么详细&#xff0c;下面呢&#xff0c;我们就来详细的介绍下Guitar Pro这款软件。 Guitar Pro是初学作曲&#xff0c;特…

openlayers百万级和千万级数据量的矢量切片在渲染过程中的技术难点解析

目录1 前言2 数据介绍3 切片方案及技术难点3.1 大数据量图层矢量切片无法正确返回结果3.2 矢量切片标注过程中标注拥挤3.3 矢量切片每一块切片都进行了标注&#xff0c;形成了冗余3.4 矢量切片标注的随机性会造成时而在中央&#xff0c;时而在边界上3.5 特殊样式的制作3.6 图层…

Jmeter(九):jmeter_逻辑控制器_事务控制器HTTP Cookie管理器

Jmeter(19)&#xff1a;jmeter_逻辑控制器_事务控制器 事务&#xff1a; 性能测试中&#xff0c;事务指的是从端到端&#xff0c;一个完整的操作过程&#xff0c;比如一次登录、一次 筛选条件查询&#xff0c;一次支付等&#xff1b;技术上讲&#xff1a;事务就是由1个或多个…

C# Spire.Xls将DataTable导出到Excel并加密

背景需求&#xff1a; 页面展示信息列表&#xff0c;需要将数据导出到Excel并加密sheet文件和工作簿结构。 代码思路&#xff1a;1.将数据转换为dataTable&#xff0c;2.将dataTable导出到Excel&#xff0c;3.处理加密。 文章目录引入必要的dll文件1.将数据转换为DataTable2.将…