自定义视图:图形与图像的处理(二):绘图

        除了使用已有的图片之外,Android应用还常常需要在运行时动态地生成图片,比如一个手机游戏,游戏界面看上去丰富多彩,而且可以随着用户动作而动态改变,这就需要借助于Android的绘图支持了。

1. Android绘图基础:Canvas、Paint等

        Android的绘图应该继承View组件,并重写它的onDraw (Canvas canvas)方法即可。

        重写onDraw (Canvas canvas)方法时涉及一个绘图APl:Canvas,Canvas代表“依附"于指定View的画布,它提供了如表所示的方法来绘制各种图形。

方法签名简要说明
drawArc(RectF oval, float startAngle, float sweepAngle, boolean useCenter, Paint paint)绘制弧
drawBitmap(Bitmap bitmap, Rect src, Rect dst, Paint paint)在指定点绘制从源位图中“挖取”的一块
drawBitmap(Bitmap bitmap, float left, float top, Paint paint)在指定点绘制位图
drawCircle(float cx, float cy, float radius, Paint paint)在指定点绘制一个圆
drawLine(float startX, float startY, float stopX, float stopY, Paint paint)绘制一条直线
drawLines(float[pts,int offset, int count,Paint paint)绘制多条直线
drawOval(RectF oval, Paint paint)绘制椭圆
drawPath(Path path,Paint paint)沿着指定Path 绘制任意形状
drawPoint(float x, float y, Paint paint)绘制一个点
drawPoints(float[] pts, int offset, int count,Paint paint)绘制多个点
drawRect(float left, float top, float right, float bottom, Paint paint)绘制矩形
drawRoundRect(RectF rect, float rx, float ry, Paint paint)绘制圆角矩形
draw Text(String text, int start, int end,Paint paint)绘制字符串
drawTextOnPath(String text, Path path, float hOffset, float vOffset, Paint paint)沿着路径绘制字符串
clipRect(float left, float top, float right, float bottom)剪切一个矩形区域
clipRegion(Region region)剪切指定区域

Canvas还提供了如下方法进行坐标变换

  • rotate (float degrees, float px,float py) :对Canvas执行旋转变换。
  • scale (float sx,float sy,float px,float py) :对Canvas执行缩放变换。
  • skew (float sx, float sy) :对Canvas执行倾斜变换。
  • translate (float dx,float dy):移动Canvas。向右移动dx距离(dx为负数即向左移动);向下移动dy距离(dy为负数即向上移动)。

        Canvas提供的方法还涉及一个API: PaintPaint代表Canvas上的画笔,因此Paint类主要用于设置绘制风格,包括画笔颜色、画笔笔触粗细、填充风格等。Paint提供了如表所示的方法。

方法签名简要说明
setARGB(int a, int r, int g, int b)/setColor(int color)设置颜色
setAlpha(int a)设置透明度
setAntiAlias(boolean aa)设置是否抗锯齿
setColor(int color)设置颜色
setPathEffect(PathEffect effect)设置绘制路径时的路径效果
setShader(Shader shader)设置画笔的填充效果
setShadowLayer(float radius, float dx, float dy, int color)设置阴影
setStrokeWidth(float width)设置画笔的笔触宽度
setStrokeJoin(Paint.Join join)设置画笔转弯处的连接风格
setStyle(Paint.Style style)设置 Paint的填充风格
setTextAlign(Paint.Align align)设置绘制文本时的文字对齐方式
setTextSize(float textSize)设置绘制文本时的文字大小

        在Canvas提供的绘制方法中还用到了一个API: Path,Path代表任意多条直线连接而成的任意图形,当Canvas根据Path绘制时,它可以绘制出任意的形状

1.1 例子

public class MyView extends View {private Path path1 = new Path();private Path path2 = new Path();private Path path3 = new Path();private Path path4 = new Path();private Path path5 = new Path();private Path path6 = new Path();public MyView(Context context, AttributeSet set){super(context,set);}private LinearGradient mShader = new LinearGradient(0f,0f,40f,60f,new int[]{Color.RED,Color.GREEN,Color.BLUE,Color.YELLOW},null, Shader.TileMode.REPEAT);private RectF rect = new RectF();//定义画笔private Paint paint = new Paint();//重写方法,进行绘图@Overrideprotected void onDraw(Canvas canvas) {super.onDraw(canvas);//把整张画布绘制成白色canvas.drawColor(Color.WHITE);//去锯齿paint.setAntiAlias(true);paint.setColor(Color.BLUE);paint.setStyle(Paint.Style.STROKE);paint.setStrokeWidth(4f);int viewWidth = this.getWidth();//绘制圆形canvas.drawCircle(viewWidth/10 + 10,viewWidth/10 + 10, viewWidth / 10, paint);//绘制正方形canvas.drawRect (10 , viewWidth / 5 + 20 , viewWidth / 5 + 10, viewWidth *2/ 5 + 20 , paint) ;//绘制矩形canvas.drawRect (10,viewWidth * 2/ 5 + 30,viewWidth / 5 + 10, viewWidth / 2 + 30, paint);@SuppressLint("DrawAllocation")RectF re1 = new RectF (10,viewWidth / 2 +40, 10 + viewWidth / 5 , viewWidth * 3 / 5 +40) ;//绘制圆角矩形canvas.drawRoundRect (re1, 15,15, paint) ;@SuppressLint("DrawAllocation")RectF re11 = new RectF(10,viewWidth * 3 / 5 + 50,10 + viewWidth / 5 ,viewWidth * 7 / 10 + 50);//绘制椭圆canvas.drawOval(re11, paint) ;//定义一个Path对象,封闭成一个三角形path1.moveTo (10,viewWidth * 9 / 10 + 60);path1.lineTo(viewWidth / 5 + 10,viewWidth * 9 /10 + 60);path1.lineTo (viewWidth / 10 + 10,viewWidth * 7 /10 + 60 );path1.close () ;//根据Path进行绘制,绘制三角形canvas.drawPath (path1, paint);//定义一个 Path对象,封闭成一个五角形path2.moveTo(10 + viewWidth / 15,viewWidth * 9 / 10 + 70);path2.lineTo(10 + viewWidth * 2/ 15,viewWidth * 9 / 10 +70);path2.lineTo(10 + viewWidth / 5, viewWidth + 70);path2.lineTo(10 + viewWidth / 10,viewWidth * 11/10 +70);path2.lineTo (10 , viewWidth + 70);path2.close();//根据Path进行绘制,绘制五角形canvas .drawPath (path2 , paint) ;//----------设置填充风格后绘制-—--------paint.setStyle(Paint.Style.FILL);paint.setColor(Color.RED);//绘制圆形canvas.drawCircle(viewWidth * 3 / 10 + 20,viewWidth / 10 + 10, viewWidth / 10, paint) ;//绘制正方形canvas.drawRect (viewWidth / 5 +20 , viewWidth / 5 +20, viewWidth * 2/ 5 + 20 , viewWidth * 2/ 5 + 20 , paint) ;//绘制矩形canvas.drawRect (viewWidth / 5 + 20,viewWidth * 2/ 5 + 30, viewWidth * 2 / 5 + 20 , viewWidth / 2 + 30,paint);@SuppressLint("DrawAllocation") RectF re2 = new RectF (viewWidth / 5 + 20,viewWidth / 2 + 40,20 + viewWidth * 2 / 5 ,viewWidth * 3 / 5 + 40);//绘制圆角矩形canvas.drawRoundRect (re2,15,15, paint) ;@SuppressLint("DrawAllocation") RectF re21 = new RectF(20 + viewWidth / 5, viewWidth * 3 / 5 + 50,20 + viewWidth * 2/ 5 ,viewWidth * 7 / 10 + 50);//绘制椭圆canvas.drawOval(re21, paint) ;//定义一个Path对象,封闭成一个三角形path3.moveTo(20 + viewWidth / 5,viewWidth * 9 / 10 + 60);path3.lineTo(viewWidth * 2/ 5 + 20,viewWidth * 9 / 10 + 60);path3.lineTo(viewWidth * 3 / 10 + 20,viewWidth * 7 / 10 + 60);path3.close ( ) ;//根据Path进行绘制,绘制三角形canvas.drawPath (path3, paint) ;//定义一个Path对象,封闭成一个五角形path4.moveTo(20 + viewWidth *4 / 15,viewWidth * 9 / 10 + 70);path4.lineTo(20 + viewWidth / 3, viewWidth * 9 / 10 +70);path4.lineTo(20 + viewWidth * 2/ 5, viewWidth + 70);path4.lineTo(20 + viewWidth * 3 / 10,viewWidth * 11/10 + 70);path4.lineTo(20 + viewWidth / 5 , viewWidth + 70);path4.close ( ) ;//根据Path进行绘制,绘制五角形canvas.drawPath (path4, paint) ;//----------设置渐变器后绘制-—------// 为Paint设置渐变器@SuppressLint("DrawAllocation")Shader mShader = new LinearGradient(0,0,40,60,new int[] {Color.RED,Color.GREEN,Color.BLUE,Color.YELLOW }, null , Shader.TileMode.REPEAT);paint.setShader(mShader) ;//设置阴影paint.setShadowLayer (25 , 20 , 20 , Color.GRAY);//绘制圆形canvas.drawCircle (viewWidth / 2 + 30, viewWidth / 10 + 10, viewWidth / 10,paint) ;//绘制正方形canvas.drawRect (viewWidth * 2 / 5 + 30 , viewWidth / 5 + 20, viewWidth * 3 / 5 + 30 , viewWidth * 2/ 5 + 20 , paint);//绘制矩形canvas.drawRect (viewWidth * 2 / 5+ 30,viewWidth * 2/ 5 + 30, viewWidth * 3 / 5 + 30 , viewWidth / 2 + 30,paint);@SuppressLint("DrawAllocation")RectF re3 = new RectF(viewWidth * 2 / 5 + 30,viewWidth / 2 + 40,30 + viewWidth * 3 / 5 , viewWidth * 3 / 5 + 40);//绘制圆角矩形canvas.drawRoundRect (re3, 15,15, paint) ;@SuppressLint("DrawAllocation")RectF re31 = new RectF(30 + viewWidth *2/ 5,viewWidth * 3 / 5 + 50,30 + viewWidth * 3 / 5 , viewWidth * 7 / 10 + 50 ) ;//绘制彬圆canvas.drawOval (re31, paint) ;//定义一个Path对象,封闭成一个三角形path5.moveTo(30 + viewWidth * 2/ 5,viewWidth * 9 / 10 + 60 ) ;path5.lineTo(viewWidth * 3 / 5 + 30,viewWidth * 9 / 10 + 60);path5.lineTo (viewWidth / 2 + 30,viewWidth * 7 / 10 + 60);path5.close();//根据Path进行绘制,绘制三角形canvas .drawPath (path5, paint) ;//定义一个Path对象,封闭成一个五角形path6.moveTo (30 + viewWidth * 7 / 15,viewWidth * 9 / 10 + 70);path6.lineTo(30 + viewWidth * 8 / 15,viewWidth * 9 / 10 + 70);path6.lineTo (30 + viewWidth* 3/ 5,viewWidth + 70);path6.lineTo (30 + viewWidth / 2,viewWidth * 11/10 + 70);path6.lineTo (30 + viewWidth * 2/ 5 , viewWidth + 70 );path6.close ( ) ;//根据Path进行绘制,绘制五角形canvas.drawPath (path6, paint);//----------设置字符大小后绘制paint.setTextSize(48);paint.setShader(null);//绘制7个字符串canvas.drawText(getResources().getString(R.string.circle),60 + viewWidth * 3 / 5, viewWidth / 10 + 10,paint);canvas.drawText(getResources ( ).getString(R.string.square),60 + viewWidth * 3 / 5,viewWidth * 3 / 10 + 20,paint);canvas.drawText (getResources ( ).getString (R.string.rect),60 + viewWidth * 3 / 5, viewWidth * 1 / 2 + 20,paint);canvas.drawText(getResources ( ).getString (R.string.round_rect),60 + viewWidth * 3 / 5,viewWidth * 3 / 5 + 30,paint) ;canvas.drawText (getResources ().getString (R.string.oval),60 + viewWidth * 3 / 5,viewWidth * 7 / 10 + 30,paint);canvas.drawText (getResources ( ).getString (R.string.triangle),60 + viewWidth * 3 / 5, viewWidth * 9 / 10 + 30,paint);canvas.drawText (getResources ( ).getString (R.string.pentagon),60 + viewWidth * 3 / 5,viewWidth * 11 / 10 + 30,paint);}}

        Android的Canvas不仅可以绘制这种简单的几何图形,还可以直接将一个Bitmap绘制到画布上,这样就给了开发者巨大的灵活性,只要前期美工把应用程序所需的图片制作出来,后期开发时把这些图片绘制到Canvas上即可。

1.2 额外知识点

(1). LinearGradient类

        此类实现线性渐变效果,目前只在实现卡拉ok字幕上使用过,就是让歌词随着歌声逐渐变色的效果。

LinearGradient lg = new LinearGradient(0,0,100,100,     new int[]{Color.RED,Color.GREEN,Color.BLUE,Color.WHITE},     null, Shader.TileMode.REPEAT);   

参数说明: 

第一个 起始的x坐标 

第二个 起始的y坐标  

第三个 结束的x坐标   

第四个 结束的y坐标   

 ——以上4个坐标参数除了设置渐变区域,还决定渐变的方向 

第五个 颜色数组,如{#000000,#ffffff}  

第六个 这个也是一个数组,如{0.5f,0.51f}, 

用来指定颜色数组的相对位置, 

取值从0.0f到1.0f按第五个参数的颜色组切分渐变区域  

如果为null 就沿坡度线均匀分布   

——以上2个参数配对出现,第六个如果不设置null,则需对应第五个参数的数组元素个数 

第七个 渲染模式

(2).RectF类

        Rect和RextF都是用来创建一个矩形的,Rect的参数是int型,RectF的参数是float型,由此可以看出RectF比Rect的精确度更高。他们都是通过四个坐标参数来确定矩形的区域。

  • RectF.left 矩形左上角的x坐标。
  • RectF.top 矩形左上角的y坐标。
  • RectF.right 矩形右下角的y坐标。
  • RectF.right 矩形右下角的y坐标。

在这里插入图片描述

2. Path类

        调用Canvas的drawPath (path,paint)方法可沿着路径绘制图形。Android还为路径绘制提供了PathEffect来定义绘制效果,PathEffect包含了如下子类(每个子类代表一种绘制效果)。

  • ComposePathEffect
  • CornerPathEffect
  • DashPathEffect
  • DiscretePathEffect
  • PathDashPathEffect
  • sumPathEffect

        这些绘制效果使用语言来表述总显得有点空洞,下面通过一个程序来让读者理解这些绘制效果。该程序绘制7条路径,分别示范了不使用效果和使用上面6种效果的效果。

2.1 例子

public class Test7Activity extends Activity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(new Test7View(this));}class Test7View extends View{private float phase;private PathEffect[] effects = new PathEffect[7];private int[] colors;private Paint paint = new Paint();//定义创建并初始化Pathprivate Path path = new Path();public Test7View(Context context){super(context);paint.setStyle(Paint.Style.STROKE);paint.setStrokeWidth(4f);path.moveTo(0f,0f);for (int i = 1; i <=40 ; i++) {//生成40个点,随机生成他们的坐标,并将它们连接成一条Pathpath.lineTo(i*25f,(float)(Math.random()*90));}//初始化7种颜色colors = new int[]{Color.BLACK,Color.BLUE,Color.CYAN,Color.GREEN,Color.MAGENTA,Color.RED,Color.YELLOW};//--------下面开始初始化 7 条路径的效果----------//不使用路径效果effects[0]=null;// 使用CornerPathEffecteffects[1]= new CornerPathEffect(10f);// 初始化DiscretePathEffecteffects[2]= new DiscretePathEffect(3.0f,5.0f);}@SuppressLint("DrawAllocation")@Overrideprotected void onDraw(Canvas canvas) {//将背景填充成白色canvas.drawColor(Color.WHITE);//将画布移到(8,8)处开始绘制canvas.translate(8f,8f);//依次使用7种不同的路径效果,7种不同的颜色来绘制路径for (int i = 0; i <effects.length ; i++) {paint.setPathEffect(effects[i]);paint.setColor(colors[i]);canvas.drawPath(path,paint);canvas.translate(0f,90f);}// 初始化DashPathEffecteffects[3] = new DashPathEffect(new float[]{20f,10f,5f,10f},phase);// 初始化PathDashPathEffectPath p = new Path();p.addRect(0f,0f,8f,8f,Path.Direction.CCW);effects[4] = new PathDashPathEffect(p,12f,phase,PathDashPathEffect.Style.ROTATE);// 初始化ComposePathEffecteffects[5] = new ComposePathEffect(effects[2],effects[4]);// 初始化sumPathEffecteffects[6] = new SumPathEffect(effects[4],effects[3]);//改变phase值 ,形成动画效果phase +=1f;invalidate();}}
}

        正如上面的程序中所看到的,当定义DashPathEffect、PathDashPathEffect时可指定一个phase参数该参数用于指定路径效果的相位,当该phase参数改变时,绘制效果也略有变化。上面的程序不停地改变phase参数,并不停地重绘该View组件,这将产生动画效果。

2.2 六条路径效果详解

  • CornerPathEffect:使路径变得圆润

通过将线段之间的任何锐角替换为指定半径的圆角,转换绘制的几何图形(描边或填充式)。          

参数:radius  相当于线段之间的圆角。

  • DiscretePathEffect:类似毛刺一样的效果

官方的解释:            

DiscretePathEffect :切断线段

segmentLength:是指定切断的长度

deviation:为切断之后线段的偏移量随机的,小于等于deviation。

  • DashPathEffect:实线与虚线之间交替

第一个,float intervals[],它是一个数组,这里用来存放,显示的实线与虚线的长度。            其中20和5属于实线 ;两个10属于虚线            

第二个,phase,它是一个偏移的数值,就是左右偏移量,正数向左,负数向右。

  • PathDashPathEffect

// 通过用指定的形状冲压绘制的路径来划线。这仅适用于绘画样式为“描边”或“描边和填充”时的绘图。            

// 如果绘画的样式是填充,那么这个效果会被忽略。绘画的笔划宽度不会影响结果。            

//shape        Path:要踩踏的路径            

//advance    float:形状的每个印章之间的间距            

//phase        float:冲压第一个形状前的偏移量     

//style          PathDashPathEffect.Style:如何在冲压时变换每个位置的形状            

//                  MORPH  ROTATE  TRANSLATE  变形 旋转 平移

  • ComposePathEffect

构建一个PathEffect,其效果是首先应用内部效果和外部pathEffect(例如outer(inner(path))。

// 第一个参数:outerpe 第二个参数:innerpe

  • sumPathEffect

构建一个PathEffect,其效果是依次应用两个效果。(例如第一个(路径)+第二个(路径))

        Canvas还提供了一个drawTextOnPath (String text,Pathpath,float hOffset,float vOffset,Paint paint)方法,该方法可以沿着Path绘制文本。其中hOffset参数指定水平偏移,vOffset参数指定垂直偏移。

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

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

相关文章

微服务、服务网格、Nacos架构与原理

Nacos架构与原理 -服务网格生态-阿里云开发者社区 ------ 该文章用于学习参考,如有侵权,请直接联系下架 服务网格的核心职责:治理“服务通信” 包括但不限于: 功能 举例说明 负载均衡 动态选择服务实例 熔断、重试 某个服务失败时自动切换、重试 流量路由 灰度发布、蓝绿…

STM32——启动过程浅析

总&#xff1a;STM32——学习总纲 参考文件&#xff1a; STM32 MAP文件浅析-V1.1 STM32 启动文件浅析_V1.2 Cortex-M3权威指南(中文)、ARM Cotrex-M3权威指南(英文).zip 一、Map文件解析 1.1 MDK编译过程文件 在编译中&#xff0c;会生成11种编译过程文件&#xff0c;可…

区块链简介

一、区块链简介 狭义上的定义&#xff1a; 区块链是一种链式数据结构&#xff0c;通过按时间顺序将数据块逐一连接形成。这种结构通过密码学确保了数据的不可篡改性和不可伪造性&#xff0c;形成了一种分布式账本技术。 广义上的定义&#xff1a; 区块链技术不仅仅是一种数据…

NestJS中@Injectable装饰器

一、基础定义与核心作用 1.1 什么是Injectable&#xff1f; Injectable() 是 NestJS 依赖注入&#xff08;Dependency Injection, DI&#xff09;系统的核心装饰器&#xff0c;用于将类标记为可注入的提供者&#xff08;Provider&#xff09;。它告知 NestJS 的 IoC&#xff08…

【机器学习深度学习】大模型应用落地:微调与RAG的角色与实践

目录 前言 一、微调与RAG&#xff1a;大模型应用落地的两大支柱 1. 微调&#xff08;Fine-tuning&#xff09; 2. RAG&#xff08;Retrieval-Augmented Generation&#xff09; 二、微调可以做什么&#xff1f; 1. 模型自我认知调整 2. 对话风格优化 3. 提升问题理解能…

List、ArrayList 与顺序表

目录 一、List 介绍 二、线性表 三、自己实现 ArrayList 3.1 显示元素 3.2 增 3.2.1 默认在数组后面新增元素 3.2.2 在指定位置中新增元素 3.3 查 3.4 取值 3.5 改 3.5.1 把 pos 位置的元素修改成 value 3.5.2 删除某个元素 3.5.3 清空 四、认识 ArrayList 4.0 说…

Baumer工业相机堡盟工业相机如何通过YoloV8深度学习模型实现各类垃圾的分类检测识别(C#代码UI界面版)

Baumer工业相机堡盟工业相机如何通过YoloV8深度学习模型实现各类垃圾的分类检测识别&#xff08;C#代码UI界面版&#xff09;工业相机使用YoloV8模型实现各类垃圾的分类检测识别工业相机通过YoloV8模型实现各类垃圾的分类检测识别的技术背景在相机SDK中获取图像转换图像的代码分…

EasyExcel高效工具类:简化Excel导入导出,支持多Sheet与枚举转换

文章目录前言一、依赖坐标二、工具类&#xff1a;ExcelUtil三、测试1.实体类2.前置操作3.单Sheet导出4.单Sheet导入5.多Sheet导出6.多Sheet导入7.完整代码四、扩展&#xff1a;自定义注解实现枚举类型转换1.枚举接口2.枚举类3.注解4.转换类5.使用示例6.测试总结前言 在现代应用…

技术速递|GitHub Copilot for Eclipse 迈出重要一步

我们非常高兴地宣布&#xff1a;2025 年 7 月 22 日&#xff0c;GitHub Copilot for Eclipse 又迈出了重要一步&#xff0c;Eclipse 变得更智能、更快捷&#xff0c;而且与 Eclipse 的集成也更无缝了&#xff01;这是继新功能上线以来&#xff0c;又一次质的提升。 &#x1f…

Coze Loop:开源智能体自动化流程编排平台原理与实践

项目简介 Coze Loop 是 Coze 团队开源的智能体自动化流程编排平台。它以“Loop”为核心概念,支持开发者通过低代码/可视化方式,将多种 AI Agent、插件、API、数据流等灵活编排为自动化工作流,实现复杂的智能体协作、任务自动化和多模态数据处理。Coze Loop 适用于企业自动化…

[GESP202309 四级] 2023年9月GESP C++四级上机题题解,附带讲解视频!

本文为2023年9月GESP C四级的上机题目的详细题解&#xff01;觉得写的不错或者有帮助可以点个赞啦。 目录 题目一讲解视频: 题目二讲解视频: 题目一:进制转换 解题思路: 代码(C): 题目二:变长编码 解题思路: 代码(C): 题目一讲解视频: 2023年9月GESP C四级上机题一题目…

【AI编程工具IDE/CLI/插件专栏】-国外IDE与Cursor能力对比

AI编程专栏(二) - Cursor 深度使用指南 Cursor 深度使用指南(二) - 新能力使用教程 从Trae 2.0与CodeBuddy IDE发布&#xff0c;谈大厂布局IDE 如何选择AI IDE&#xff1f;对比Cursor分析功能差异 AI编程工具IDE/CLI/插件专栏-热门AI编程CLI初识与IDE对 前面文章介绍过了国…

word2vector细致分解(CBOW, SKIP_GRAM, 层次soft Max, 负采样)

1 前世今生&#xff1a;NGRAM NGRAM&#xff1a;将词当成一个离散的单元&#xff08;因此存在一定的局限性&#xff0c;没有考虑到词与词之间的关系&#xff09; neural network language model&#xff1a;只能处理定长序列&#xff0c;训练慢。使用RNN之后有所改善 2 两种训…

Elasticsearch向量库

在Elasticsearch&#xff08;ES&#xff09;最新版本&#xff08;目前8.x系列&#xff09;中&#xff0c;无需额外的“embedding插件”&#xff0c;因为ES从7.14版本开始就原生支持向量数据类型&#xff08;dense_vector&#xff09; 和向量搜索能力&#xff0c;可直接作为向量…

嵌入式学习的第四十四天-ARM

一、ARM内核基础知识1.ALU算术逻辑单元&#xff1b;完成运算的电路2.通用寄存器&#xff1a;R0~R15R13&#xff08;SP&#xff09;&#xff1a;栈指针寄存器&#xff1a;指向栈的指针&#xff08;指向正确的位置&#xff09;&#xff0c;为了保护现场 R14&#xff08;LR…

QML开发:QML中的基本元素

文章目录一、概述二、常用基本元素2.1 基础视觉元素&#xff08;常用于布局和显示&#xff09;2.1.1 元素 Item 的介绍和使用2.1.2 元素 Rectangle 的介绍和使用2.1.3 元素 Image 的介绍和使用2.1.4 元素 Text 的介绍和使用2.2 交互元素&#xff08;用于接收用户操作&#xff0…

Spring AI 项目实战(二十二):Spring Boot + AI +DeepSeek实现智能合同数据问答助手​(附完整源码)

系列文章 序号 文章名称 1 Spring AI 项目实战(一):Spring AI 核心模块入门 2 Spring AI 项目实战(二):Spring Boot + AI + DeepSeek 深度实战(附完整源码) 3 Spring AI 项目实战(三):Spring Boot + AI + DeepSeek 打造智能客服系统(附完整源码) 4

从 0 到 1 创建 InfluxDB 3 表:标签、字段、命名规范一篇讲透

前言 在使用 InfluxDB 3 存储时序数据时,表的设计堪比盖房子打地基,地基打歪,数据“塌方”指日可待。InfluxDB 虽然不是传统意义上的关系型数据库,但它有自己的一套“审美”:标签(Tags)和字段(Fields)是它的双核心,谁先谁后,关系重大,顺序写错,查询性能立马打折。…

[sqlserver] 分析SQL Server中执行效率较低的SQL语句

查询性能分析较低的SQL语句 -- 查询性能分析 SELECT TOP 50qs.creation_time AS [编译时间],qs.last_execution_time AS [最后执行时间],qs.execution_count AS [执行次数],qs.total_worker_time/1000 AS [CPU总时间(ms)],qs.total_elapsed_time/1000 AS [总耗时(ms)],(qs.tota…

SmartX 用户建云实践|宝信软件:搭建“双架构”私有云平台,灵活满足多种业务需求

上海宝信软件股份有限公司&#xff08;以下简称宝信软件&#xff09;系中国宝武实际控制、宝钢股份控股的上市软件企业&#xff0c;是中国领先的工业软件行业应用解决方案和服务提供商&#xff0c;为宝武集团提供整体 IT 基础架构解决方案与服务。为统一管理宝武集团旗下分散在…