当前位置: 首页 > news >正文

uniapp - 小程序实现摄像头拍照 + 水印绘制 + 反转摄像头 + 拍之前显示时间+地点 + 图片上传到阿里云服务器

前言

uniapp,碰到新需求,反转摄像头,需要在打卡的时候对上传图片加上水印,拍照前就显示当前时间日期+地点,拍摄后在呈现刚才拍摄的图加上水印,最好还需要将图片上传到阿里云。

声明

水印部分代码是借鉴的这位博主的博客,剩下的是我根据自己的需求加上的。水印部分看原博主博客就行。
小晗同学 - 原小程序拍照+水印绘制博主博客链接跳转

效果预览

拍摄前预览
右上角切换前后摄像头
底部时间和位置信息,这里位置替换掉真实位置了,代码里没变
在这里插入图片描述
拍摄后效果
在这里插入图片描述

水印组件代码

<template><view class="camera-wrapper"><!-- 拍照 --><template v-if="!snapSrc"><!-- 相机 --><camera :device-position="cameraPosition" flash="off" @error="handleError" class="image-size"><view class="photo-btn" @click="handleTakePhoto">拍照</view><view class="iconfont icon-qiehuanshexiangtou switch-camera-btn" @click="handleSwitchCamera"></view><view class="time-wrap"><view>{{ new Date().toLocaleString() }}</view><view>{{ location_data }}</view><!-- <view>这里是位置信息,</view> --></view></camera><!-- 水印 --><canvas canvas-id="photoMarkCanvas" id="photoMarkCanvas" class="mark-canvas":style="{ width: canvasWidth + 'px', height: canvasHeight + 'px' }" /></template><!-- 预览 --><template v-else><!-- <view class="re-photo-btn btn" @click="handleRephotograph">重拍</view> --><!-- <view class="re-fanhui-btn btn" @click="fanhui">返回</view> --><image class="image-size" :src="snapSrc"></image></template></view>
</template>
<script>
const util_two = require('../../static/utils/util_two.js')
const upload = require('../../static/utils/upload.js')
export default {name: 'CameraSnap',props: {// 照片地址(若传递了照片地址,则默认为预览该照片或添加水印后预览)photoSrc: {type: String,default: ""},// 水印类型markType: {type: String,default: "fixed", // 定点水印 fixed,背景水印 background},// 水印文本列表(支持多行)markList: {type: Array,default: () => []},textColor: {type: String,default: "#FFFFFF"},textSize: {type: Number,default: 32},// 定点水印的遮罩(为了让水印更清楚)useTextMask: {type: Boolean,default: true}},data() {return {snapSrc: "",canvasWidth: "",canvasHeight: "",cameraPosition: 'back', // 默认为后置摄像头inputText: "", // 用户输入的文本location: null, // 存储位置信息location_data: "",photocount: 10,hasUserInfo: false,productInfo: [],fileurl: [],prveImgInfo: [],imgs: [],arrImg: [],imgQueRemData: [],//确实上传数据源// 位置和时间日期}},watch: {photoSrc: {handler: function (newValue, oldValue) {if (newValue) {this.getWaterMarkImgPath(newValue)}},immediate: true}},mounted() {uni.getLocation({type: 'wgs84', // 获取经纬度坐标success: (res) => {this.location = res;setTimeout(() => {this.GetMapData();}, 1000);},fail: (err) => {console.error('获取位置信息失败', err);}});},methods: {closeCamera() {this.$emit('close'); // 发送一个事件通知父组件关闭 CameraSnap 组件},handleTakePhoto() {// const that = thisconst ctx = uni.createCameraContext();ctx.takePhoto({quality: 'high',success: (res) => {const imgPath = res.tempImagePathif (this.markList.length) {this.getWaterMarkImgPath(imgPath)this.$emit('watermarkPath', this.snapSrc);} else {this.snapSrc = imgPath;this.$emit('complete', imgPath)this.$emit('watermarkPath', this.snapSrc);}}});},handleRephotograph() {this.snapSrc = ""},handleSwitchCamera() {this.cameraPosition = this.cameraPosition === 'front' ? 'back' : 'front'; // 切换摄像头},handleError(err) {uni.showModal({title: '警告',content: '若不授权使用摄像头,将无法使用拍照功能!',cancelText: '不授权',confirmText: '授权',success: (res) => {if (res.confirm) {// 允许打开授权页面,调起客户端小程序设置界面,返回用户设置的操作结果uni.openSetting({success: (res) => {res.authSetting = { "scope.camera": true }},})} else if (res.cancel) {// 拒绝打开授权页面uni.showToast({ title: '您已拒绝授权,无法进行拍照', icon: 'error', duration: 2500 });}}})},setWaterMark(context, image) {const listLength = this.markList?.lengthswitch (this.markType) {case 'fixed':const spacing = 6 // 行间距const paddingTopBottom = 60 // 整体上下间距// 默认每行的高度 = 字体高度 + 向下间隔const lineHeight = this.textSize + spacingconst allLineHeight = lineHeight * listLength// 矩形遮罩的 Y 坐标const maskRectY = image.height - allLineHeight// 绘制遮罩层if (this.useTextMask) {context.setFillStyle('rgba(0,0,0,0.4)');context.fillRect(0, maskRectY - paddingTopBottom, image.width, allLineHeight + paddingTopBottom)}// 文本与 x 轴之间的间隔const textX = 40// 文本一行的最大宽度(减去 20 是为了一行的左右留间隙)const maxWidth = image.width - 20context.setFillStyle(this.textColor)context.setFontSize(this.textSize)this.markList.forEach((item, index) => {// 因为文本的 Y 坐标是指文本基线的 Y 轴坐标,所以要获取文本顶部的 Y 坐标const textY = maskRectY - paddingTopBottom / 2 + this.textSize + lineHeight * indexcontext.fillText(item, textX, textY, maxWidth);})break;case 'background':context.translate(0, 0);context.rotate(30 * Math.PI / 180);context.setFillStyle(this.textColor)context.setFontSize(this.textSize)const colSize = parseInt(image.height / 6)const rowSize = parseInt(image.width / 2)let x = -rowSizelet y = -colSize// 循环绘制 5 行 6 列 的文字for (let i = 1; i <= 6; i++) {for (let j = 1; j <= 5; j++) {context.fillText(this.markList[0], x, y, rowSize)// 每个水印间隔 20x += rowSize + 20}y += colSizex = -rowSize}break;}context.save();},getWaterMarkImgPath(src) {const _this = thisuni.getImageInfo({src,success: (image) => {this.canvasWidth = image.widththis.canvasHeight = image.heightconst context = uni.createCanvasContext("photoMarkCanvas", this)context.drawImage(src, 0, 0, image.width, image.height)// 设置水印this.setWaterMark(context, image)// 若还需其他操作,可在操作之后叠加保存:context.restore()// 将画布上的图保存为图片context.draw(false, () => {setTimeout(() => {uni.canvasToTempFilePath({destWidth: image.width,destHeight: image.height,canvasId: 'photoMarkCanvas',fileType: 'jpg',success: function (res) {console.log("将画布上的图保存为图片", JSON.parse(JSON.stringify(res)));_this.snapSrc = res.tempFilePathconst tempFilePath = res.tempFilePath;const tempFilePathArray = [tempFilePath];_this.uploadimg({path: tempFilePathArray //这里是选取的图片的地址数组});_this.$emit('complete', _this.snapSrc)}},_this);}, 200)});}})},fanhui() {this.closeCamera();},sendUploadedImagesToParent() {this.$emit('imagesUploaded', this.prveImgInfo);// prveImgInfo  imgs},//多张图片上传  服务器uploadimg: function (data) {// 这两个是对应的,传递的就是这个路径var that = this;// var orderid = that.XmID;//项目idvar orderid = '';// var gsid = '';let photocount = 9;var i = data.i ? data.i : 0; //当前上传的哪张图片var success = data.success ? data.success : 0; //上传成功的个数var fail = data.fail ? data.fail : 0; //上传失败的个数//上传到阿里云util_two.request(uni.$baseUrlweb + '/api/xcx/oss/fankui').then(function (result) {if (result.code == 0) {// var filePath = data.path;var filePath = data.path[i];var filename = result.dir + orderid + upload.calculate_object_name(filePath, '');uni.uploadFile({url: result.host,filePath: filePath,name: "file",/**上传的参数**/formData: {'key': filename, // 文件名'policy': result.policy,'OSSAccessKeyId': result.accessid,'success_action_status': "200",'signature': result.signature,'callback': result.callback},success: (resp) => {if (resp.statusCode == "200") {success++; //图片上传成功,图片上传成功的变量+1photocount--;var show_url = result.host + '/' + filename + result.style1;var productInfo = that.productInfo;productInfo.push(show_url);var prve_url = result.host + '/' + filename + result.style2;var prveImgInfo = that.prveImgInfo;prveImgInfo.push(prve_url);that.sendUploadedImagesToParent();var up_url = filename;var fileurl = that.fileurl;fileurl.push(up_url);let n = i + 1;uni.showLoading({title: n + '/' + data.path.length + '上传成功', //这里打印出 上传成功})}},fail: (res) => {fail++; //图片上传失败,图片上传失败的变量+1uni.showLoading({title: (i + 1) + '/' + data.path.length + '上传失败', //这里打印出 上传成功})},complete: (res) => {i++; //这个图片执行完上传后,开始上传下一张if (i == data.path.length) { //当图片传完时,停止调用     // 添加上传数据that.imgQueRemData.push(filename)// 添加到展示数组const path = result.host + '/' + filename + result.style1that.arrImg.push(path)that.imgs.push(path)uni.hideLoading();that.closeCamera();if (success == i) {uni.showToast({title: '组图上传完成', //这里打印出 上传成功icon: 'success',duration: 1000})} else {uni.showModal({title: '组图上传失败', //这里打印出 上传成功content: '请稍后再试',showCancel: false})}} else { //若图片还没有传完,则继续调用函数data.i = i;data.success = success;data.fail = fail;that.uploadimg(data);}}});}})},// 获取具体位置信息async GetMapData() {const res = await this.$axios("work/getMap", {lat: this.location.latitude,lon: this.location.longitude});if (res.data.code == 0) {this.location_data = res.data.result;} else {uni.showToast({title: res.data.msg,icon: 'none',duration: 1000})}},}
}
</script>
<style lang="scss" scoped>
.icon-qiehuanshexiangtou {font-size: 30px;
}.camera-wrapper {position: relative;
}.switch-camera-btn {position: absolute;top: 20px;right: 20px;color: #fff;font-size: 16px;cursor: pointer;
}.mark-canvas {position: absolute;/* 将画布移出展示区域 */top: -200vh;left: -200vw;
}.image-size {width: 100%;height: 100vh;
}.photo-btn {position: absolute;bottom: 120rpx;left: 50%;transform: translateX(-50%);width: 140rpx;height: 140rpx;line-height: 140rpx;text-align: center;background-color: #000000;border-radius: 50%;border: 10rpx solid #ffffff;color: #fff;
}.btn {padding: 10rpx 20rpx;background-color: #000000;border-radius: 10%;border: 6rpx solid #ffffff;color: #fff
}.re-photo-btn {position: absolute;bottom: 150rpx;right: 40rpx;}.re-fanhui-btn {position: absolute;bottom: 150rpx;right: 180rpx;}.re-fanhui-tijao {position: absolute;bottom: 150rpx;right: 320rpx;}.time-wrap {position: absolute;left: 1rem;bottom: 1rem;color: white;
}
</style>

使用水印相机组件代码

<template><view><view class="qianDao_img"><view class="imgs"><view style="margin-right: 10px;">照片:</view><view @click="paizhao" class="paizhao"><view class="iconfont icon-paizhao1"></view></view></view><view class="img_wrap"><image v-for="(item, index) in shuiyinImg" :key="index" :src="item" mode="scaleToFill"@click="SYpreviewImage(index)" @longpress="SYdeleteImage(index)" /></view></view><!-- <button @click="paizhao">拍照</button> --><view class="full-screen" v-if="paizhaoType"><CameraSnap @imagesUploaded="handleImagesUploaded" @close="paizhaoType = false":mark-list="[new Date().toLocaleString(), location_data]" textSize="24" useTextMask /></view><view class="Bom_Btn"><view @click="BaoCunAction" class="Bom_Btn_log"><view>提交</view></view></view></view>
</template><script>import CameraSnap from '../CameraSnap.vue'export default {data() {return {paizhaoType: false,location: null, // 存储位置信息location_data: "",// 水印图片shuiyinImg: '',};},components: {CameraSnap,},onLoad(options) {uni.getLocation({type: 'wgs84', // 获取经纬度坐标success: (res) => {this.location = res;setTimeout(() => {this.GetMapData();}, 1000);},fail: (err) => {console.error('获取位置信息失败', err);}});},methods: {// 这里是水印图片handleImagesUploaded(images) {console.log("成功上传的图片数据:", images);this.shuiyinImg = [...this.shuiyinImg, ...images];},paizhao() {this.paizhaoType = true;},// 获取具体位置信息async GetMapData() {const res = await this.$axios("work/getMap", {lat: this.location.latitude,lon: this.location.longitude});if (res.data.code == 0) {this.location_data = res.data.result;} else {uni.showToast({title: res.data.msg,icon: 'none',duration: 1000})}},// 水印图片预览SYpreviewImage(index) {uni.previewImage({urls: this.shuiyinImg,current: index, // 当前显示图片的索引loop: true // 是否开启图片轮播});},// 长按删除水印图片SYdeleteImage(index) {uni.showModal({title: '提示',content: '确定要删除这张图片吗?',success: (res) => {if (res.confirm) {this.shuiyinImg.splice(index, 1);}}});},}
}
</script><style lang="scss" scoped>
.full-screen {position: fixed;top: 0;left: 0;width: 100vw;height: 100vh;// background-color: rgba(0, 0, 0, 0.5); /* 半透明背景 */z-index: 9999;/* 确保在最顶层显示 */
}// 签到图片
.qianDao_img {// padding: 15px;border-top: 1px solid #dddddf;background-color: white;// 图片.imgs {padding: 15px;display: flex;align-items: center;flex-wrap: wrap;}.img_wrap {padding: 10px;display: flex;// justify-content: space-around;flex-wrap: wrap;image {width: 80px;height: 80px;margin-bottom: 5px;margin: 4px;}}// 上传图片.paizhao {width: 80px;height: 80px;// border: 1px solid red;margin: 10px 0;background-color: #f7f8fa;.icon-paizhao1 {// border: 1px solid red;width: 50%;font-size: 22px;padding-left: 25px;padding-top: 25px;}}
}.Bom_Btn {width: 100%;padding: 10px;position: absolute;bottom: 0;left: 0;border-top: 1px solid #ededed;background-color: white;z-index: 2;.Bom_Btn_log {width: 70%;// display: flex;// align-items: center;// justify-content: center;// margin: auto;padding: 10px 0;margin: auto;}view {border-radius: 5px;text-align: center;color: white;background-color: #1989fa;}
}
</style>

只能说勉强够用,算不上精细,凑合看把,引入的两个js文件 都是辅助上传阿里云图片的,就是格式啥的进行校验,就没必要上传了,看懂整个思路就行,具体代码肯定还是需要根据自己的情况进行改动的

相关文章:

uniapp - 小程序实现摄像头拍照 + 水印绘制 + 反转摄像头 + 拍之前显示时间+地点 + 图片上传到阿里云服务器

前言 uniapp&#xff0c;碰到新需求&#xff0c;反转摄像头&#xff0c;需要在打卡的时候对上传图片加上水印&#xff0c;拍照前就显示当前时间日期地点&#xff0c;拍摄后在呈现刚才拍摄的图加上水印&#xff0c;最好还需要将图片上传到阿里云。 声明 水印部分代码是借鉴的…...

Qt天气预报系统设计界面布局第四部分左边

Qt天气预报系统设计 1、第四部分左边的第一部分1.1添加控件1.2修改控件名字 2、第四部分左边的第二部分2.1添加控件2.2修改控件名字 3、第四部分左边的第三部分3.1添加控件3.2修改控件名字 4、对整个widget04l调整 1、第四部分左边的第一部分 1.1添加控件 拖入一个widget&…...

VS无法找到低版本的.net,vs2022创建不了.net6的项目

很多人会遇到安装完vs最新版(目前是2022)之后&#xff0c;创建不了旧版本的.net项目了&#xff0c;比如我在学习.net core 6&#xff0c;我的2022无法创建&#xff0c;只能创建.netcore8的项目&#xff0c;以及又安装了2019&#xff0c;同样无法创建&#xff0c;接下来介绍怎么…...

C++软件设计模式之解释器模式

解释器模式的目的和意图 解释器模式&#xff08;Interpreter Pattern&#xff09;是一种行为设计模式&#xff0c;主要用于定义一种语言的文法&#xff0c;并通过该文法解释语言中的句子&#xff08;表达式&#xff09;。解释器模式的核心思想是将一个特定的语言表示为其文法规…...

小程序发版后,用户使用时,强制更新为最新版本

为什么要强制更新为最新版本&#xff1f; 在小程序的开发和运营过程中&#xff0c;强制用户更新到最新版本是一项重要的策略&#xff0c;能够有效提升用户体验并保障系统的稳定性与安全性。以下是一些主要原因&#xff1a; 1. 功能兼容 新功能或服务通常需要最新版本的支持&…...

如何使用AI工具cursor(内置ChatGPT 4o+claude-3.5)

⚠️温馨提示&#xff1a; 禁止商业用途&#xff0c;请支持正版&#xff0c;充值使用&#xff0c;尊重知识产权&#xff01; 免责声明&#xff1a; 1、本教程仅用于学习和研究使用&#xff0c;不得用于商业或非法行为。 2、请遵守Cursor的服务条款以及相关法律法规。 3、本…...

说说缓存使用的具体场景都有哪些?缓存和数据库一致性问题该如何解决?缓存使用常见问题有哪些?

面试官&#xff1a;说说缓存使用的具体场景都有哪些&#xff1f;缓存和数据库一致性问题该如何解决&#xff1f;缓存使用常见问题有哪些&#xff1f; 缓存的具体使用场景有这些&#xff1a; 数据频繁读取&#xff1a; 当某些数据频繁被读取而不常变化时&#xff0c;可以将这些…...

2025-01-01 NO2. XRHands 介绍

文章目录 软件配置1 XR Hands 简介2 XRHand2.1 Pose2.2 Handedness 3 XRHandJoint3.1 XRHandJointID3.2 XRHandJointTrackingState 4 XRHandSubsystem4.1 数据属性4.1.1 UpdateSuccessFlags4.1.2 UpdateType 4.2 处理器管理&#xff1a;注册和注销4.3 更新手部数据&#xff1a;…...

Java开发-后端请求成功,前端显示失败

文章目录 报错解决方案1. 后端未配置跨域支持2. 后端响应的 Content-Type 或 CORS 配置问题3. 前端 request 配置问题4. 浏览器缓存或代理问题5. 后端端口未被正确映射 报错 如下图&#xff0c;后端显示请求成功&#xff0c;前端显示失败 解决方案 1. 后端未配置跨域支持 …...

未来20年在大语言模型相关研究方向--大语言模型的优化与改进

未来20年在大语言模型相关研究方向 模型性能优化 模型架构创新:研究新型的模型架构,如探索更高效的Transformer变体、融合递归神经网络(RNN)和卷积神经网络(CNN)的优点,以提高模型的性能、可扩展性和适应性,满足不同应用场景对模型效率和效果的要求。高效训练算法:开…...

[react] 纯组件优化子

有组件如下,上面变化秒数, 下面是大量计算的子组件,上面每一秒钟变化一次,这时候子组件会不断重新渲染, 浪费资源 父组件如下 import React, { memo, useEffect, useMemo, useState } from react; import type { ReactNode, FC } from react; import HugeCount from ./Te; int…...

美观强大的文件保险库Chibisafe

简介 什么是 Chibisafe &#xff1f; Chibisafe 是一款用 Typescript 编写的快速文件上传服务&#xff0c;非常实用。它接受文件、照片、文档以及您能想到的任何内容&#xff0c;并返回可共享的链接&#xff0c;供您发送给其他人。它易于使用、易于部署、免费且开源&#xff0…...

详细教程:SQL2008数据库备份与还原全流程!

数据的安全性至关重要&#xff0c;无论是操作系统、重要文件、磁盘存储&#xff0c;还是企业数据库&#xff0c;备份都是保障其安全和完整性的关键手段。拥有备份意味着即使发生误删、系统崩溃或病毒攻击等问题&#xff0c;也能迅速通过恢复功能解决&#xff0c;避免数据丢失带…...

HTML——49.header和footer标签

<!DOCTYPE html> <html><head><meta charset"UTF-8"><title>header和footer标签</title></head><body><!--header和footer标签:是html5中新标签--><!--header:定义文档的页眉&#xff0c;通常用来定义可见…...

【蓝桥杯选拔赛真题87】python输出字符串 第十五届青少年组蓝桥杯python选拔赛真题 算法思维真题解析

目录 python输出字符串 一、题目要求 1、编程实现 2、输入输出 二、算法分析 三、程序编写 四、程序说明 五、运行结果 六、考点分析 七、 推荐资料 1、蓝桥杯比赛 2、考级资料 3、其它资料 python输出字符串 第十五届蓝桥杯青少年组python比赛选拔赛真题详细解析…...

OpenStack-Dashboard界面简单修改

OpenStack Dashboard界面替换图片 一、dashboard界面Logo的路径及文件 dashboard的Logo存放&#xff08;在Controller节点&#xff09;的路径&#xff1a; /usr/share/openstack-dashboard/openstack_dashboard/static/dashboard/img/涉及需要修改的文件&#xff08;3个&…...

DevOps工程技术价值流:Ansible自动化与Semaphore集成

在DevOps的浪潮中&#xff0c;自动化运维工具扮演着举足轻重的角色。Ansible&#xff0c;作为一款新兴的自动化运维工具&#xff0c;凭借其强大的功能和灵活性&#xff0c;在运维领域迅速崭露头角。本文将深入探讨Ansible的特点、架构、工作原理&#xff0c;以及其应用场景&…...

【服务器】上传文件到服务器并训练深度学习模型下载服务器文件到本地

前言&#xff1a;本文教程为&#xff0c;上传文件到服务器并训练深度学习模型&#xff0c;与下载服务器文件到本地。演示指令输入&#xff0c;完整的上传文件到服务器&#xff0c;并训练模型过程&#xff1b;并演示完整的下载服务器文件到本地的过程。 本文使用的服务器为云服…...

第四届电子信息工程与数据处理(EIEDP 2025)

第四届电子信息工程与数据处理 2025 4th International Conference on Electronic Information Engineering and Data Processing 2025年1月17-19日 马来西亚 吉隆坡 重要信息 会议官网&#xff1a;www.eiedp.net 大会时间&#xff1a;2025年1月17-19日 大会地点&#…...

模型预测控制(MPC)算法介绍

模型预测控制&#xff08;Model Predictive Control&#xff0c;MPC&#xff09;是一种先进的控制策略&#xff0c;广泛应用于工业过程控制、机器人控制、电力系统等领域。它基于系统的模型&#xff0c;通过滚动优化来预测系统未来的行为&#xff0c;并据此确定当前的最优控制输…...

设计模式 创建型 建造者模式(Builder Pattern)与 常见技术框架应用 解析

建造者模式&#xff0c;又称生成器模式&#xff0c;是一种对象构建模式。它主要用于构建复杂对象&#xff0c;通过将复杂对象的构建过程与其表示分离&#xff0c;使得同样的构建过程可以创建出具有不同表示的对象。该模式的核心思想是将一个复杂对象的构建过程分解为多个简单的…...

嵌入式系统中C++的基本使用方法

大家好,今天主要给大家分享一下,最近操作C++代码的控制方法。 什么是构造函数?构造函数在对象实例化时被系统自动调用,仅且调用一次。 什么是析构函数?与构造函数相反, 在对象结束其生命周期时系统自动执行析构函数。 第一个:析构函数与构造函数区别 实例代码: #inclu…...

机器人C++开源库The Robotics Library (RL)使用手册(四)

建立自己的机器人3D模型和运动学模型 这里以国产机器人天机TR8为例,使用最普遍的DH运动学模型,结合RL所需的描述文件,进行生成。 最终,需要的有两个文件,一个是.wrl三维模型描述文件;一个是.xml运动学模型描述文件。 1、通过STEP/STP三维文件生成wrl三维文件 机器人的…...

在 uni-app 中使用 wxml-to-canvas 的踩坑经验总结

在 uni-app 中使用 wxml-to-canvas 的踩坑经验总结 wxml-to-canvas 是一款非常强大的小程序工具&#xff0c;可以将 WXML 转换为 Canvas 绘图&#xff0c;用于生成海报、分享图片等。将其应用于 uni-app 项目中&#xff0c;可以为多端开发带来极大的便利&#xff0c;但也有一些…...

视频智能翻译

i68,爱六八,链接你我他 EasyVideoTrans英文视频转换成中文视频 EasyVideoTrans简要 最快的英文视频转中文方案由B站多位程序员Up主共同协作开发开源的项目在线Demo:EasyVideoTrans前端项目:https://github.com/sutro-planet/easyvideotrans-frontend后端项目:https://github…...

《Python加解密小实验:探索数据加密与解密的世界》

铺垫&#xff08;1&#xff09;-源码 import hashlib source "你好" # print(hashlib.md5(source.encode()).hexdigest())# 文件加解密 with open(../文件引用/index.png, rb) as file:data file.read() # print(hashlib.md5(data).hexdigest())# SHA也是摘要算法…...

C高级day四shell脚本

1.思维导图 2.终端输入一个C源文件名&#xff08;.c结尾&#xff09;判断文件是否有内容&#xff0c;如果没有内容删除文件&#xff0c;如果有内容编译并执行该文件。 #!/bin/bashread -p "请输入一个.c脚本名&#xff1a;" n if [ -s "$n" ] thenecho $n…...

android studio 写一个小计时器(版本二)

as版本&#xff1a;23.3.1patch2 例程&#xff1a;timer 在前一个版本的基本上改的&#xff0c;增加了继续的功能&#xff0c;实现方法稍微不同。 动画演示&#xff1a; activity_main.xml <?xml version"1.0" encoding"utf-8"?> <androidx…...

【网络安全实验室】SQL注入实战详情

如果额头终将刻上皱纹&#xff0c;你只能做到&#xff0c;不让皱纹刻在你的心上 1.最简单的SQL注入 查看源代码&#xff0c;登录名为admin 最简单的SQL注入&#xff0c;登录名写入一个常规的注入语句&#xff1a; 密码随便填&#xff0c;验证码填正确的&#xff0c;点击登录…...

华为,新华三,思科网络设备指令

1. 设备信息查看 华为 display version # 查看设备版本信息 display device # 查看设备硬件信息 新华三&#xff08;H3C&#xff09; display version # 查看设备版本信息 display device # 查看设备硬件信息 锐捷 show version …...