View->Bitmap缩放到自定义ViewGroup的任意区域(Matrix方式绘制Bitmap)
Bitmap
缩放和平移
- 加载一张
Bitmap
可能为宽高相同的正方形,也可能为宽高不同的矩形 - 缩放方向可以为中心缩放,左上角缩放,右上角缩放,左下角缩放,右下角缩放
Bitmap
中心缩放,包含了缩放和平移两个操作,不可拆开Bitmap
其余四个方向的缩放,可以单独缩放不带平移,也可以缩放带平移
XML
文件
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"><com.yang.app.MyRelativeLayoutandroid:id="@+id/real_rl"android:layout_width="match_parent"android:layout_height="0dp"android:layout_weight="1"android:layout_marginTop="30dp"android:layout_marginBottom="30dp"android:layout_marginLeft="30dp"android:layout_marginRight="30dp"android:background="@color/gray"><com.yang.app.MyImageViewandroid:id="@+id/real_iv"android:layout_width="match_parent"android:layout_height="match_parent"android:layout_marginTop="30dp"android:layout_marginBottom="30dp"android:layout_marginLeft="30dp"android:layout_marginRight="30dp" /></com.yang.app.MyRelativeLayout><ImageViewandroid:layout_width="match_parent"android:layout_height="200dp"android:layout_weight="0"android:background="#00ff00" />
</LinearLayout>
Activity
代码
const val TAG = "Yang"
class MainActivity : AppCompatActivity() {var mRealView : MyImageView ?= nullvar mRelativeLayout : MyRelativeLayout ?= nullvar tempBitmap : Bitmap ?= nullvar mHandler = Handler(Looper.getMainLooper())var screenWidth = 0var screenHeight = 0var srcRect = RectF()var destRect = RectF()override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContentView(R.layout.activity_main)mRealView = findViewById(R.id.real_iv)mRelativeLayout = findViewById(R.id.real_rl)// 屏幕宽高的一半作为临时RectF, 用于压缩BitmapscreenWidth = resources.displayMetrics.widthPixelsscreenHeight = resources.displayMetrics.heightPixelsval tempRect = RectF(0f, 0f, screenWidth.toFloat() / 2, screenHeight.toFloat() / 2)CoroutineScope(Dispatchers.IO).launch {tempBitmap = getBitmap(resources, tempRect, R.drawable.fake)withContext(Dispatchers.Main) {mRelativeLayout?.post {// 获取初始区域的RectFsrcRect.set(0f,0f,mRelativeLayout?.width?.toFloat()!!,mRelativeLayout?.height?.toFloat()!!)// 获取结束区域的RectFmRelativeLayout?.forEach { childView ->if (childView is MyImageView) {destRect.set(0f,0f,childView.width.toFloat(),childView.height.toFloat())}}scaleRectFun(tempBitmap, srcRect, destRect)}}}}fun scaleRectFun(tempBitmap: Bitmap?, srcRect : RectF, destRect: RectF){tempBitmap?.let { bitmap->mRelativeLayout?.setBitmap(bitmap)val animator = ValueAnimator.ofFloat(0f, 1f)animator.duration = 5000Lanimator.interpolator = DecelerateInterpolator()animator.addUpdateListener {val value = it.animatedValue as Float// 中心缩放mRelativeLayout?.setDestRectCenterWithTranslate(srcRect, destRect, value)// 左上角不带平移缩放// mRelativeLayout?.setDestRectLeftTopNoTranslate(srcRect, destRect, value)// 左上角平移缩放// mRelativeLayout?.setDestRectLeftTopWithTranslate(srcRect, destRect, value)// 右上角不带平移缩放// mRelativeLayout?.setDestRectRightTopNoTranslate(srcRect, destRect, value)// 右上角平移缩放// mRelativeLayout?.setDestRectRightTopWithTranslate(srcRect, destRect, value)// 左下角不带平移缩放// mRelativeLayout?.setDestRectLeftBottomNoTranslate(srcRect, destRect, value)// 左下角平移缩放// mRelativeLayout?.setDestRectLeftBottomWithTranslate(srcRect, destRect, value)// 右下角不带平移缩放// mRelativeLayout?.setDestRectRightBottomNoTranslate(srcRect, destRect, value)// 右下角平移缩放// mRelativeLayout?.setDestRectRightBottomWithTranslate(srcRect, destRect, value)}animator.start()}}
}
fun getBitmap(resources : Resources, destRect : RectF, imageId: Int): Bitmap? {var imageWidth = -1var imageHeight = -1val preOption = BitmapFactory.Options().apply {// 只获取图片的宽高inJustDecodeBounds = trueBitmapFactory.decodeResource(resources, imageId, this)}imageWidth = preOption.outWidthimageHeight = preOption.outHeight// 计算缩放比例val scaleMatrix = Matrix()// 确定未缩放Bitmap的RectFvar srcRect = RectF(0f, 0f, imageWidth.toFloat(), imageHeight.toFloat())// 通过目标RectF, 确定缩放数值,存储在scaleMatrix中scaleMatrix.setRectToRect(srcRect, destRect, Matrix.ScaleToFit.CENTER)// 缩放数值再映射到原始Bitmap上,得到缩放后的RectFscaleMatrix.mapRect(srcRect)val finalOption = BitmapFactory.Options().apply {if (imageHeight > 0 && imageWidth > 0) {inPreferredConfig = Bitmap.Config.RGB_565inSampleSize = calculateInSampleSize(imageWidth,imageHeight,srcRect.width().toInt(),srcRect.height().toInt())}}return BitmapFactory.decodeResource(resources, imageId, finalOption)
}fun calculateInSampleSize(fromWidth: Int, fromHeight: Int, toWidth: Int, toHeight: Int): Int {var bitmapWidth = fromWidthvar bitmapHeight = fromHeightif (fromWidth > toWidth|| fromHeight > toHeight) {var inSampleSize = 2// 计算最大的inSampleSize值,该值是2的幂,并保持原始宽高大于目标宽高while (bitmapWidth >= toWidth && bitmapHeight >= toHeight) {bitmapWidth /= 2bitmapHeight /= 2inSampleSize *= 2}return inSampleSize}return 1
}
自定义ViewGroup
和View
代码
class MyImageView @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
) : AppCompatImageView(context, attrs, defStyleAttr)class MyRelativeLayout @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
) : RelativeLayout(context, attrs, defStyleAttr) {var mBitmap : Bitmap ?= nullvar mScaleMatrix = Matrix()var mDestRect = RectF()fun setBitmap(bitmap: Bitmap?) {mBitmap = bitmap}override fun onDraw(canvas: Canvas?) {super.onDraw(canvas)mBitmap?.let {canvas?.drawBitmap(it, mScaleMatrix, Paint().apply {isAntiAlias = true})}}
}
中心缩放
ValueAnimator
动画的初始值为0,开始区域为外层MyRelativeLayout
区域,结束区域为内层MyImageView
区域,缩放区域在这两个区域大小之间变化- 缩放比例取决于当前缩放区域
mDestRect
和Bitmap
宽高的最小宽高比
fun setDestRectCenterWithTranslate(srcRect: RectF, destRect: RectF, value : Float) {mDestRect = RectF(srcRect.left + (destRect.left - srcRect.left) * value,srcRect.top + (destRect.top - srcRect.top) * value,srcRect.right + (destRect.right - srcRect.right) * value,srcRect.bottom + (destRect.bottom - srcRect.bottom) * value)val scale = Math.min(mDestRect.width() / mBitmap?.width!!, mDestRect.height() / mBitmap!!.height)val dx = (srcRect.width() - mBitmap?.width!! * scale) / 2val dy = (srcRect.height() - mBitmap?.height!! * scale) / 2mScaleMatrix.reset()mScaleMatrix.postScale(scale, scale)mScaleMatrix.postTranslate(dx, dy)invalidate()
}
- 中心缩放效果图
左上角缩放
- 左上角不带平移缩放
fun setDestRectLeftTopNoTranslate(srcRect: RectF, destRect: RectF, value : Float) {mDestRect = RectF(srcRect.left + (destRect.left - srcRect.left) * value,srcRect.top + (destRect.top - srcRect.top) * value,srcRect.right + (destRect.right - srcRect.right) * value,srcRect.bottom + (destRect.bottom - srcRect.bottom) * value)val scale = Math.min(mDestRect.width() / mBitmap?.width!!, mDestRect.height() / mBitmap!!.height)mScaleMatrix.setScale(scale, scale)invalidate()
}
-
左上角不带平移缩放效果图
-
左上角带平移缩放
fun setDestRectLeftTopWithTranslate(srcRect: RectF, destRect: RectF, value : Float) {mDestRect = RectF(srcRect.left + (destRect.left - srcRect.left) * value,srcRect.top + (destRect.top - srcRect.top) * value,srcRect.right + (destRect.right - srcRect.right) * value,srcRect.bottom + (destRect.bottom - srcRect.bottom) * value)val scale = Math.min(mDestRect.width() / mBitmap?.width!!, mDestRect.height() / mBitmap!!.height)val dx = ((srcRect.width() - destRect.width())/2) * value + (destRect.left - srcRect.left) * valueval dy = ((srcRect.height() - destRect.height())/2) * value + (destRect.top - srcRect.top) * valuemScaleMatrix.reset()mScaleMatrix.postScale(scale, scale)mScaleMatrix.postTranslate(dx, dy)invalidate()
}
- 左上角带平移缩放效果图
右上角缩放
- 右上角不带平移缩放
fun setDestRectRightTopNoTranslate(srcRect: RectF, destRect: RectF, value : Float) {mDestRect = RectF(srcRect.left + (destRect.left - srcRect.left) * value,srcRect.top + (destRect.top - srcRect.top) * value,srcRect.right + (destRect.right - srcRect.right) * value,srcRect.bottom + (destRect.bottom - srcRect.bottom) * value)val scale = Math.min(mDestRect.width() / mBitmap?.width!!, mDestRect.height() / mBitmap!!.height)val dx = srcRect.width() - mBitmap!!.width * scaleval dy = 0fmScaleMatrix.reset()mScaleMatrix.postScale(scale, scale)mScaleMatrix.postTranslate(dx, dy)invalidate()
}
- 右上角不带平移缩放效果图
- 右上角带平移缩放
fun setDestRectRightTopWithTranslate(srcRect: RectF, destRect: RectF, value : Float) {mDestRect = RectF(srcRect.left + (destRect.left - srcRect.left) * value,srcRect.top + (destRect.top - srcRect.top) * value,srcRect.right + (destRect.right - srcRect.right) * value,srcRect.bottom + (destRect.bottom - srcRect.bottom) * value)val scale = Math.min(mDestRect.width() / mBitmap?.width!!, mDestRect.height() / mBitmap!!.height)val dx = ((srcRect.width() - destRect.width())/2) * value + (destRect.left - srcRect.left) * valueval dy = ((srcRect.height() - destRect.height())/2) * value + (destRect.top - srcRect.top) * valuemScaleMatrix.reset()mScaleMatrix.postScale(scale, scale)mScaleMatrix.postTranslate(dx, dy)invalidate()
}
- 右上角不带平移缩放效果图
左下角缩放
- 左下角不带平移缩放
fun setDestRectLeftBottomNoTranslate(srcRect: RectF, destRect: RectF, value : Float) {mDestRect = RectF(srcRect.left + (destRect.left - srcRect.left) * value,srcRect.top + (destRect.top - srcRect.top) * value,srcRect.right + (destRect.right - srcRect.right) * value,srcRect.bottom + (destRect.bottom - srcRect.bottom) * value)val scale = Math.min(mDestRect.width() / mBitmap?.width!!, mDestRect.height() / mBitmap!!.height)val dx = 0fval dy = srcRect.height() - mBitmap?.height!! * scalemScaleMatrix.reset()mScaleMatrix.postScale(scale, scale)mScaleMatrix.postTranslate(dx, dy)invalidate()
}
- 左下角不带平移缩放效果图
- 左下角平移缩放
fun setDestRectLeftBottomWithTranslate(srcRect: RectF, destRect: RectF, value : Float) {mDestRect = RectF(srcRect.left + (destRect.left - srcRect.left) * value,srcRect.top + (destRect.top - srcRect.top) * value,srcRect.right + (destRect.right - srcRect.right) * value,srcRect.bottom + (destRect.bottom - srcRect.bottom) * value)val scale = Math.min(mDestRect.width() / mBitmap?.width!!, mDestRect.height() / mBitmap!!.height)val dx = ((srcRect.width() - destRect.width())/2 )* valueval dy = ((srcRect.height() - destRect.height())/2 )* value + (destRect.bottom - srcRect.bottom) * value + (srcRect.height()- mBitmap?.height!! * scale)mScaleMatrix.reset()mScaleMatrix.postScale(scale, scale)mScaleMatrix.postTranslate(dx, dy)invalidate()
}
- 左下角平移缩放效果图
右下角缩放
- 右下角不带平移缩放
fun setDestRectRightBottomNoTranslate(srcRect: RectF, destRect: RectF, value : Float) {mDestRect = RectF(srcRect.left + (destRect.left - srcRect.left) * value,srcRect.top + (destRect.top - srcRect.top) * value,srcRect.right + (destRect.right - srcRect.right) * value,srcRect.bottom + (destRect.bottom - srcRect.bottom) * value)val scale = Math.min(mDestRect.width() / mBitmap?.width!!, mDestRect.height() / mBitmap!!.height)val dx = srcRect.width() - mBitmap!!.width * scaleval dy = srcRect.height() - mBitmap?.height!! * scalemScaleMatrix.reset()mScaleMatrix.postScale(scale, scale)mScaleMatrix.postTranslate(dx, dy)invalidate()
}
- 右下角不带平移缩放效果图
- 右下角平移缩放
fun setDestRectRightBottomWithTranslate(srcRect: RectF, destRect: RectF, value : Float) {mDestRect = RectF(srcRect.left + (destRect.left - srcRect.left) * value,srcRect.top + (destRect.top - srcRect.top) * value,srcRect.right + (destRect.right - srcRect.right) * value,srcRect.bottom + (destRect.bottom - srcRect.bottom) * value)val scale = Math.min(mDestRect.width() / mBitmap?.width!!, mDestRect.height() / mBitmap!!.height)val dx = ((srcRect.width() - destRect.width())/2 )* valueval dy = ((srcRect.height() - destRect.height())/2 )* value + (destRect.bottom - srcRect.bottom) * value + (srcRect.height()- mBitmap?.height!! * scale)mScaleMatrix.reset()mScaleMatrix.postScale(scale, scale)mScaleMatrix.postTranslate(dx, dy)invalidate()
}
- 右下角平移缩放效果图
相关文章:

View->Bitmap缩放到自定义ViewGroup的任意区域(Matrix方式绘制Bitmap)
Bitmap缩放和平移 加载一张Bitmap可能为宽高相同的正方形,也可能为宽高不同的矩形缩放方向可以为中心缩放,左上角缩放,右上角缩放,左下角缩放,右下角缩放Bitmap中心缩放,包含了缩放和平移两个操作…...

Centos 7部署NTP
介绍 NTP是Network Time Protocol(网络时间协议)的简称,它是用来通过互联网或局域网将计算机时钟同步到世界协调时间(UTC)的协议。 安装 # yum安装 yum install -y ntp# 离线安装 #下载地址:https://mir…...

【前缀和】42. 接雨水
本文涉及知识点 C算法:前缀和、前缀乘积、前缀异或的原理、源码及测试用例 包括课程视频 LeetCode42. 接雨水 给定 n 个非负整数表示每个宽度为 1 的柱子的高度图,计算按此排列的柱子,下雨之后能接多少雨水。 示例 1: 输入&am…...
我的名字叫大数据
第1章 大家好,我叫大数据 1.1 我的家族传统:从我小小的祖先到壮大的我 1.1.1 最初的我:原始部落里的计数石头 大家好,我是你们人类文明的“老朋友”——大数据。你们知道吗?在我还没有变成你们手机、电脑里飞速跑动的那些数字前,我最初的模样可是一块块“计数石头”。…...
数据库漫谈-infomix
infomix数据库知名度不高,主要跟它的定位有关,它主要用于unix操作系统:Informix便是取自Information和Unix的结合,它也是第一个支持linux系统的数据库。它其实在金融、电信行业使用率非常高。98年,当时我在做银行领域的…...

【Qt】Qt界面美化指南:深入理解QSS样式表的应用与实践
文章目录 前言:1. 背景介绍2. 基本语法3. QSS 设置方式3.1. 设置全局样式3.2. 从文件加载样式表3.3. 使用 Qt Designer 编辑样式 总结: 前言: 在当今这个视觉至上的时代,用户界面(UI)的设计对于任何软件产…...

七彩云南文化旅游网站的设计
管理员账户功能包括:系统首页,个人中心,管理员管理,游客管理,导游管理,旅游景点管理,酒店信息管理 前台账户功能包括:系统首页,个人中心,论坛,旅…...

7-zip安装教程
一、简介 7-Zip 是一款开源的文件压缩软件,由 Igor Pavlov 开发。它具有高压缩比、支持多种格式、跨平台等特点。使用 C语言编写,其代码在 Github 上开源。 7-Zip的官网: 7-Zip 7-zip官方中文网站: 7-Zip 官方中文网站 7-Zip 的 G…...

oracle 12c DB卸载流程
1.运行卸载程序 [rootprimary1 ~]# su - oracle [oracleprimary1 ~]$ cd $ORACLE_HOME/deinstall [oracleprimary1 deinstall]$ ./deinstall Checking for required files and bootstrapping ... Please wait ... 这里选择3 、回车、y、y、回车、ASM 这里输入y 2.删除相关目录…...

Docker学习笔记 - 创建自己的image
目录 基本概念常用命令使用docker compose启动脚本创建自己的image 使用Docker是现在最为流行的软件发布方式, 本系列将阐述Docker的基本概念,常用命令,启动脚本和如何生产自己的docker image。 在我们发布软件时,往往需要把我…...

java web爬虫
目录 读取本地文件 从网站读取文件 java爬虫 总结 读取本地文件 import java.io.File; import java.io.PrintWriter; import java.util.Scanner;public class ReplaceText {public static void main() throws Exception{File file new File("basic\\test.txt"…...
MySQL开发教程和具体应用案例
一、MySQL开发教程 初识数据库 定义:数据仓库,安装在操作系统之上,用于存储和管理数据。 分类:关系型数据库(如MySQL、Oracle、SQL Server)和非关系型数据库(如Redis、MongoDB)。 SQL:结构化查询语言,用于管理和操作关系型数据库。 操作数据库 创建、修改、删除…...

QT C++ 模型视图结构 QTableView 简单例子
在Qt中,MVC模式被广泛使用于各种用户界面框架中,包括Qt的模型视图结构。Qt的模型视图结构是基于MVC模式设计的,其中包括了Model、View和Delegate三个部分。 QTableView是Qt模型视图结构中的一种视图,它用于以表格形式显示数据。 …...
2024年3月电子学会Python编程等级考试(四级)真题题库
2024年3月青少年软件编程Python等级考试(四级)真题试卷 题目总数:38 总分数:100 选择题 第 1 题 单选题 运行如下Python代码,若输入整数3,则最终输出的结果为?( ÿ…...

深入分析 Android BroadcastReceiver (一)
文章目录 深入分析 Android BroadcastReceiver (一)1. Android BroadcastReceiver 设计说明1.1 BroadcastReceiver 的主要用途 2. BroadcastReceiver 的工作机制2.1 注册 BroadcastReceiver2.1.1 静态注册2.1.2 动态注册 3. BroadcastReceiver 的生命周期4. 实现和使用 Broadca…...

2024医美如何做抖音医美抖音号,本地团购、短视频直播双ip爆品引流,实操落地课
课程下载:https://download.csdn.net/download/m0_66047725/89307619 更多资源下载:关注我。 课程内容: 01-0-序.mp4 02-01-账号定位.mp4 03-02-误区.mp4 04-03-五件套.mp4 05-04-文案怎么来.mp4 06-05-对标怎么弄.mp4 07-06-人设怎…...
Debian常用指令指南:高效管理你的Linux系统
Debian作为Linux发行版中的佼佼者,以其稳定性和安全性而闻名。掌握Debian的常用指令对于系统管理员和开发人员来说至关重要。本文将介绍一系列Debian系统中的常用指令,帮助你高效地管理和维护你的系统。喜欢的话记得一键三连哦,方便找到它。 …...
什么是DELINS交货指示?
DELINS 是指 Delivery Instruction(交货指示)报文,用于在供应链管理中传递交货指令和相关信息。该报文用于在供应链中的不同合作伙伴之间交换关于交货的详细信息。 DELINS 报文的主要功能 交货指示:传达具体的交货指令ÿ…...
基于Open3D的点云处理24-ICP匹配cuda加速
参考:docs/jupyter/t_pipelines/t_icp_registration.ipynb 完整测试用例: import open3d as o3d import open3d.core as o3cif o3d.__DEVICE_API__ == cuda:import open3d.cuda.pybind.t.pipelines.registration as treg else:...

UE_地编教程_创建地形洞材质
个人学习笔记,不喜勿喷。侵权立删! 使用地形洞材质来遮罩地形上特定位置的可视性和碰撞。如要在山脉侧面创建进入洞穴的入口,此操作将非常有用。可使用地形材质和地形洞材质的相同材质,但注意:对比不使用不透明蒙版的…...
Python|GIF 解析与构建(5):手搓截屏和帧率控制
目录 Python|GIF 解析与构建(5):手搓截屏和帧率控制 一、引言 二、技术实现:手搓截屏模块 2.1 核心原理 2.2 代码解析:ScreenshotData类 2.2.1 截图函数:capture_screen 三、技术实现&…...
【Linux】shell脚本忽略错误继续执行
在 shell 脚本中,可以使用 set -e 命令来设置脚本在遇到错误时退出执行。如果你希望脚本忽略错误并继续执行,可以在脚本开头添加 set e 命令来取消该设置。 举例1 #!/bin/bash# 取消 set -e 的设置 set e# 执行命令,并忽略错误 rm somefile…...

基于距离变化能量开销动态调整的WSN低功耗拓扑控制开销算法matlab仿真
目录 1.程序功能描述 2.测试软件版本以及运行结果展示 3.核心程序 4.算法仿真参数 5.算法理论概述 6.参考文献 7.完整程序 1.程序功能描述 通过动态调整节点通信的能量开销,平衡网络负载,延长WSN生命周期。具体通过建立基于距离的能量消耗模型&am…...

【HarmonyOS 5.0】DevEco Testing:鸿蒙应用质量保障的终极武器
——全方位测试解决方案与代码实战 一、工具定位与核心能力 DevEco Testing是HarmonyOS官方推出的一体化测试平台,覆盖应用全生命周期测试需求,主要提供五大核心能力: 测试类型检测目标关键指标功能体验基…...
Objective-C常用命名规范总结
【OC】常用命名规范总结 文章目录 【OC】常用命名规范总结1.类名(Class Name)2.协议名(Protocol Name)3.方法名(Method Name)4.属性名(Property Name)5.局部变量/实例变量(Local / Instance Variables&…...

DBAPI如何优雅的获取单条数据
API如何优雅的获取单条数据 案例一 对于查询类API,查询的是单条数据,比如根据主键ID查询用户信息,sql如下: select id, name, age from user where id #{id}API默认返回的数据格式是多条的,如下: {&qu…...

pikachu靶场通关笔记22-1 SQL注入05-1-insert注入(报错法)
目录 一、SQL注入 二、insert注入 三、报错型注入 四、updatexml函数 五、源码审计 六、insert渗透实战 1、渗透准备 2、获取数据库名database 3、获取表名table 4、获取列名column 5、获取字段 本系列为通过《pikachu靶场通关笔记》的SQL注入关卡(共10关࿰…...

[ACTF2020 新生赛]Include 1(php://filter伪协议)
题目 做法 启动靶机,点进去 点进去 查看URL,有 ?fileflag.php说明存在文件包含,原理是php://filter 协议 当它与包含函数结合时,php://filter流会被当作php文件执行。 用php://filter加编码,能让PHP把文件内容…...

Chrome 浏览器前端与客户端双向通信实战
Chrome 前端(即页面 JS / Web UI)与客户端(C 后端)的交互机制,是 Chromium 架构中非常核心的一环。下面我将按常见场景,从通道、流程、技术栈几个角度做一套完整的分析,特别适合你这种在分析和改…...

企业大模型服务合规指南:深度解析备案与登记制度
伴随AI技术的爆炸式发展,尤其是大模型(LLM)在各行各业的深度应用和整合,企业利用AI技术提升效率、创新服务的步伐不断加快。无论是像DeepSeek这样的前沿技术提供者,还是积极拥抱AI转型的传统企业,在面向公众…...