test.nvue 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459
  1. <template>
  2. <view class="content">
  3. <view class="show-view">
  4. <Ba-CameraView ref="cameraView" class="camera-view" :load="loadData"></Ba-CameraView>
  5. </view>
  6. <view class="es x-bc es-mt-4 es-mb-4 btnBox">
  7. <button class="btn1" @click="takePhoto" :sizeLimit="100">拍照</button>
  8. <button class="btn1" @click="changeCamera" v-if="!isTablet">切换摄像头</button>
  9. <button class="btn1" @click="setFrontCamera" v-if="!isTablet">前置摄像头</button>
  10. <button class="btn1" @click="setRearCamera">后置摄像头</button>
  11. </view>
  12. <!-- <view class="es x-bc es-mt-20">
  13. <view class="title">自动变焦</view>ca
  14. <switch :checked="loadData.autoZoomEnabled" color="#FF5C03" @change="toggleAutoZoom" style="transform:scale(0.7)"/>
  15. </view> -->
  16. <!-- 控制按钮 -->
  17. <view class="controls">
  18. <button class="btn" @click="toggleAutoZoom">
  19. {{ loadData.autoZoomEnabled ? '关闭自动变焦' : '开启自动变焦' }}
  20. </button>
  21. <button class="btn" @click="switchZoomMode">
  22. 切换模式: {{ currentZoomMode }}
  23. </button>
  24. <button class="btn" @click="manualZoom">手动变焦</button>
  25. </view>
  26. <view class="es x-bc" style="display:flex;flex:1;">
  27. <view class="label">选择清晰度</view>
  28. <view class="right x-end" style="height: 40px; margin-right: 10px;">
  29. <picker style="width: 100%;text-align: right;" @change="pickerQuality" :value="currentQuality" :range="qualityPicker">
  30. <view class="picker">
  31. {{loadData.captureQuality}}
  32. </view>
  33. </picker>
  34. </view>
  35. </view>
  36. <!-- 状态显示 -->
  37. <div class="status">
  38. <text class="status-text">设备类型: {{ isTablet ? '平板设备(Shimeta)' : '普通设备' }}</text>
  39. <text class="status-text">当前摄像头: {{ loadData.isFacingFront ? '前置摄像头' : '后置摄像头' }}</text>
  40. <text class="status-text">分辨率质量: {{ loadData.captureQuality }} (动态适配)</text>
  41. <text class="status-text">自动变焦: {{ loadData.autoZoomEnabled ? '开启' : '关闭' }}</text>
  42. <text class="status-text">变焦模式: {{ currentZoomMode }}</text>
  43. <text class="status-text">状态信息: {{ statusMessage }}</text>
  44. </div>
  45. <!-- 配置检查按钮 -->
  46. <view class="btn-container">
  47. <button class="btn" @click="forceApplyConfig">检查并应用配置</button>
  48. </view>
  49. </view>
  50. </template>
  51. <script>
  52. export default {
  53. data() {
  54. // 在data初始化时就进行设备检测
  55. const systemInfo = uni.getSystemInfoSync();
  56. console.log('设备信息:', systemInfo);
  57. // // 判断是否为平板设备
  58. // const isTabletBySize = systemInfo.screenWidth > 800 && systemInfo.screenHeight > 1200;
  59. const isTabletByModel = systemInfo.brand && (
  60. //systemInfo.model.toLowerCase().includes('tablet') ||
  61. //systemInfo.model.toLowerCase().includes('pad') ||
  62. systemInfo.brand.toLowerCase().includes('shimeta')
  63. );
  64. const isTablet = isTabletByModel;
  65. const defaultCameraFacing = isTablet ? false : true; // 平板默认后置,手机默认前置
  66. console.log('设备检测结果:', {
  67. isTablet,
  68. defaultCameraFacing: defaultCameraFacing ? '前置' : '后置',
  69. screenSize: `${systemInfo.screenWidth}x${systemInfo.screenHeight}`,
  70. model: systemInfo.model
  71. });
  72. return {
  73. obj: {
  74. src: null,
  75. text: null,
  76. vSrc: null
  77. },
  78. // 设备类型检测
  79. isTablet: isTablet,
  80. isShimeta: isTablet,
  81. loadData: { //配置
  82. isToast: true,
  83. isShowVibrate:false,
  84. isFacingFront: defaultCameraFacing, // 根据设备类型设置默认摄像头
  85. captureQuality:"HIGH", //摄像头清晰度 **HIGH**: 动态适配高清 **MEDIUM**: 动态适配中等 **LOW**: 动态适配低清
  86. autoZoomEnabled: true, // 启用舌诊自动变焦
  87. autoZoomMode: "TONGUE", // 变焦模式:FACE(面部) 或 TONGUE(舌诊)
  88. isTablet: isTablet // 设备类型配置
  89. },
  90. qualityPicker: ['HIGH', 'MEDIUM','LOW'],
  91. currentQuality:0,
  92. currentZoomMode:"TONGUE", // 默认使用舌诊模式
  93. statusMessage: isTablet ? "检测到平板设备,默认使用后置摄像头" : "检测到手机设备,默认使用前置摄像头"
  94. }
  95. },
  96. onLoad() {
  97. this.setListener(); //设置监听
  98. console.log('onLoad - 当前配置:', {
  99. isTablet: this.isTablet,
  100. isFacingFront: this.loadData.isFacingFront,
  101. statusMessage: this.statusMessage
  102. });
  103. },
  104. mounted() {
  105. // 强制应用配置,确保平板设备使用后置摄像头
  106. // this.$nextTick(() => {
  107. // this.forceApplyConfig();
  108. // });
  109. },
  110. methods: {
  111. takePhoto() {
  112. this.$refs.cameraView.takePicture((res) => {
  113. this.showToast(res.msg)
  114. });
  115. },
  116. //切换摄像头
  117. changeCamera() {
  118. // 检查是否为平板设备
  119. if (this.isTablet) {
  120. this.statusMessage = '平板设备只有后置摄像头,无法切换';
  121. uni.showToast({
  122. title: "平板设备只有后置摄像头",
  123. icon: 'none'
  124. });
  125. return;
  126. }
  127. this.$refs.cameraView.switchCamera((result) => {
  128. if (result.ok) {
  129. this.loadData.isFacingFront = !this.loadData.isFacingFront;
  130. this.statusMessage = `已切换到${this.loadData.isFacingFront ? '前置' : '后置'}摄像头`;
  131. uni.showToast({
  132. title: "切换成功",
  133. icon: 'none'
  134. });
  135. } else {
  136. this.statusMessage = '切换摄像头失败: ' + result.msg;
  137. console.error('操作失败', result.msg);
  138. }
  139. });
  140. },
  141. // 设置为前置摄像头
  142. setFrontCamera() {
  143. if (this.isTablet) {
  144. this.statusMessage = '平板设备只有后置摄像头,无法使用前置摄像头';
  145. uni.showToast({
  146. title: "平板设备只有后置摄像头",
  147. icon: 'none'
  148. });
  149. return;
  150. }
  151. this.$refs.cameraView.setCameraFacing((result) => {
  152. if (result.ok) {
  153. this.loadData.isFacingFront = true;
  154. this.statusMessage = '已设置为前置摄像头';
  155. uni.showToast({
  156. title: "已设置为前置摄像头",
  157. icon: 'none'
  158. });
  159. } else {
  160. this.statusMessage = '设置前置摄像头失败: ' + result.msg;
  161. console.error('设置前置摄像头失败', result.msg);
  162. }
  163. }, {
  164. useFrontCamera: true
  165. });
  166. },
  167. // 设置为后置摄像头
  168. setRearCamera() {
  169. this.$refs.cameraView.setCameraFacing((result) => {
  170. if (result.ok) {
  171. this.loadData.isFacingFront = false;
  172. this.statusMessage = '已设置为后置摄像头';
  173. uni.showToast({
  174. title: "已设置为后置摄像头",
  175. icon: 'none'
  176. });
  177. } else {
  178. this.statusMessage = '设置后置摄像头失败: ' + result.msg;
  179. uni.showToast({
  180. title: "设置失败: " + result.msg,
  181. icon: 'none'
  182. });
  183. }
  184. }, {
  185. useFrontCamera: false
  186. });
  187. },
  188. // 强制应用当前配置(确保平板设备配置生效)
  189. forceApplyConfig() {
  190. console.log('强制应用配置:', this.loadData);
  191. // 如果是平板设备,确保使用后置摄像头
  192. if (this.isTablet && this.loadData.isFacingFront) {
  193. console.log('检测到平板设备使用前置摄像头,强制切换到后置');
  194. this.loadData.isFacingFront = false;
  195. this.statusMessage = '平板设备强制使用后置摄像头';
  196. // 调用底层API确保配置生效
  197. this.setRearCamera();
  198. // 平板设备切换摄像头后,重新应用自动变焦设置
  199. if (this.loadData.autoZoomEnabled) {
  200. setTimeout(() => {
  201. this.reapplyAutoZoom();
  202. }, 1000); // 等待摄像头切换完成
  203. }
  204. }
  205. // 更新状态显示
  206. this.statusMessage = this.isTablet ?
  207. '平板设备 - 后置摄像头' :
  208. (this.loadData.isFacingFront ? '手机设备 - 前置摄像头' : '手机设备 - 后置摄像头');
  209. },
  210. // 重新应用自动变焦设置
  211. reapplyAutoZoom() {
  212. console.log('重新应用自动变焦设置:', {
  213. enabled: this.loadData.autoZoomEnabled,
  214. mode: this.currentZoomMode
  215. });
  216. this.$refs.cameraView.setAutoZoom((result) => {
  217. if (result.ok) {
  218. this.statusMessage = `平板设备 - 自动变焦已重新应用 (${this.currentZoomMode}模式)`;
  219. console.log('平板设备自动变焦重新应用成功');
  220. } else {
  221. this.statusMessage = '重新应用自动变焦失败: ' + result.msg;
  222. console.error('Failed to reapply auto zoom:', result.msg);
  223. }
  224. }, {
  225. enabled: this.loadData.autoZoomEnabled,
  226. mode: this.currentZoomMode
  227. });
  228. },
  229. setListener() {
  230. this.$refs.cameraView.setListener((res) => {
  231. if (res.action == "error") {
  232. this.showToast(res.msg)
  233. }
  234. });
  235. },
  236. showToast(msg) {
  237. uni.showToast({
  238. title: msg,
  239. icon: 'none'
  240. });
  241. },
  242. toggleAutoZoom(){
  243. this.loadData.autoZoomEnabled = !this.loadData.autoZoomEnabled;
  244. // 更新loadData中的配置
  245. this.loadData.autoZoomMode = this.currentZoomMode;
  246. this.$refs.cameraView.setAutoZoom((result) => {
  247. if (result.ok) {
  248. this.statusMessage = this.loadData.autoZoomEnabled ?
  249. `自动变焦已开启 (${this.currentZoomMode}模式)` : '自动变焦已关闭';
  250. this.showToast(this.statusMessage);
  251. console.log('变焦切换:', {
  252. enabled: this.loadData.autoZoomEnabled,
  253. mode: this.currentZoomMode
  254. });
  255. } else {
  256. this.statusMessage = '设置自动变焦失败: ' + result.msg;
  257. console.error('Failed to toggle auto zoom:', result.msg);
  258. this.showToast(this.statusMessage);
  259. }
  260. }, {
  261. enabled: this.loadData.autoZoomEnabled,
  262. mode: this.currentZoomMode
  263. });
  264. },
  265. switchZoomMode() {
  266. // 在 FACE、TONGUE、DEFAULT 之间切换
  267. const modes = ['FACE', 'TONGUE', 'DEFAULT'];
  268. const currentIndex = modes.indexOf(this.currentZoomMode);
  269. this.currentZoomMode = modes[(currentIndex + 1) % modes.length];
  270. // 更新loadData中的配置
  271. this.loadData.autoZoomMode = this.currentZoomMode;
  272. // 显示切换状态
  273. const zoomLevels = {
  274. 'FACE': this.isTablet ? '2.0倍' : '1.8倍',
  275. 'TONGUE': this.isTablet ? '3.0倍' : '2.8倍',
  276. 'DEFAULT': this.isTablet ? '1.8倍' : '1.5倍'
  277. };
  278. if (this.loadData.autoZoomEnabled) {
  279. // 如果自动变焦已开启,重新设置以应用新模式
  280. this.$refs.cameraView.setAutoZoom((result) => {
  281. if (result.ok) {
  282. this.statusMessage = `变焦模式已切换到: ${this.currentZoomMode} (${zoomLevels[this.currentZoomMode]})`;
  283. console.log('Zoom mode switched to:', this.currentZoomMode, 'with zoom level:', zoomLevels[this.currentZoomMode]);
  284. this.showToast(this.statusMessage);
  285. // 减少延时并立即执行变焦以显示效果
  286. setTimeout(() => {
  287. this.manualZoom();
  288. // 为了确保变焦效果明显,再次执行
  289. setTimeout(() => {
  290. this.manualZoom();
  291. }, 100);
  292. }, 200);
  293. } else {
  294. this.statusMessage = '切换变焦模式失败: ' + result.msg;
  295. console.error('Failed to switch zoom mode:', result.msg);
  296. this.showToast(this.statusMessage);
  297. }
  298. }, {
  299. enabled: this.loadData.autoZoomEnabled,
  300. mode: this.currentZoomMode
  301. });
  302. } else {
  303. this.statusMessage = `变焦模式已设置为: ${this.currentZoomMode} (${zoomLevels[this.currentZoomMode]}) - 需开启自动变焦`;
  304. this.showToast(this.statusMessage);
  305. }
  306. },
  307. manualZoom() {
  308. this.$refs.cameraView.performAutoZoom((result) => {
  309. if (result.ok) {
  310. this.statusMessage = '手动变焦执行成功';
  311. console.log('Manual zoom performed successfully');
  312. } else {
  313. this.statusMessage = '手动变焦失败: ' + result.msg;
  314. console.error('Manual zoom failed:', result.msg);
  315. }
  316. //this.showToast(this.statusMessage);
  317. });
  318. },
  319. pickerQuality(e){
  320. console.log("qxj detailValue",e);
  321. this.currentQuality=e.detail.value;
  322. const newQuality = this.qualityPicker[this.currentQuality];
  323. // 显示加载状态
  324. this.statusMessage = `正在切换到${newQuality}分辨率...`;
  325. uni.showLoading({
  326. title: '切换分辨率中...'
  327. });
  328. this.loadData.captureQuality = newQuality;
  329. this.$refs.cameraView.setCaptureQuality((result) => {
  330. uni.hideLoading();
  331. if (result.ok) {
  332. this.statusMessage = `分辨率已切换到: ${newQuality}`;
  333. uni.showToast({
  334. title: `已切换到${newQuality}分辨率`,
  335. icon: 'success'
  336. });
  337. // 分辨率切换后,如果自动变焦开启,重新应用设置
  338. if (this.loadData.autoZoomEnabled) {
  339. setTimeout(() => {
  340. this.$refs.cameraView.setAutoZoom((autoZoomResult) => {
  341. if (autoZoomResult.ok) {
  342. console.log('分辨率切换后自动变焦重新应用成功');
  343. }
  344. }, {
  345. enabled: this.loadData.autoZoomEnabled,
  346. mode: this.currentZoomMode
  347. });
  348. }, 1000); // 等待摄像头重新初始化完成
  349. }
  350. } else {
  351. this.statusMessage = `分辨率切换失败: ${result.msg}`;
  352. console.error('分辨率切换失败', result.msg);
  353. uni.showToast({
  354. title: `切换失败: ${result.msg}`,
  355. icon: 'error'
  356. });
  357. // 恢复之前的设置
  358. this.currentQuality = this.qualityPicker.indexOf(this.loadData.captureQuality);
  359. }
  360. }, {
  361. quality: newQuality
  362. });
  363. }
  364. }
  365. }
  366. </script>
  367. <style>
  368. .show-view {
  369. flex-direction: row;
  370. }
  371. .camera-view {
  372. display: flex;
  373. flex: 1;
  374. height: 800rpx;
  375. background-color: #333333;
  376. }
  377. .controls {
  378. flex-direction: column;
  379. align-items: center;
  380. }
  381. .btnBox{
  382. display: flex;
  383. flex: 1;
  384. margin-left: 10rpx;
  385. }
  386. .btn1{
  387. display: flex;
  388. flex: 1;
  389. margin-right: 10rpx;
  390. }
  391. .btn {
  392. width: 750rpx;
  393. height: 50px;
  394. background-color: #007AFF;
  395. color: #fff;
  396. border-radius: 10rpx;
  397. margin-bottom: 10rpx;
  398. font-size: 16px;
  399. text-align: center;
  400. line-height: 50px;
  401. }
  402. .r-flex {
  403. margin-top: 40rpx;
  404. margin-bottom: 40rpx;
  405. flex-wrap: wrap;
  406. flex-direction: row;
  407. }
  408. .status {
  409. flex-direction: column;
  410. align-items: center;
  411. padding: 15px;
  412. background-color: #fff;
  413. border-radius: 10px;
  414. border: 1px solid #ddd;
  415. }
  416. .status-text {
  417. font-size: 14px;
  418. color: #666;
  419. margin-bottom: 5px;
  420. text-align: center;
  421. }
  422. </style>