function.vue 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249
  1. <template>
  2. <div style="width: 100%; height: 100%">
  3. <div class="img">
  4. <div class="controlZ">
  5. <div id="screan" ref="dv">
  6. <img :src="img[0]" alt="" v-show="!isCamera" />
  7. <!--图片展示-->
  8. <video
  9. ref="video"
  10. width="130"
  11. height="130"
  12. autoplay
  13. v-show="isCamera"
  14. ></video>
  15. </div>
  16. <div id="tou" ref="dv1">
  17. <img :src="img[2]" alt="" />
  18. </div>
  19. <div id="ai" ref="dv2">
  20. <img :src="img[1]" alt="" />
  21. </div>
  22. <div id="police" ref="dv2">
  23. <img :src="img[3]" alt="" />
  24. </div>
  25. </div>
  26. <div class="cameraZ">
  27. <!--开启摄像头-->
  28. <div class="cameraBtn">
  29. <el-button
  30. size="mini"
  31. type="primary"
  32. @click="callCamera"
  33. v-if="!isCamera"
  34. >开启摄像头</el-button
  35. >
  36. <el-button size="mini" type="primary" @click="closeCamera" v-else
  37. >关闭摄像头</el-button
  38. >
  39. <el-button size="mini" type="primary" @click="photograph"
  40. >确认保存</el-button
  41. >
  42. </div>
  43. <!--确认-->
  44. <div>
  45. <!--canvas截取流-->
  46. <canvas ref="canvas" width="300" height="240" v-if="isCamera"></canvas>
  47. </div>
  48. </div>
  49. </div>
  50. </div>
  51. </template>
  52. <script>
  53. export default {
  54. data() {
  55. return {
  56. that: this,
  57. img: [
  58. require("../assets/img/screan.png"),
  59. require("../assets/img/ai.png"),
  60. require("../assets/img/tou.png"),
  61. require("../assets/img/police.png"),
  62. ],
  63. isCamera: false,
  64. };
  65. },
  66. methods: {
  67. // 调用摄像头
  68. callCamera() {
  69. let _this = this;
  70. // H5调用电脑摄像头API
  71. navigator.mediaDevices
  72. .getUserMedia({
  73. video: true,
  74. })
  75. .then((success) => {
  76. _this.isCamera = true;
  77. // 摄像头开启成功
  78. _this.$refs["video"].srcObject = success;
  79. // 实时拍照效果
  80. _this.$refs["video"].play();
  81. })
  82. .catch((error) => {
  83. // console.error("摄像头开启失败,请检查摄像头是否可用!");
  84. _this.$message.error('摄像头开启失败,请检查摄像头是否可用!');
  85. });
  86. },
  87. // 拍照
  88. photograph() {
  89. let ctx = this.$refs["canvas"].getContext("2d");
  90. // 把当前视频帧内容渲染到canvas上
  91. ctx.drawImage(this.$refs["video"], 0, 0, 300, 240);
  92. // 转base64格式、图片格式转换、图片质量压缩
  93. let imgBase64 = this.$refs["canvas"].toDataURL("image/jpeg", 0.7); // 由字节转换为KB 判断大小
  94. let str = imgBase64.replace("data:image/jpeg;base64,", "");
  95. let strLength = str.length;
  96. let fileLength = parseInt(strLength - (strLength / 8) * 2); // 图片尺寸 用于判断
  97. let size = (fileLength / 1024).toFixed(2);
  98. console.log(size); // 上传拍照信息 调用接口上传图片 .........
  99. // 保存到本地
  100. // this.isCamera = false;
  101. let ADOM = document.createElement("a");
  102. ADOM.href = imgBase64;
  103. ADOM.download = new Date().getTime() + ".jpeg";
  104. ADOM.click();
  105. this.$message({
  106. message: '保存成功',
  107. type: 'success'
  108. });
  109. },
  110. // 关闭摄像头
  111. closeCamera() {
  112. if (!this.$refs["video"].srcObject) {
  113. this.isCamera = false;
  114. return;
  115. }
  116. let stream = this.$refs["video"].srcObject;
  117. let tracks = stream.getTracks();
  118. tracks.forEach((track) => {
  119. track.stop();
  120. });
  121. this.$refs["video"].srcObject = null;
  122. this.isCamera = false;
  123. },
  124. },
  125. };
  126. </script>
  127. <style scoped>
  128. html,
  129. body {
  130. margin: 0;
  131. padding: 0;
  132. width: 100%;
  133. }
  134. .tip {
  135. margin: 25px 0 30px 20px;
  136. width: 419px;
  137. }
  138. .tip > img,
  139. #screan > img,
  140. #tou > img,
  141. #ai > img,
  142. #police > img,
  143. .right > img {
  144. width: 100%;
  145. height: 100%;
  146. user-select: none;
  147. }
  148. .img {
  149. display: flex;
  150. flex-direction: row;
  151. justify-content: flex-start;
  152. align-items: center;
  153. /* margin: auto; */
  154. width: 100%;
  155. height: 100%;
  156. position: relative;
  157. /* position: relative; */
  158. }
  159. #screan {
  160. width: 130px;
  161. position: absolute;
  162. z-index: 4;
  163. top: 85px;
  164. left: 55.3px;
  165. }
  166. #ai {
  167. width: 130px;
  168. position: absolute;
  169. z-index: 1;
  170. top: 82px;
  171. left: 55.3px;
  172. }
  173. #tou {
  174. width: 45px;
  175. position: absolute;
  176. z-index: 3;
  177. top: 56px;
  178. left: 97.5px;
  179. }
  180. #police {
  181. width: 240px;
  182. position: absolute;
  183. z-index: 2;
  184. }
  185. .button {
  186. color: #fff;
  187. background: #8ca1de;
  188. width: 550px;
  189. height: 55px;
  190. font-size: 20px;
  191. text-align: center;
  192. line-height: 55px;
  193. position: absolute;
  194. bottom: 10%;
  195. left: 50%;
  196. transform: translateX(-50%);
  197. user-select: none;
  198. }
  199. .right {
  200. width: 40px;
  201. position: absolute;
  202. left: 55%;
  203. top: 70%;
  204. display: none;
  205. }
  206. .dark {
  207. background: #5b79d0;
  208. cursor: pointer;
  209. }
  210. .controlZ {
  211. width: 240px;
  212. height: 450px;
  213. margin-left: 10%;
  214. position: relative;
  215. }
  216. .cameraZ {
  217. display: flex;
  218. height: 340px;
  219. }
  220. .cameraZ div {
  221. margin-left: 10px;
  222. }
  223. .cameraBtn {
  224. display: flex;
  225. flex-direction: column;
  226. align-items: center;
  227. }
  228. .cameraBtn button {
  229. margin: 0 0 10px 0;
  230. }
  231. </style>