Android 13.0 MTK Camera2 设置默认拍照尺寸功能实现
Android 13.0 MTK Camera2 设置默认拍照尺寸功能实现
文章目录
- 需求:
- 参考资料
- 架构图了解
- Camera相关专栏
- 零散知识了解
- 部分相机源码参考,学习API使用,梳理流程,偏应用层
- Camera2 系统相关
- 修改文件-修改方案
- 修改文件:
- 修改内容:
- PictureSize.java onValueInitialized 方法
- PictureSizeHelper.java getCustomDefault 方法
- 源码分析
- 设置拍照尺寸的核心类
- 源码逐步分析
- 关联的照片大小搜索
- PictureSizeSelector
- 进入界面选中的逻辑
- 点击选中图片大小逻辑
- PictureSizeSelectorPreference
- PictureSizeSettingView
- onItemClick
- onPreferenceClick
- PictureSize
- onValueInitialized
- 总结
需求:
默认相机拍照尺寸
需求原因
1)客户自身喜好
2)部分客户自己的摄像头不兼容,比如拍照尺寸太大会卡顿,拉丝等现象
参考资料
Android 13.0 MTK Camera2 设置默认拍照尺寸功能实现
Android 11.0 MTK Camera2 设置默认拍照尺寸功能实现
这两篇文章介绍的蛮好的,可以看看,对于类似需求同理也可以按照改一改? 为什么有些会默认最高分辨率拍照,可能原因在于手机端产品为了最好的拍摄效果,尺寸会默认到最大。
对于Camera2 开发,遇到的困难点就是源码代码量太多,对于很多同事来说就是一脸懵逼,建议多积累一定的代码量,掌握基本的知识。
架构图了解
MTKCamera2相机架构
Camera2架构
Android Camera架构简析
Camera相关专栏
Camera Framework 专栏
小驰私房菜系列
小驰私房菜MTK系列
小驰Camera 开发系列
Camera 相机开发
展讯平台 Camera
官方文档:谷歌官方 API 描述
零散知识了解
MTK 相机UI介绍
Camera2 相机认知
Camera2学习笔记
camera2关于拍照预览方向旋转90度和拍照图片镜像功能实现
Camera2 预览集成、简单拍照:熟悉预览步骤流程比较有用
Camera镜像上下左右颠倒问题的解决办法
MTK相机成像质量差
Camera应用分析
部分相机源码参考,学习API使用,梳理流程,偏应用层
极客相机 Camera2 API
Camera2 API详解
极客相机源码
Camera2 相机Demo
Camera2 专业相机Demo
拍照、预览、录像Demo
使用Camera2 拍照
Camera2 系统相关
Camera2 Service 启动
修改文件-修改方案
修改文件:
\vendor\mediatek\proprietary\packages\apps\Camera2\feature\setting\picturesize\src\com\mediatek\camera\feature\setting\picturesize\PictureSize.java\vendor\mediatek\proprietary\packages\apps\Camera2\feature\setting\picturesize\src\com\mediatek\camera\feature\setting\picturesize\PictureSizeHelper.java
修改内容:
PictureSize.java onValueInitialized 方法
在 onValueInitialized 方法中,默认valueInStore 中调用PictureSizeHelper 类中自定义的 getCustomDefault 方法
if (valueInStore == null) {// Default picture size is the max full-ratio size.
- List<String> entryValues = getEntryValues();
+ LogHelper.d(TAG, "valueInStore == null Default picture size is the max full-ratio size:");
+ /*List<String> entryValues = getEntryValues();for (String value : entryValues) {if (PictureSizeHelper.getStandardAspectRatio(value) == fullRatio) {valueInStore = value;
+ LogHelper.d(TAG, "valueInStore == null:valueInStore:"+valueInStore);break;}
- }
+ }*/
+ valueInStore =PictureSizeHelper.getCustomDefault(getEntryValues());
+ }
PictureSizeHelper.java getCustomDefault 方法
自定义 getCustomDefault 方法,设置默认分辨率。 这里直接写死,或者 根据客需要求设置为最大、最小 等。
public static String getCustomDefault(List<String> supportedEntryValues){for (int i=0;i< supportedEntryValues.size();i++) { /*Size size = valueToSize(supportedEntryValues.get(i));temp = size.width * size.height; if (temp > maxSize) {maxSize = temp;maxIndex = i;}*/LogHelper.d(TAG, "getCustomDefault:" +supportedEntryValues.get(i));}return "1920x1088";}
源码分析
设置拍照尺寸的核心类
\vendor\mediatek\proprietary\packages\apps\Camera2\feature\setting\picturesize\src\com\mediatek\camera\feature\setting\picturesize\PictureSize.java
\vendor\mediatek\proprietary\packages\apps\Camera2\feature\setting\picturesize\src\com\mediatek\camera\feature\setting\picturesize\PictureSizeHelper.java
\vendor\mediatek\proprietary\packages\apps\Camera2\feature\setting\picturesize\src\com\mediatek\camera\feature\setting\picturesize\PictureSizeSettingView.java
源码逐步分析
关联的照片大小搜索
grep -rn 照片大小
找到如下路径相关关键字:照片大小
feature/mode/vsdof/res/values-zh-rCN/strings.xml
<string name="sdof_picture_size_title">"照片大小"</string>feature/setting/picturesize/res/values-zh-rCN/strings.xml<string name="pref_camera_picturesize_title">"照片大小"</string>
PictureSizeSelector
上面已经找到了两个关键字,这里先根据第一个关键字找一下源码:
路径:
/vendor/mediatek/proprietary/packages/apps/Camera2/feature/setting/picturesize/src/com/mediatek/camera/feature/setting/picturesize/PictureSizeSelector.java
R.string.pref_camera_picturesize_title
我们看类定义:
/*** Picture size selector.*/public class PictureSizeSelector extends PreferenceFragment {
就是图片大小选择器
对应的是如下界面:
既然是这个界面,那就看一下点击选中方法和进入这个界面的设置方法
进入界面选中的逻辑
这里关联的有四个方法,对应的进入界面选中逻辑:
@Overridepublic void onCreate(Bundle savedInstanceState) {LogHelper.d(TAG, "[onCreate]");super.onCreate(savedInstanceState);prepareValuesOnShown();Toolbar toolbar = (Toolbar) getActivity().findViewById(R.id.toolbar);if (toolbar != null) {toolbar.setTitle(getActivity().getResources().getString(R.string.pref_camera_picturesize_title));}addPreferencesFromResource(R.xml.picturesize_selector_preference);PreferenceScreen screen = getPreferenceScreen();for (int i = 0 ; i < mEntryValues.size(); i++) {RadioPreference preference = new RadioPreference(getActivity());if (mEntryValues.get(i).equals(mSelectedValue)) {preference.setChecked(true);}LogHelper.d(TAG," onCreate ->mEntryValues.get(i):"+mEntryValues.get(i));preference.setTitle(mTitleList.get(i));preference.setSummary(mSummaryList.get(i));preference.setOnPreferenceClickListener(mOnPreferenceClickListener);screen.addPreference(preference);}}/*** Set the default selected value.** @param value The default selected value.*/public void setValue(String value) {LogHelper.d(TAG," setValue: value->"+value);mSelectedValue = value;}/*** Set the picture sizes supported.** @param entryValues The picture sizes supported.*/public void setEntryValues(List<String> entryValues) {mEntryValues.clear();mEntryValues.addAll(entryValues);}private void prepareValuesOnShown() {List<String> tempValues = new ArrayList<>(mEntryValues);mEntryValues.clear();mTitleList.clear();mSummaryList.clear();for (int i = 0; i < tempValues.size(); i++) {String value = tempValues.get(i);String title = PictureSizeHelper.getPixelsAndRatio(value);LogHelper.d(TAG," prepareValuesOnShown: value->"+value+" title:"+title);if (title != null) {mTitleList.add(title);mEntryValues.add(value);mSummaryList.add(value);}else{LogHelper.d(TAG, "[prepareValuesOnShown] value :"+value+" will not shown.");}}}
方法 | 作用 |
---|---|
setEntryValues | 设置支持的图片大小 分辨率 |
prepareValuesOnShown | 准备显示的数据 在onCreate 方法里面调用的 |
setValue | 设置默认选择的值 |
onCreate | 通过setEntryValue 设置的集合,遍历创建PreferenceScreen ,对于传递进来的value 作为选中效果 |
点击选中图片大小逻辑
对于点击逻辑更为简单,回调 返回上一层,代码如下:
private class MyOnPreferenceClickListener implements Preference.OnPreferenceClickListener {@Overridepublic boolean onPreferenceClick(Preference preference) {String summary = (String) preference.getSummary();int index = mSummaryList.indexOf(summary);String value = mEntryValues.get(index);mListener.onItemClick(value);LogHelper.d(TAG," MyOnPreferenceClickListener: onPreferenceClick value->"+value);mSelectedValue = value;getActivity().getFragmentManager().popBackStack();return true;}}
PictureSizeSelectorPreference
同 PictureSizeSelector 上面已经找到了两个关键字,这里先根据第二个关键字找一下源码:
路径:
./vendor/mediatek/proprietary/packages/apps/Camera2/feature/mode/aicombo/src/com/mediatek/camera/feature/mode/aicombo/photo/view/PictureSizeSelectorPreference.java
./vendor/mediatek/proprietary/packages/apps/Camera2/feature/mode/vsdof/src/com/mediatek/camera/feature/mode/vsdof/photo/view/PictureSizeSelectorPreference.java看源码发现和 PictureSizeSelector 代码基本一致 ,但是仔细看一个方法的说明如下:/*** Set the video quality supported.* @param entryValues The video quality supported.*/public void setEntryValues(List<String> entryValues) {mEntryValues.clear();mEntryValues.addAll(entryValues);}这些事设置Vieo 的 并不是设置picture 的。 所以我们需求设置图片质量的其实应该是上面找到的 PictureSizeSelector
PictureSizeSettingView
路径:
/vendor/mediatek/proprietary/packages/apps/Camera2/feature/setting/picturesize/src/com/mediatek/camera/feature/setting/picturesize/PictureSizeSettingView.java
找到这个类的方法有两种
- grep 查找关键字 “照片大小”
- 根据上面定位到的源码 PictureSizeSelector
就是进入到 PictureSizeSelector 界面之前的页面,如下:
准确的来说, PictureSizeSettingView 对应的其实是这个界面中 图片大小的这个item .
源码代码量不多,我们赋上来看看:
package com.mediatek.camera.feature.setting.picturesize;import android.app.Activity;
import android.app.FragmentTransaction;
import android.preference.PreferenceFragment;import com.mediatek.camera.R;
import com.mediatek.camera.common.debug.LogHelper;
import com.mediatek.camera.common.debug.LogUtil;
import com.mediatek.camera.common.preference.Preference;
import com.mediatek.camera.common.setting.ICameraSettingView;import java.util.ArrayList;
import java.util.List;/*** Picture size setting view.*/
public class PictureSizeSettingView implements ICameraSettingView,PictureSizeSelector.OnItemClickListener {private static final LogUtil.Tag TAG =new LogUtil.Tag(PictureSizeSettingView.class.getSimpleName());private Activity mActivity;private Preference mPref;private OnValueChangeListener mListener;private String mKey;private String mSelectedValue;private List<String> mEntryValues = new ArrayList<>();private String mSummary;private PictureSizeSelector mSizeSelector;private boolean mEnabled;/*** Listener to listen picture size value changed.*/public interface OnValueChangeListener {/*** Callback when picture size value changed.** @param value The changed picture size, such as "1920x1080".*/void onValueChanged(String value);}/*** Picture size setting view constructor.** @param key The key of picture size.*/public PictureSizeSettingView(String key) {mKey = key;}@Overridepublic void loadView(PreferenceFragment fragment) {LogHelper.d(TAG, "[loadView]");mActivity = fragment.getActivity();if (mSizeSelector == null) {mSizeSelector = new PictureSizeSelector();mSizeSelector.setOnItemClickListener(this);}fragment.addPreferencesFromResource(R.xml.picturesize_preference);mPref = (Preference) fragment.findPreference(mKey);mPref.setRootPreference(fragment.getPreferenceScreen());mPref.setId(R.id.picture_size_setting);mPref.setContentDescription(mActivity.getResources().getString(R.string.picture_size_content_description));mPref.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {@Overridepublic boolean onPreferenceClick(android.preference.Preference preference) {mSizeSelector.setValue(mSelectedValue);mSizeSelector.setEntryValues(mEntryValues);FragmentTransaction transaction = mActivity.getFragmentManager().beginTransaction();transaction.addToBackStack(null);transaction.replace(R.id.setting_container,mSizeSelector, "picture_size_selector").commit();return true;}});mPref.setEnabled(mEnabled);if (mSelectedValue != null) {mSummary = PictureSizeHelper.getPixelsAndRatio(mSelectedValue);}}@Overridepublic void refreshView() {if (mPref != null) {LogHelper.d(TAG, "[refreshView]");mPref.setSummary(mSummary);mPref.setEnabled(mEnabled);}}@Overridepublic void unloadView() {LogHelper.d(TAG, "[unloadView]");}@Overridepublic void setEnabled(boolean enabled) {mEnabled = enabled;}@Overridepublic boolean isEnabled() {return mEnabled;}/*** Set listener to listen the changed picture size value.** @param listener The instance of {@link OnValueChangeListener}.*/public void setOnValueChangeListener(OnValueChangeListener listener) {mListener = listener;}/*** Set the default selected value.** @param value The default selected value.*/public void setValue(String value) {mSelectedValue = value;}/*** Set the picture sizes supported.** @param entryValues The picture sizes supported.*/public void setEntryValues(List<String> entryValues) {mEntryValues = entryValues;}@Overridepublic void onItemClick(String value) {mSelectedValue = value;mSummary = PictureSizeHelper.getPixelsAndRatio(value);if (mListener != null) {mListener.onValueChanged(value);}}
}
onItemClick
这里关注下这个 onItemClick 点击方法,我们看类声明如下:
PictureSizeSettingView implements ICameraSettingView,PictureSizeSelector.OnItemClickListener
所以 这个 onItemClick 方法其实是PictureSizeSelector 类的点击方法的回调。
onPreferenceClick
先看源码,如下:
mPref.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {@Overridepublic boolean onPreferenceClick(android.preference.Preference preference) {mSizeSelector.setValue(mSelectedValue);mSizeSelector.setEntryValues(mEntryValues);FragmentTransaction transaction = mActivity.getFragmentManager().beginTransaction();transaction.addToBackStack(null);transaction.replace(R.id.setting_container,mSizeSelector, "picture_size_selector").commit();return true;}});
这个方法其实就做了三件事情:
- setValue 设置默认图片大小
- setEntryValues 设置支持的所有图片大小集合
- transaction.replace 操作,跳转到PictureSizeSelector 界面
这里其实就和PictureSizeSelector 完全关联起来了。
接下来就要关注 两个事情:
- mListener.onValueChanged(value); 在哪里设置回调的
- setValue 这个类里面也有设置默认图片大小,到底在哪里设置的
PictureSize
源码路径:
/vendor/mediatek/proprietary/packages/apps/Camera2/feature/setting/picturesize/src/com/mediatek/camera/feature/setting/picturesize/PictureSize.java
如何关联到这个类?
上面已经分析到了 PictureSizeSettingView 的 onValueChanged,其实就是要找 PictureSizeSettingView 中 接口 OnValueChangeListener 是在哪里实现的,这样来找到具体的实现和调用地方。
先看类说明:
这里我们看下部分代码片段截图:
上面截图就可以基本确认了,它对应的界面才是 照片设置图,如下:
onValueInitialized
源代码如下:
/*** Invoked after setting's all values are initialized.** @param supportedPictureSize Picture sizes which is supported in current platform.*/public void onValueInitialized(List<String> supportedPictureSize) {LogHelper.d(TAG, "[onValueInitialized], supportedPictureSize:" + supportedPictureSize);double fullRatio = PictureSizeHelper.findFullScreenRatio(mActivity);List<Double> desiredAspectRatios = new ArrayList<>();desiredAspectRatios.add(fullRatio);desiredAspectRatios.add(PictureSizeHelper.RATIO_4_3);PictureSizeHelper.setDesiredAspectRatios(desiredAspectRatios);PictureSizeHelper.setFilterParameters(DEGRESSIVE_RATIO, MAX_COUNT);if (sFilterPictureSize) {supportedPictureSize = PictureSizeHelper.filterSizes(supportedPictureSize);LogHelper.d(TAG, "[onValueInitialized], after filter, supportedPictureSize = "+ supportedPictureSize);}if (FILTER_MODE.equals(mModeKey)|| VFB_MODE.equals(mModeKey)|| FB_MODE.equals(mModeKey)) {//for low romif ((VFB_MODE.equals(mModeKey)||FILTER_MODE.equals(mModeKey))&& isLowRam()) {List<String> supportedPictureSizeAfterCheck = new ArrayList<String>();for (String pictureSize : supportedPictureSize) {String[] size = pictureSize.split("x");int width = Integer.parseInt(size[0]);int height = Integer.parseInt(size[1]);if (width < PICTURE_SIZE_9M_WIDTH&& height < PICTURE_SIZE_9M_HEIGHT) {supportedPictureSizeAfterCheck.add(pictureSize);}}supportedPictureSize = supportedPictureSizeAfterCheck;LogHelper.d(TAG, "[onValueInitialized], low ram, after check, " +"supportedPictureSize:"+ supportedPictureSize);} else {List<String> supportedPictureSizeAfterCheck = new ArrayList<String>();for (String pictureSize : supportedPictureSize) {String[] size = pictureSize.split("x");int width = Integer.parseInt(size[0]);int height = Integer.parseInt(size[1]);if (width <= PictureSizeHelper.getMaxTexureSize()&& height <= PictureSizeHelper.getMaxTexureSize()) {supportedPictureSizeAfterCheck.add(pictureSize);}}supportedPictureSize = supportedPictureSizeAfterCheck;LogHelper.d(TAG, "[onValueInitialized], GPU Mode, after check, " +"supportedPictureSize:"+ supportedPictureSize);}}if (HDR_MODE.equals(mModeKey)) {List<String> supportedPictureSizeAfterCheck = new ArrayList<String>();for (String pictureSize : supportedPictureSize) {for (String yuvSize:mYUVsupportedSize){if(pictureSize.equals(yuvSize)){supportedPictureSizeAfterCheck.add(pictureSize);}}}supportedPictureSize=supportedPictureSizeAfterCheck;LogHelper.d(TAG, "[onValueInitialized], PostAlgo Mode, after check, supportedPictureSize:"+ supportedPictureSize);}if (AIBEAUTYPHOTO_MODE.equals(mModeKey)|| AIBOKEHPHOTO_MODE.equals(mModeKey)|| AICOLORPHOTO_MODE.equals(mModeKey)|| AILEGGYPHOTO_MODE.equals(mModeKey)|| AISLIMMINGPHOTO_MODE.equals(mModeKey)) {List<String> supportedPictureSizeAfterCheck = new ArrayList<String>();for (String pictureSize : supportedPictureSize) {String[] size = pictureSize.split("x");int width = Integer.parseInt(size[0]);int height = Integer.parseInt(size[1]);if (width <= PictureSizeHelper.getMaxTexureSize()&& height <= PictureSizeHelper.getMaxTexureSize()) {supportedPictureSizeAfterCheck.add(pictureSize);}}supportedPictureSize = supportedPictureSizeAfterCheck;LogHelper.d(TAG, "[onValueInitialized], mModeKey:" + mModeKey + ",after check, supportedPictureSize:"+ supportedPictureSize);}setSupportedPlatformValues(supportedPictureSize);setSupportedEntryValues(supportedPictureSize);setEntryValues(supportedPictureSize);refreshViewEntry();String valueInStore = mDataStore.getValue(getKey(), null, getStoreScope());if (valueInStore != null&& !supportedPictureSize.contains(valueInStore)) {LogHelper.d(TAG, "[onValueInitialized], value:" + valueInStore+ " isn't supported in current platform");valueInStore = null;mDataStore.setValue(getKey(), null, getStoreScope(), false);}if (valueInStore == null) {// Default picture size is the max full-ratio size.LogHelper.d(TAG, "valueInStore == null Default picture size is the max full-ratio size:");/*List<String> entryValues = getEntryValues();for (String value : entryValues) {if (PictureSizeHelper.getStandardAspectRatio(value) == fullRatio) {valueInStore = value;LogHelper.d(TAG, "valueInStore == null:valueInStore:"+valueInStore);break;}}*/valueInStore =PictureSizeHelper.getCustomDefault(getEntryValues());}// If there is no full screen ratio picture size, use the first value in// entry values as the default value.if (valueInStore == null) {valueInStore = getEntryValues().get(0);LogHelper.d(TAG, "valueInStore:valueInStore:"+valueInStore);}setValue(valueInStore);}
看方法注释就一目了然了,根据当前平台设置-初始化图片大小
/*** Invoked after setting's all values are initialized.** @param supportedPictureSize Picture sizes which is supported in current platform.*/
对于 valueInStore 的具体设置内容和关联逻辑,这里暂不分析。
总结
- 实现了MTK Android13 平台下默认图片大小的逻辑
- 分析了解决问题的思路,源码分析流程
- 建议对Camera2 相关知识需要一定的了解最好
- 在查看源码的过程中,难免找不到关键字,不知道修改哪里。 可以借助IDE- AS VS 操作,方便定位源码位置。
相关文章:
Android 13.0 MTK Camera2 设置默认拍照尺寸功能实现
Android 13.0 MTK Camera2 设置默认拍照尺寸功能实现 文章目录 需求:参考资料架构图了解Camera相关专栏零散知识了解部分相机源码参考,学习API使用,梳理流程,偏应用层Camera2 系统相关 修改文件-修改方案修改文件:修改…...
Linux:基础IO 文件系统
Linux:基础IO && 文件系统 一、系统IO(一)系统文件操作接口1、open2、write3、read (二)文件描述符1、概念2、标准输入、标准输出、标准错误 (三)dup系统调用(重定向原理) 二…...
近期有哪些断链危机?如何提升供应链风险管理能力?
全球供应链格局正经历深刻变革,其网络架构愈发复杂,涉及多国企业主体且涵盖多个节点与复杂环节,管理难度显著增大。从原材料采购到终端交付,运输、仓储、加工等任一环节均存在潜在风险,单一环节效率滞后易引发系统性连…...
知识科普|褪黑素的发展历程及应用研究进展
睡眠作为维持人体健康的重要生理机制,其节律性受到精密调控。在昼夜节律系统的调控下,人类普遍遵循周期性单次睡眠模式,这一过程涉及复杂的神经-体液调控网络。其中神经元活动、神经递质传导、激素分泌及遗传调控机制共同作用于睡眠觉醒系统&…...
企业如何构建一个全面的Web安全防护体系
企业如何构建一个全面的Web安全防护体系 企业构建全面的Web安全防护体系需融合战略规划、技术防御、持续运营和风险治理四大维度,以下是基于行业最佳实践的系统化方案: 一、顶层设计:治理架构与安全战略 战略规划与合规驱动 制定网络安全愿…...
T8332FN凯钰LED驱动芯片多拓扑车规级AEC-Q100
T8332FN是一款支持多拓扑结构的恒流LED驱动控制芯片,适用于汽车照明及高功率LED应用,具备宽电压输入、高精度调光及多重保护功能。 核心特性 - 输入与拓扑:支持5-60V宽电压输入,适配Boost、Buck、Buck-Boost、SEPIC四种拓扑结构&…...
Redis一些小记录
Redis一些小记录 SpringData Redis:RedisTemplate配置与数据操作 操作String类型数据 String是Redis中最基本的数据类型,可以存储字符串、整数或浮点数。RedisTemplate提供了ValueOperations接口来操作String类型的数据,支持设置值、获取值、…...
Win10安装 P104-100 驱动
安装完之后总结一下, 之前做了不少功课, 在网上搜了很多教程, 视频的文字的, 但是很多已经比较陈旧了. 最后发现的这个 GitHub 项目 NVIDIA-patcher 是最有用的, 因为这是现在这些魔改驱动的来源. NVIDIA-patcher 仓库地址: https://github.com/dartraiden/NVIDIA-patcher 安…...
Android开机动画资源包制作(测试使用)
开机动画资源包需要采用仅存储的方式进行压缩,不能使用压缩软件直接压缩生成。 如果是系统开发人员,可以在源码目录中,采用bootanim程序提供的制作方式进行,下面可供测试人员自行制作。 制作流程 1)基于设备中已有开…...
PWN基础-利用格式化字符串漏洞泄露canary结合栈溢出getshell
测试源码: #include<stdio.h> void exploit() {system("/bin/sh"); } void func() {char str[0x20];read(0, str, 0x50);printf(str);read(0, str, 0x50); } int main() {func();return 0; } 编译,开启 canary 保护,关闭 p…...
Kafka HA集群配置搭建与SpringBoot使用示例总结
Kafka HA集群配置搭建与SpringBoot使用示例总结 一、Kafka高可用(HA)集群搭建 1. 环境准备 至少3台服务器(推荐奇数台,如3、5、7)已安装Java环境(JDK 1.8)下载Kafka二进制包(如kafka_2.13-3.2.1.tgz&…...
MSO-Player:基于vlc的Unity直播流播放器,支持主流RTSP、RTMP、HTTP等常见格式
MSO-Player 基于libVLC的Unity视频播放解决方案 支持2D视频和360度全景视频播放的Unity插件 📑 目录 🎥 MSO-Player 📋 功能概述🚀 快速入门📚 关键组件📝 使用案例🔌 依赖项📋 注意…...
97A6-ASEMI无人机专用功率器件97A6
编辑:ll 97A6-ASEMI无人机专用功率器件97A6 型号:97A6 品牌:ASEMI 封装:SOT-23 批号:最新 引脚数量:3 特性:双向可控硅 工作温度:-40℃~150℃ 97A6双向可控硅:…...
body Param Query 三个 不同的入参 分别是什么意思 在前端 要怎么传 这三种不同的参数
在 NestJS 中,Body()、Param() 和 Query() 用于处理不同类型的请求参数。以下是它们的含义及前端传递方式: Body():请求体参数 • 含义:用于获取请求体中的数据(如 POST/PUT 请求中提交的 JSON、表单数据等)…...
生成式人工智能认证(GAI认证)含金量怎么样?
当生成式人工智能(Generative AI)的浪潮以摧枯拉朽之势重塑职业版图时,一个尖锐的问题正悬在无数人的心头:在技术迭代比眨眼更快的时代,如何证明自己具备驾驭AI的核心能力? 这场认知革命的背后,一张认证证书的价值早已超越了纸面——它既是个人能力的“信用背书”,也是…...
环境DNA宏条形码技术,鱼类检测引物如何选择?
环境DNA(eDNA)宏条形码技术在鱼类多样性调查研究中的优势明显,相比于传统调查方式,eDNA宏条形码技术灵敏度更高,能够更好地揭示鱼类的丰富度,并且具有高时效性。然而,在使用这个技术的过程中&am…...
Scala集合操作与WordCount案例实战总结
集合计算简单函数 1、说明 (1)求和 (2)求乘积 (3)最大值 (4)最小值 (5)排序 2、案例实操 object demo29{ def main(args: Array[String]): Unit { val…...
Spark-Streaming核心编程(四)总结
有状态转化操作 - UpdateStateByKey 功能描述 UpdateStateByKey原语用于在DStream中跨批次维护状态,例如流计算中的累加wordcount。 它允许对一个状态变量进行访问和更新,适用于键值对形式的DStream。 工作原理 给定一个由(键,事…...
关系型数据库PostgreSQL for Mac 保姆级使用教程
第一部分:安装PostgreSQL 方法一:使用Postgres.app(最简单) 访问 Postgres.app官网 下载最新版本,将 Postgres.app 移动到 “Applications” 文件夹。 双击Postgres.app打开应用,点击"Initialize&q…...
新增 29 个专业,科技成为关键赛道!
近日,教育部正式发布《普通高等学校本科专业目录(2025年)》,新增 29 个本科专业,包括区域国别学、碳中和科学与工程、海洋科学与技术、健康与医疗保障、智能分子工程、医疗器械与装备工程、时空信息工程、国际邮轮管理…...
云计算市场的重新分类研究
云计算市场传统分类方式,比如按服务类型分为IaaS、PaaS、SaaS,或者按部署模式分为公有云、私有云、混合云。主要提供计算资源、存储和网络等基础设施。 但随着AI大模型的出现,云计算市场可以分为计算云和智算云,智算云主要是AI模…...
大模型时代的具身智能:从虚拟到现实的智能体进化革命
一、具身智能:重新定义 AI 与物理世界的交互范式 (一)概念解析:从 "离身" 到 "具身" 的认知革命 具身智能(Embodied AI)是融合大模型决策能力与物理实体执行能力的新型智能系统&…...
鸿蒙NEXT开发正则工具类(ArkTs)
import { FormatUtil } from ./FormatUtil;/*** 正则工具类* author CSDN-鸿蒙布道师* since 2025/04/27*/ export class RegexUtil {/*** 英文字母、数字和下划线*/static readonly REG_GENERAL "^\\w$";/*** 数字*/static readonly REG_NUMBERS "^\\d$"…...
Flink维表深度解析
一、维表的概念与作用 维表(Dimension Table) 是数据仓库中的核心概念,通常用于存储静态或缓慢变化的业务实体信息(如用户资料、商品信息、地理位置等)。在实时流处理场景中,维表的作用是为主数据流&#…...
基于ArcGIS的洪水灾害普查、风险评估及淹没制图技术研究
一、洪水普查技术规范解读 1.1 全国水旱灾害风险普查实施方案解读 1.2 洪水风险区划及防治区划编制技术要求解读 1.3 山丘区中小河流洪水淹没图编制技术要求解读 二、ArcGIS介绍及数据管理 2.1 ArcGIS界面及数据加载 2.2 ArcGIS常见数据格式 2.3基于Geodatabase的洪水灾…...
初识数据结构——二叉树从基础概念到实践应用
数据结构专栏 ⬅(click) 初识二叉树:从基础概念到实践应用🌳 一、树型结构基础 1.1 树的基本概念 树是一种非线性的数据结构,由n(n>0)个有限节点组成一个具有层次关系的集合。它看起来像一棵倒挂的树,根朝上而叶朝下。 关键特…...
手搓传染病模型(SEIR)
先看模型 在本模型中,人群有四种自然史状态:易感者(S),暴露者(E),感染者(I)以及康复者(R) 2.模型假设人群分布是同质均匀的,未考虑人群出生、死亡、迁入迁出对疾病传播的影响 3.康复者永久免疫:康复者永久免…...
企业数据赋能 | 应用模板分享:汽车销售仪表板
实时监控销售数据,比较车型、地区业绩~ 今天,小编向大家分享 Tableau 应用分析模板:由 Imran Shaikh 搭建的汽车销售仪表板。借助此仪表板,企业可以实时跟踪销售情况,了解市场趋势,并比较不同车型、地区和销…...
C++?动态内存管理!!!
一、引言 之前我们一起讨论了类和对象的相关知识,接下来我们将继续完善我们的知识体系,为以后继续深入学习C知识添砖加瓦,在本期我们将一起学习C中关于动态内存管理的相关知识,在学习之前将要先回顾C语言中是如何进行动态内存管理…...
MCP协议:AI生态的统一标准
MCP(Model Context Protocol,模型上下文协议)是人工智能领域的革命性协议标准,被广泛类比为“AI世界的USB-C接口”。它通过统一模型、算力和数据的交互方式,解决了AI生态中的碎片化问题,重构了智能协作的技术范式。以下是其核心解析与技术哲学: 一、MCP协议的核心定位与…...
在 UniApp 中实现 App 与 H5 页面的跳转及通信
在移动应用开发中,内嵌 H5 页面或与外部网页交互是常见需求。UniApp 作为跨平台框架,提供了灵活的方式实现 App 与 H5 的跳转和双向通信。本文将详细讲解实现方法,并提供可直接复用的代码示例。 文章目录 一、 App 内嵌 H5 页面(使…...
目标跟踪最新文章阅读列表
AAAI2025 TrackFormer: Multi-Object Tracking with Transformers 论文:https://arxiv.org/abs/2101.02702 代码:https://github.com/timmeinhardt/trackformer AAAI2025 SUTrack 单目标跟踪 论文:https://pan.baidu.com/s/10cR4tQt3lSH5V2RNf7-3gg?pwd=pks2 代码:htt…...
Spark RDD行动算子与共享变量实战:从数据聚合到分布式通信
RDD行动算子: 行动算子就是会触发action的算子,触发action的含义就是真正的计算数据。 1、reduce import org.apache.spark.{SparkConf, SparkContext} object value11 { def main(args: Array[String]): Unit { // 创建 SparkConf 对象并设置应用…...
《2025全球机器学习技术大会:阿里云讲师张玉明深度剖析通义灵码AI程序员》
4 月 18 日 - 19 日,由 CSDN & Boolan 联合举办的 2025 全球机器学习技术大会(ML-Summit)于上海顺利举行。大会聚焦人工智能与机器学习前沿技术,汇聚了来自科技与人工智能领域的数位顶尖专家以及数千名开发者和研究者…...
python+adafruit_pca9685 测试舵机存储当前角度
测试代码如下: # -*- coding: UTF-8 -*- import time from board import SCL, SDA import busio from adafruit_pca9685 import PCA9685 from adafruit_motor import servo 测试控制1块驱动板或者多块 pip install Adafruit-PCA9685 --break-system-packages pip i…...
视觉/深度学习/机器学习相关面经总结(2)(持续更新)
目录 1、跨模态对齐的方案2、位置编码方式1. **正弦和余弦位置编码(Sinusoidal Positional Encoding)**2. **可学习的位置编码(Learnable Positional Encoding)**3. **相对位置编码(Relative Positional Encoding&…...
缓存并发更新的挑战
缓存并发更新的挑战 1. 引言:并发更新的挑战2. 并发场景下的常见“坑”最后写入胜出 (Last-Write-Wins)脏读 (Dirty Read)丢失更新 (Lost Update)不可重复读 (Non-repeatable Read)幻读 (Phantom Read)写偏斜 (Write Skew)缓存与数据库不一致分布式系统中的时序问题…...
LeetCode题解1297. 子串的最大出现次数
(好久没写题解了,忙着学ai去了) 先来看题目 很显然,题目就是要我们在给定的字符串中找到一个满足要求的连续子串。 首先,要求子串中不同字母的数目得小于等于maxLetters,我们可以用一个DifLettsers函数来…...
零基础小白如何上岸数模国奖
零基础小白如何上岸数模国奖 我自己本人第一次参加数模国赛顺利上岸国奖,当然那段经历也是比较痛苦了,差不多也是从当年四月开始接触数学建模,第一次参加妈妈杯成绩并不理想,后面不断参加数模比赛进行模拟,最后顺利上岸…...
Redux-Saga vs Redux-Thunk
Redux-Saga与Redux-Thunk对比 #mermaid-svg-zbDYIbzoVqlMJXiE {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-zbDYIbzoVqlMJXiE .error-icon{fill:#552222;}#mermaid-svg-zbDYIbzoVqlMJXiE .error-text{fill:#55222…...
Win11 配置 Git 绑定 Github 账号的方法与问题汇总
目录 一、创建 Github 项目库(远程仓库)二、配置安装好的 Git1. 设置用户信息2. 查看已配置的信息3. 建立本地仓库4. Git 常用命令速查表 三、配置 SSH 公钥1. 生成 ssh key出现的问题 2. 启动 ssh-agent 并添加秘钥3. 在 Github 上绑定 ssh 公钥出现的问…...
李臻20242817_安全文件传输系统项目报告_第9周
安全文件传输系统项目报告(第 9 周) 1. 代码链接 Gitee 仓库地址:https://gitee.com/li-zhen1215/homework/tree/master/Secure-file 代码结构说明: project-root/├── src/ # 源代码目录│ ├── main.c # 主程序入口│ ├…...
OceanBase TPCC测试常见报错汇总
OceanBase TPCC测试常见报错汇总 报错1:加载测试数据时创建tablegroup失败报错2:加载测试数据时执行超时报错3:加载测试数据时funcs.sh函数找不到报错4:加载数据时报错超过租户内存上限办法一:增加租户内存办法二:调高转储线程数办法三:调整MemStore内存占比和冻结触发阈…...
文心一言开发指南06——千帆大模型平台新手指南
版权声明 本文原创作者:谷哥的小弟作者博客地址:http://blog.csdn.net/lfdfhl 千帆大模型平台为新手用户提供了一个全面的入门指南,以便用户能够快速熟悉平台的操作和功能。千帆大模型平台通过提供详细的新手指南,确保用户能够顺…...
解决SSLError: [SSL: DECRYPTION_FAILED_OR_BAD_RECORD_MAC] decryption faile的问题
问题描述: 在pip安装第三方库时,出现SSL的问题。 传输层安全性协议(TLS)及其前身安全套接层(SSL)是现在的 HTTPS 协议中的一种安全协议,目的是为互联网通信提供安全及数据完整性保障。而较新版…...
Clang中ext_vector_type和address_space __attribute__的使用
Clang中ext_vector_type和address_space __attribute__的使用 一.背景二. 关键概念详解三.示例代码与验证四. 总结 一.背景 在使用 Clang 编译可执行程序时,遇到类似下面的链接错误: undefined reference to atomic_add(int volatile AS4*, int) undef…...
echarts自定义图表
普通柱状图 自定义柱状图 实现思路 4个图层 背景 边框实体 内部透明地步透明间隙红色柱形数据数据使用自定义字体倾斜柱形上方扁平矩形矩形颜色透明 label字体颜色和背景色相同实现矩形块 上下靠padding实现 向下 paddingBottom使用负数 完整代码 <!DOCTYPE html> <…...
【应用密码学】实验二 分组密码(2)
一、实验要求与目的 1) 学习AES密码算法原理 2) 学习AES密码算法编程实现 二、实验内容与步骤记录(只记录关键步骤与结果,可截图,但注意排版与图片大小) 字符串加解密 运行python程序,输入…...
【深度学习】多头注意力机制的实现|pytorch
博主简介:努力学习的22级计算机科学与技术本科生一枚🌸博主主页: Yaoyao2024往期回顾:【深度学习】注意力机制| 基于“上下文”进行编码,用更聪明的矩阵乘法替代笨重的全连接每日一言🌼: 路漫漫其修远兮,吾…...
OceanBase数据库磁盘空间管理
OceanBase数据库磁盘空间管理 日志盘空间管理日志盘容量参数日志盘空间满应急处理 数据盘空间管理数据盘容量参数数据文件自动扩展数据盘空间满应急处理表占用的磁盘空间 日志盘空间管理 日志盘容量参数 🐯 与日志盘redo_dir相关的四个重要参数: log_…...