function.vue 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350
  1. <template>
  2. <div style="width: 100%; height: 100%">
  3. <h1>{{ isdetected }}</h1>
  4. <div class="img">
  5. <div class="controlZ">
  6. <div id="screan" ref="dv">
  7. <img :src="img[0]" alt v-show="!isCamera" />
  8. <!--图片展示-->
  9. <video
  10. ref="video"
  11. id="video_cam"
  12. width="265"
  13. height="212"
  14. class="face"
  15. autoplay
  16. v-show="isCamera"
  17. ></video>
  18. <canvas
  19. ref="canvasDOM"
  20. width="265"
  21. height="212"
  22. class="kuang"
  23. v-show="isCamera"
  24. ></canvas>
  25. </div>
  26. <div id="tou" ref="dv1">
  27. <img :src="img[2]" alt />
  28. </div>
  29. <div id="ai" ref="dv2">
  30. <img :src="img[1]" alt />
  31. </div>
  32. <div id="police" ref="dv2">
  33. <img :src="img[3]" alt />
  34. </div>
  35. </div>
  36. <div class="cameraZ">
  37. <!--开启摄像头-->
  38. <div class="cameraBtn">
  39. <el-button
  40. size="mini"
  41. type="primary"
  42. @click="callCamera"
  43. v-if="!isCamera"
  44. >开启摄像头</el-button
  45. >
  46. <el-button size="mini" type="primary" @click="closeCamera" v-else
  47. >关闭摄像头</el-button
  48. >
  49. <el-button
  50. size="mini"
  51. type="primary"
  52. @click="photograph"
  53. v-if="isCamera"
  54. >确认保存</el-button
  55. >
  56. </div>
  57. <!--确认-->
  58. <div>
  59. <!--canvas截取流-->
  60. <canvas
  61. ref="canvas"
  62. width="300"
  63. height="240"
  64. v-if="isCamera"
  65. ></canvas>
  66. </div>
  67. <div>
  68. <!--canvas截取流-->
  69. <!-- <canvas
  70. ref="canvasDOM"
  71. width="188"
  72. height="144"
  73. v-show="isCamera"
  74. ></canvas> -->
  75. </div>
  76. </div>
  77. </div>
  78. </div>
  79. </template>
  80. <script>
  81. import tracking from "@/assets/js/tracking-min.js";
  82. import "@/assets/js/face-min.js";
  83. export default {
  84. data() {
  85. return {
  86. that: this,
  87. img: [
  88. require("../assets/img/screan.png"),
  89. require("../assets/img/ai.png"),
  90. require("../assets/img/tou.png"),
  91. require("../assets/img/police.png"),
  92. ],
  93. isCamera: false,
  94. count: 0,
  95. isdetected: "请您保持脸部在画面中央",
  96. videoEl: {},
  97. canvasEL: {},
  98. };
  99. },
  100. methods: {
  101. // 调用摄像头
  102. callCamera() {
  103. let _this = this;
  104. // H5调用电脑摄像头API
  105. navigator.mediaDevices
  106. .getUserMedia({
  107. video: true,
  108. })
  109. .then((success) => {
  110. _this.isCamera = true;
  111. // 摄像头开启成功
  112. _this.$refs["video"].srcObject = success;
  113. // 实时拍照效果
  114. _this.$refs["video"].play();
  115. const video = this.videoEl;
  116. const canvas = this.canvasEL;
  117. const canvasContext = canvas.getContext("2d");
  118. let tracker = new window.tracking.ObjectTracker("face");
  119. // video.pause();
  120. // video.src = "";
  121. tracker.setInitialScale(4);
  122. tracker.setStepSize(2);
  123. tracker.setEdgesDensity(0.1);
  124. window.tracking.track("#video_cam", tracker, { camera: true });
  125. tracker.on("track", function (event) {
  126. const { autoCaptureTrackTraking } = _this;
  127. canvasContext.clearRect(0, 0, canvas.width, canvas.height);
  128. event.data.forEach(function ({ x, y, width, height }) {
  129. canvasContext.strokeStyle = "#FFFF";
  130. canvasContext.strokeRect(x+10, y-30, width - 20, height);
  131. canvasContext.font = "11px Helvetica";
  132. canvasContext.fillStyle = "#fff";
  133. });
  134. if (!(event.data.length == 0) && _this.count <= 10) {
  135. if (_this.count < 0) _this.count = 0;
  136. _this.count += 1;
  137. if (_this.count > 10) {
  138. _this.isdetected = "已检测到人脸";
  139. }
  140. } else {
  141. _this.count -= 1;
  142. if (_this.count < 0) _this.isdetected = "请您保持脸部在画面中央";
  143. //this.isdetected = '已检测到人脸,正在登录'
  144. }
  145. });
  146. })
  147. .catch((error) => {
  148. // console.error("摄像头开启失败,请检查摄像头是否可用!");
  149. _this.$message.error("摄像头开启失败,请检查摄像头是否可用!");
  150. });
  151. },
  152. // 拍照
  153. photograph() {
  154. let ctx = this.$refs["canvas"].getContext("2d");
  155. // 把当前视频帧内容渲染到canvas上
  156. ctx.drawImage(this.$refs["video"], 0, 0, 300, 240);
  157. // 转base64格式、图片格式转换、图片质量压缩
  158. let imgBase64 = this.$refs["canvas"].toDataURL("image/jpeg", 0.7); // 由字节转换为KB 判断大小
  159. let str = imgBase64.replace("data:image/jpeg;base64,", "");
  160. let strLength = str.length;
  161. let fileLength = parseInt(strLength - (strLength / 8) * 2); // 图片尺寸 用于判断
  162. let size = (fileLength / 1024).toFixed(2);
  163. console.log(size); // 上传拍照信息 调用接口上传图片 .........
  164. // 保存到本地
  165. // this.isCamera = false;
  166. let ADOM = document.createElement("a");
  167. ADOM.href = imgBase64;
  168. ADOM.download = new Date().getTime() + ".jpeg";
  169. ADOM.click();
  170. this.$message({
  171. message: "保存成功",
  172. type: "success",
  173. });
  174. },
  175. // 关闭摄像头
  176. closeCamera() {
  177. if (!this.$refs["video"].srcObject) {
  178. this.isCamera = false;
  179. return;
  180. }
  181. let stream = this.$refs["video"].srcObject;
  182. let tracks = stream.getTracks();
  183. tracks.forEach((track) => {
  184. track.stop();
  185. });
  186. this.$refs["video"].srcObject = null;
  187. this.isCamera = false;
  188. },
  189. },
  190. mounted() {
  191. // console.log(this.$store.state.function);
  192. // var _s3 = document.createElement("script");
  193. // _s3.src = "/static/materialize/jquery-2.1.3.min.js";
  194. // _s3.type = "text/javascript";
  195. // document.head.appendChild(_s3);
  196. // var _s2 = document.createElement("script");
  197. // _s2.src = "/static/camera.283d5d54.js";
  198. // _s2.type = "text/javascript";
  199. // document.head.appendChild(_s2);
  200. // var _s1 = document.createElement("script");
  201. // _s1.src = "/static/bundle.js";
  202. // _s1.type = "text/javascript";
  203. // document.head.appendChild(_s1);
  204. // console.log(this.$store.state.function);
  205. // if (this.$store.state.function == 1) {
  206. // this.$message.error("摄像头开启失败,请检查摄像头是否可用!");
  207. // }
  208. this.videoEl = this.$refs.video;
  209. this.canvasEL = this.$refs.canvasDOM;
  210. },
  211. };
  212. </script>
  213. <style scoped>
  214. html,
  215. body {
  216. margin: 0;
  217. padding: 0;
  218. width: 100%;
  219. }
  220. .tip {
  221. margin: 25px 0 30px 20px;
  222. width: 419px;
  223. }
  224. .tip > img,
  225. #screan > img,
  226. #tou > img,
  227. #ai > img,
  228. #police > img,
  229. .right > img {
  230. width: 100%;
  231. height: 100%;
  232. user-select: none;
  233. }
  234. .img {
  235. display: flex;
  236. flex-direction: row;
  237. justify-content: flex-start;
  238. /* align-items: center; */
  239. /* margin: auto; */
  240. width: 100%;
  241. height: 100%;
  242. position: relative;
  243. /* position: relative; */
  244. }
  245. #screan {
  246. width: 265px;
  247. position: absolute;
  248. z-index: 4;
  249. top: 174px;
  250. left: 114.3px;
  251. }
  252. #ai {
  253. width: 265px;
  254. position: absolute;
  255. z-index: 3;
  256. top: 170px;
  257. left: 114.3px;
  258. }
  259. #tou {
  260. width: 83px;
  261. position: absolute;
  262. z-index: 5;
  263. top: 123px;
  264. left: 205px;
  265. }
  266. #police {
  267. width: 490px;
  268. position: absolute;
  269. z-index: 2;
  270. }
  271. .button {
  272. color: #fff;
  273. background: #8ca1de;
  274. width: 550px;
  275. height: 55px;
  276. font-size: 20px;
  277. text-align: center;
  278. line-height: 55px;
  279. position: absolute;
  280. bottom: 10%;
  281. left: 50%;
  282. transform: translateX(-50%);
  283. user-select: none;
  284. }
  285. .right {
  286. width: 40px;
  287. position: absolute;
  288. left: 55%;
  289. top: 70%;
  290. display: none;
  291. }
  292. .dark {
  293. background: #5b79d0;
  294. cursor: pointer;
  295. }
  296. .controlZ {
  297. width: 490px;
  298. height: 900px;
  299. margin-left: calc(50% - (490px / 2));
  300. position: relative;
  301. }
  302. .cameraZ {
  303. display: flex;
  304. height: 340px;
  305. }
  306. .cameraZ div {
  307. margin-left: 10px;
  308. }
  309. .cameraBtn {
  310. display: flex;
  311. flex-direction: column;
  312. align-items: center;
  313. }
  314. .cameraBtn button {
  315. margin: 0 0 10px 0;
  316. }
  317. .face {
  318. position: absolute;
  319. z-index: 1;
  320. padding: 26.5px 0;
  321. }
  322. .kuang {
  323. padding: 26.5px 0;
  324. position: absolute;
  325. z-index: 2;
  326. }
  327. </style>