vue项目中基于fabric 插件实现涂鸦画布功能

vue项目中基于fabric 插件实现涂鸦画布功能

  • 一、效果图
  • 二、安装依赖
  • 三、main.js引入
  • 四、主要代码

一、效果图

在这里插入图片描述

二、安装依赖

 npm install fabric 

三、main.js引入

import fabric from 'fabric'
Vue.use(fabric);

四、主要代码

//封装成了一个组件
<template><el-dialogtitle="涂鸦生图":visible="visible"custom-class="doodleDialog"@close="handleClose"@open="openDialog"width="1500px"><div style="display: flex; justify-content: space-between"><div class="rigth"><p style="font-size: 16px">涂鸦区</p><div class="maintenancePlanAdd"><div class="child-panel-title"></div><div class="panel-body"><div class="demo"><canvas id="canvas" :width="width" :height="height"></canvas><div class="draw-btn-group"><div:class="{ active: drawType == '' }"title="自由选择"@click="drawTypeChange('')"><i class="draw-icon icon-mouse"></i></div><div:class="{ active: drawType == 'arrow' }"title="画箭头"@click="drawTypeChange('arrow')"><i class="draw-icon icon-1"></i></div><div:class="{ active: drawType == 'text' }"title="文本输入框"@click="drawTypeChange('text')"><i class="draw-icon icon-2"></i></div><div:class="{ active: drawType == 'ellipse' }"title="画圆"@click="drawTypeChange('ellipse')"><i class="draw-icon icon-3"></i></div><div:class="{ active: drawType == 'rectangle' }"title="画矩形"@click="drawTypeChange('rectangle')"><i class="draw-icon icon-4"></i></div><div:class="{ active: drawType == 'polygon' }"title="画多边形"@click="drawPolygon"><i class="draw-icon icon-6"></i></div><div:class="{ active: drawType == 'pen' }"title="笔画"@click="drawTypeChange('pen')"><i class="draw-icon icon-7"></i></div><div:class="{ active: drawType == 'pentagram' }"title="五角星"@click="drawTypeChange('pentagram')"><i class="draw-icon icon-pentagram"></i></div><div:class="{ active: drawType == 'delete' }"title="删除"@click="drawTypeDelete()"><i style="font-size: 26px" class="el-icon-delete"></i></div><!-- <div @click="uploadImg" title="从文件选择图片上传"><i class="draw-icon icon-img"></i></div><div @click="loadExpImg" title="加载背景图"><i class="draw-icon icon-back"></i></div><div @click="save" title="保存"><i class="draw-icon icon-save"></i></div> --></div></div></div><input type="file" @change="uploadImgChange" id="imgInput" accept="image/*" /><img id="img" :src="imgSrc" /><img id="expImg" src="../../../assets/images/draw/exp.jpg" /></div></div><div class="left" style="width: 600px"><p style="font-size: 16px">生成区</p><div style="border: 1px dashed black"><p style="text-align: center; margin-top: 5px">生成图片如下:</p><div style="width: 598px; height: 400px; margin-top: 18px; margin-bottom: 58px"><imgv-if="resultImg"style="width: 598px; height: 400px; display: inline-block":src="resultImg"alt=""/></div><el-formclass="screenwaper":model="addInnerFrom":rules="addRules"ref="addInnerFrom"label-width="90px"label-position="rigth"><el-form-item label="文字描述:" prop="prompt"><el-inputstyle="width: 500px"v-model="addInnerFrom.prompt"placeholder="请输入"size="small"type="textarea":rows="2"></el-input></el-form-item><el-form-item label="相似度:" prop="similarity"><el-sliderstyle="width: 500px"v-model="addInnerFrom.similarity":format-tooltip="formatTooltip"></el-slider></el-form-item><p style="text-align: center; margin: 20px 0 30px"><el-buttonsize="small"type="primary":loading="loading"@click="handleSureDialog('addInnerFrom')">确定生成</el-button></p></el-form></div></div></div><div style="text-align: center; padding: 20px 0 0"><el-button size="small" @click="handleSure">关 闭</el-button></div></el-dialog>
</template><script>
import { fabric } from 'fabric';
import { doodleImg } from '../api';
export default {name: 'doodleDialog',props: {visible: {type: Boolean,default: false,},},data() {return {addInnerFrom: { prompt: '', imageUploadData: '', similarity: 0 },addRules: {prompt: [{ required: true, message: '请输入标题', trigger: 'blur' }],similarity: [{ required: true, message: '请输入文本描述', trigger: 'blur' }],},loading: false,width: 800,height: 700,rect: [],canvas: {},showMenu: false,x: '',y: '',mouseFrom: {},mouseTo: {},drawType: null, //当前绘制图像的种类canvasObjectIndex: 0,textbox: null,rectangleLabel: 'warning',drawWidth: 2, //笔触宽度color: '#E34F51', //画笔颜色drawingObject: null, //当前绘制对象moveCount: 1, //绘制移动计数器doDrawing: false, // 绘制状态//polygon 相关参数polygonMode: false,pointArray: [],lineArray: [],activeShape: false,activeLine: '',line: {},delectKlass: {},imgFile: {},imgSrc: '',resultImg: '',};},watch: {drawType() {this.canvas.selection = !this.drawType;},width() {this.canvas.setWidth(this.width);},height() {this.canvas.setHeight(this.height);},},methods: {formatTooltip(val) {return val / 100;},openDialog() {this.resultImg = '';this.loading = false;this.addInnerFrom = { prompt: '', imageUploadData: '', similarity: 0 };this.$nextTick(() => {this.canvas = new fabric.Canvas('canvas', {// skipTargetFind: false, //当为真时,跳过目标检测。目标检测将返回始终未定义。点击选择将无效// selectable: false,  //为false时,不能选择对象进行修改// selection: false   // 是否可以多个对象为一组});this.canvas.selectionColor = 'rgba(0,0,0,0.05)';this.canvas.on('mouse:down', this.mousedown);this.canvas.on('mouse:move', this.mousemove);this.canvas.on('mouse:up', this.mouseup);document.onkeydown = e => {// 键盘 delect删除所选元素if (e.keyCode == 46) {this.deleteObj();}// ctrl+z 删除最近添加的元素if (e.keyCode == 90 && e.ctrlKey) {this.canvas.remove(this.canvas.getObjects()[this.canvas.getObjects().length - 1]);}};});},//  画布下面删除按钮drawTypeDelete() {this.drawType = 'delete';this.canvas.clear();},handleClose() {this.canvas.clear();this.$emit('DialogCancel');},handleSure() {this.handleClose();this.$emit('DialogOk', this.resultImg);},handleSureDialog(From) {this.$refs[From].validate(valid => {if (valid) {this.loading = true;let canvas = document.getElementById('canvas');this.addInnerFrom.imageUploadData = canvas.toDataURL('png');doodleImg({imageFile: this.addInnerFrom.imageUploadData,prompt: this.addInnerFrom.prompt,similarity: this.formatTooltip(this.addInnerFrom.similarity),}).then(({ data }) => {if (data.length) {this.loading = false;this.resultImg = data[0];this.$message({showClose: true,message: `已成功生成图片${data.length}`,type: 'success',});}});} else {console.log('error submit!!');return false;}});},// 保存当前画布为png图片save() {let canvas = document.getElementById('canvas');let imgData = canvas.toDataURL('png');console.log(imgData, 'wwww');imgData = imgData.replace('image/png', 'image/octet-stream');// 下载后的问题名,可自由指定let filename = 'drawingboard_' + new Date().getTime() + '.' + 'png';this.saveFile(imgData, filename);},saveFile(data, filename) {let save_link = document.createElement('a');save_link.href = data;save_link.download = filename;let event = document.createEvent('MouseEvents');event.initMouseEvent('click',true,false,window,0,0,0,0,0,false,false,false,false,0,null);save_link.dispatchEvent(event);},uploadImg() {document.getElementById('imgInput').click();},// 从已渲染的DOM元素加载图片至canvasloadExpImg() {let imgElement = document.getElementById('expImg'); //声明我们的图片let imgInstance = new fabric.Image(imgElement, {selectable: false,// zIndex:-99,});this.canvas.add(imgInstance);},// 从文件加载图片至canvasuploadImgChange() {// 获取文件let eleImportInput = document.getElementById('imgInput');this.imgFile = eleImportInput.files[0];let imgSrc = '',imgTitle = '';// 从reader中获取选择文件的srcif (/\.(jpe?g|png|gif)$/i.test(this.imgFile.name)) {let reader = new FileReader();let _this = this;reader.addEventListener('load',function () {imgTitle = _this.imgFile.name;_this.imgSrc = this.result;},false);reader.readAsDataURL(this.imgFile);}let imgElement = document.getElementById('img'); //声明我们的图片imgElement.onload = () => {this.width = imgElement.width;this.height = imgElement.height;let imgInstance = new fabric.Image(imgElement, {zIndex: -1,selectable: false,});this.canvas.add(imgInstance);};},// 开始绘制时,指定绘画种类drawTypeChange(e) {this.drawType = e;this.canvas.skipTargetFind = !!e;if (e == 'pen') {// isDrawingMode为true 才可以自由绘画this.canvas.isDrawingMode = true;} else {this.canvas.isDrawingMode = false;}},// 鼠标按下时触发mousedown(e) {// 记录鼠标按下时的坐标let xy = e.pointer || this.transformMouse(e.e.offsetX, e.e.offsetY);this.mouseFrom.x = xy.x;this.mouseFrom.y = xy.y;this.doDrawing = true;if (this.drawType == 'text') {this.drawing();}if (this.textbox) {this.textbox.enterEditing();this.textbox.hiddenTextarea.focus();}// 绘制多边形if (this.drawType == 'polygon') {this.canvas.skipTargetFind = false;try {// 此段为判断是否闭合多边形,点击红点时闭合多边形if (this.pointArray.length > 1) {// e.target.id == this.pointArray[0].id 表示点击了初始红点if (e.target && e.target.id == this.pointArray[0].id) {this.generatePolygon();}}//未点击红点则继续作画if (this.polygonMode) {this.addPoint(e);}} catch (error) {console.log(error);}}},// 鼠标松开执行mouseup(e) {let xy = e.pointer || this.transformMouse(e.e.offsetX, e.e.offsetY);this.mouseTo.x = xy.x;this.mouseTo.y = xy.y;this.drawingObject = null;this.moveCount = 1;if (this.drawType != 'polygon') {this.doDrawing = false;}},//鼠标移动过程中已经完成了绘制mousemove(e) {if (this.moveCount % 2 && !this.doDrawing) {//减少绘制频率return;}this.moveCount++;let xy = e.pointer || this.transformMouse(e.e.offsetX, e.e.offsetY);this.mouseTo.x = xy.x;this.mouseTo.y = xy.y;// 多边形与文字框特殊处理if (this.drawType != 'text' || this.drawType != 'polygon') {this.drawing(e);}if (this.drawType == 'polygon') {if (this.activeLine && this.activeLine.class == 'line') {let pointer = this.canvas.getPointer(e.e);this.activeLine.set({ x2: pointer.x, y2: pointer.y });let points = this.activeShape.get('points');points[this.pointArray.length] = {x: pointer.x,y: pointer.y,zIndex: 1,};this.activeShape.set({points: points,});this.canvas.renderAll();}this.canvas.renderAll();}},deleteObj() {this.canvas.getActiveObjects().map(item => {this.canvas.remove(item);});},transformMouse(mouseX, mouseY) {return { x: mouseX / 1, y: mouseY / 1 };},// 绘制多边形开始,绘制多边形和其他图形不一样,需要单独处理drawPolygon() {this.drawType = 'polygon';this.polygonMode = true;//这里画的多边形,由顶点与线组成this.pointArray = new Array(); // 顶点集合this.lineArray = new Array(); //线集合this.canvas.isDrawingMode = false;},addPoint(e) {let random = Math.floor(Math.random() * 10000);let id = new Date().getTime() + random;let circle = new fabric.Circle({radius: 5,fill: '#ffffff',stroke: '#333333',strokeWidth: 0.5,left: (e.pointer.x || e.e.layerX) / this.canvas.getZoom(),top: (e.pointer.y || e.e.layerY) / this.canvas.getZoom(),selectable: false,hasBorders: false,hasControls: false,originX: 'center',originY: 'center',id: id,objectCaching: false,});if (this.pointArray.length == 0) {circle.set({fill: 'red',});}let points = [(e.pointer.x || e.e.layerX) / this.canvas.getZoom(),(e.pointer.y || e.e.layerY) / this.canvas.getZoom(),(e.pointer.x || e.e.layerX) / this.canvas.getZoom(),(e.pointer.y || e.e.layerY) / this.canvas.getZoom(),];this.line = new fabric.Line(points, {strokeWidth: 2,fill: '#999999',stroke: '#999999',class: 'line',originX: 'center',originY: 'center',selectable: false,hasBorders: false,hasControls: false,evented: false,objectCaching: false,});if (this.activeShape) {let pos = this.canvas.getPointer(e.e);let points = this.activeShape.get('points');points.push({x: pos.x,y: pos.y,});let polygon = new fabric.Polygon(points, {stroke: '#333333',strokeWidth: 1,fill: '#cccccc',opacity: 0.3,selectable: false,hasBorders: false,hasControls: false,evented: false,objectCaching: false,});this.canvas.remove(this.activeShape);this.canvas.add(polygon);this.activeShape = polygon;this.canvas.renderAll();} else {let polyPoint = [{x: (e.pointer.x || e.e.layerX) / this.canvas.getZoom(),y: (e.pointer.y || e.e.layerY) / this.canvas.getZoom(),},];let polygon = new fabric.Polygon(polyPoint, {stroke: '#333333',strokeWidth: 1,fill: '#cccccc',opacity: 0.3,selectable: false,hasBorders: false,hasControls: false,evented: false,objectCaching: false,});this.activeShape = polygon;this.canvas.add(polygon);}this.activeLine = this.line;this.pointArray.push(circle);this.lineArray.push(this.line);this.canvas.add(this.line);this.canvas.add(circle);},generatePolygon() {let points = new Array();this.pointArray.map((point, index) => {points.push({x: point.left,y: point.top,});this.canvas.remove(point);});this.lineArray.map((line, index) => {this.canvas.remove(line);});this.canvas.remove(this.activeShape).remove(this.activeLine);let polygon = new fabric.Polygon(points, {stroke: this.color,strokeWidth: this.drawWidth,fill: 'rgba(255, 255, 255, 0)',opacity: 1,hasBorders: true,hasControls: false,});this.canvas.add(polygon);this.activeLine = null;this.activeShape = null;this.polygonMode = false;this.doDrawing = false;this.drawType = null;},drawing(e) {if (this.drawingObject) {this.canvas.remove(this.drawingObject);}let canvasObject = null;let left = this.mouseFrom.x,top = this.mouseFrom.y,mouseFrom = this.mouseFrom,mouseTo = this.mouseTo;switch (this.drawType) {case 'arrow':{//箭头let x1 = mouseFrom.x,x2 = mouseTo.x,y1 = mouseFrom.y,y2 = mouseTo.y;let w = x2 - x1,h = y2 - y1,sh = Math.cos(Math.PI / 4) * 16;let sin = h / Math.sqrt(Math.pow(w, 2) + Math.pow(h, 2));let cos = w / Math.sqrt(Math.pow(w, 2) + Math.pow(h, 2));let w1 = (16 * sin) / 4,h1 = (16 * cos) / 4,centerx = sh * cos,centery = sh * sin;/*** centerx,centery 表示起始点,终点连线与箭头尖端等边三角形交点相对x,y* w1 ,h1用于确定四个点*/let path = ' M ' + x1 + ' ' + y1;path += ' L ' + (x2 - centerx + w1) + ' ' + (y2 - centery - h1);path += ' L ' + (x2 - centerx + w1 * 2) + ' ' + (y2 - centery - h1 * 2);path += ' L ' + x2 + ' ' + y2;path += ' L ' + (x2 - centerx - w1 * 2) + ' ' + (y2 - centery + h1 * 2);path += ' L ' + (x2 - centerx - w1) + ' ' + (y2 - centery + h1);path += ' Z';canvasObject = new fabric.Path(path, {stroke: this.color,fill: this.color,strokeWidth: this.drawWidth,});}break;case 'pentagram':{//五角星let x1 = mouseFrom.x,x2 = mouseTo.x,y1 = mouseFrom.y,y2 = mouseTo.y;/*** 实现思路  (x1,y1)表示鼠标起始的位置 (x2,y2)表示鼠标抬起的位置* r 表示五边形外圈圆的半径,这里建议自己画个图理解* 正五边形夹角为36度。计算出cos18°,sin18°备用*/let w = Math.abs(x2 - x1),h = Math.abs(y2 - y1),r = Math.sqrt(w * w + h * h);let cos18 = Math.cos((18 * Math.PI) / 180);let sin18 = Math.sin((18 * Math.PI) / 180);/*** 算出对应五个点的坐标转化为路径*/let point1 = [x1, y1 + r];let point2 = [x1 + 2 * r * sin18, y1 + r - 2 * r * cos18];let point3 = [x1 - r * cos18, y1 + r * sin18];let point4 = [x1 + r * cos18, y1 + r * sin18];let point5 = [x1 - 2 * r * sin18, y1 + r - 2 * r * cos18];let path = ' M ' + point1[0] + ' ' + point1[1];path += ' L ' + point2[0] + ' ' + point2[1];path += ' L ' + point3[0] + ' ' + point3[1];path += ' L ' + point4[0] + ' ' + point4[1];path += ' L ' + point5[0] + ' ' + point5[1];path += ' Z';canvasObject = new fabric.Path(path, {stroke: this.color,fill: this.color,strokeWidth: this.drawWidth,// angle:180,  //设置旋转角度});}break;case 'ellipse':{//椭圆// 按shift时画正圆,只有在鼠标移动时才执行这个,所以按了shift但是没有拖动鼠标将不会画圆if (e.e.shiftKey) {mouseTo.x - left > mouseTo.y - top? (mouseTo.y = top + mouseTo.x - left): (mouseTo.x = left + mouseTo.y - top);}let radius =Math.sqrt((mouseTo.x - left) * (mouseTo.x - left) +(mouseTo.y - top) * (mouseTo.y - top)) / 2;canvasObject = new fabric.Ellipse({left: (mouseTo.x - left) / 2 + left,top: (mouseTo.y - top) / 2 + top,stroke: this.color,fill: 'rgba(255, 255, 255, 0)',originX: 'center',originY: 'center',rx: Math.abs(left - mouseTo.x) / 2,ry: Math.abs(top - mouseTo.y) / 2,strokeWidth: this.drawWidth,});}break;case 'rectangle':{//长方形// 按shift时画正方型if (e.e.shiftKey) {mouseTo.x - left > mouseTo.y - top? (mouseTo.y = top + mouseTo.x - left): (mouseTo.x = left + mouseTo.y - top);}let path ='M ' +mouseFrom.x +' ' +mouseFrom.y +' L ' +mouseTo.x +' ' +mouseFrom.y +' L ' +mouseTo.x +' ' +mouseTo.y +' L ' +mouseFrom.x +' ' +mouseTo.y +' L ' +mouseFrom.x +' ' +mouseFrom.y +' z';canvasObject = new fabric.Path(path, {left: left,top: top,stroke: this.color,strokeWidth: this.drawWidth,fill: 'rgba(255, 255, 255, 0)',hasControls: false,});}//也可以使用fabric.Rectbreak;case 'text':{//文本框this.textbox = new fabric.Textbox('', {left: mouseFrom.x,top: mouseFrom.y - 10,// width: 150,fontSize: 16,borderColor: this.color,fill: this.color,hasControls: false,});this.canvas.add(this.textbox);this.textbox.enterEditing();this.textbox.hiddenTextarea.focus();}break;default:break;}if (canvasObject) {// canvasObject.index = getCanvasObjectIndex();\this.canvas.add(canvasObject); //.setActiveObject(canvasObject)this.drawingObject = canvasObject;}},},
};
</script><style lang="scss" scope>
.doodleDialog {.el-container {flex-direction: column;}img,input {display: none;}.demo {display: flex;flex-direction: column;align-items: center;}canvas {border: 1px dashed black;}.draw-btn-group {// width: 1270px;margin-top: 10px;display: flex;align-items: center;justify-content: flex-start;& > div {background: #fafafa;cursor: pointer;&:hover {background: #eee;}i {display: flex;background-repeat: no-repeat;background-size: 80%;background-position: 50% 50%;height: 30px;width: 30px;}.icon-1 {background-image: url('../../../assets/images/draw/1.png');}.icon-pentagram {background-image: url('../../../assets/images/draw/pentagram.png');}.icon-2 {background-image: url('../../../assets/images/draw/2.png');}.icon-3 {background-image: url('../../../assets/images/draw/3.png');}.icon-4 {background-image: url('../../../assets/images/draw/4.png');background-size: 75%;}.icon-5 {background-image: url('../../../assets/images/draw/5.png');background-size: 70%;}.icon-6 {background-image: url('../../../assets/images/draw/6.png');}.icon-7 {background-image: url('../../../assets/images/draw/7.png');background-size: 80%;}.icon-del {background-image: url('../../../assets/images/draw/del.png');background-size: 90%;}.icon-img {background-image: url('../../../assets/images/draw/img.png');background-size: 80%;}.icon-back {background-image: url('../../../assets/images/draw/back.png');background-size: 75%;}.icon-save {background-image: url('../../../assets/images/draw/save.png');background-size: 80%;}.icon-mouse {background-image: url('../../../assets/images/draw/mouse.png');background-size: 60%;}}.active {background: #eee;}}
}
</style>
<style lang="scss"></style>

链接: https://www.jianshu.com/p/d6d924eb5cf7
链接: https://github.com/Couy69/vue-fabric-drawingboard

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/3217.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

FlashSpeech、ID-Animator、TalkingGaussian、FlowMap、CutDiffusion

本文首发于公众号&#xff1a;机器感知 FlashSpeech、ID-Animator、TalkingGaussian、FlowMap、CutDiffusion Gradient Guidance for Diffusion Models: An Optimization Perspective Diffusion models have demonstrated empirical successes in various applications and ca…

《MATLAB科研绘图与学术图表绘制从入门到精通》示例:绘制婴儿性别比例饼图

在MATLAB 中可以使用 pie 函数来创建饼图。饼图是一种展示不同部分占总体的相对比例的图表。 本示例从“婴儿出生数据.csv”文件读取婴儿出生数据&#xff0c;然后计算男性和女性婴儿的数量&#xff0c;使用MATLAB绘制饼图。 配套图书链接&#xff1a;https://item.jd.com…

AI图书推荐:AI驱动的图书写作工作流—从想法构思到变现

《AI驱动的图书写作工作流—从想法到变现》&#xff08;AI-Driven Book Creation: From Concept to Cash&#xff09;是Martynas Zaloga倾力打造的一本实用指南&#xff0c;它巧妙地将写作艺术与人工智能前沿技术相结合。此书不仅揭示了AI在图书出版领域的无限潜力&#xff0c;…

应用层协议 -- HTTPS 协议

目录 一、了解 HTTPS 协议 1、升级版的 HTTP 协议 2、理解“加密” 二、对称加密 1、理解对称加密 2、对称加密存在的问题 三、非对称加密 1、理解非对称加密 2、中间人攻击 3、CA 证书和数字签名 四、总结 一、了解 HTTPS 协议 1、升级版的 HTTP 协议 HTTPS 也是…

fatal: unable to access ‘https://github.com/alibaba/flutter_boost.git/

Git error. Command: git fetch stdout: stderr: fatal: unable to access ‘https://github.com/alibaba/flutter_boost.git/’: Failed to connect to github.com port 443 after 75005 ms: Couldn’t connect to server exit code: 128 GitHub (国际型)代码 分发平台/托管平…

Mycat(一)入门概述

文章目录 概述作用原理 Mycat1.x 与 Mycat2 功能对比1.x 与 2.0 功能对比图 Mycat2 相关概念概念描述 配置文件1、服务&#xff08;server&#xff09;2、用户&#xff08;user&#xff09;3、数据源&#xff08;datasource&#xff09;4、集群&#xff08;cluster&#xff09;…

车企的数智化“内功”,大模型帮修炼

文&#xff5c;白 鸽 编&#xff5c;王一粟 时隔4年回归的北京车展&#xff0c;遇上了中国智能汽车的热潮。 开年价格战的持续洗礼&#xff0c;不仅让一众中国车企都慌得一批&#xff0c;也让全球巨头特斯拉也面临一季度销量大跌局面。 与此同时&#xff0c;智能汽车还在…

C++初识内存管理和模版

目录 前言 1.C/C内存分布 2. C的内存管理方式 2.1 new/delete操作内置类型 2. new和delete操作自定义类型 3. operator new和operator delete函数 4. new和delete的实现原理 4.1 内置类型 4.2 自定义类型 5. malloc/free和new/delete的区别 6. 初识模版 6.1 泛型编…

ERROR: Permission denied (publickey,gssapi-keyex,gssapi-with-mic,password).

今天本来想在A服务器上传文件给B服务器的结果发现明明给root用户设置了密码就是远程登陆不了&#xff0c;后来才发现在容器中很多服务都是没有的&#xff0c;所以刚安装后忘记了修改配置文件&#xff0c;导致远程登陆失败。 报错&#xff1a; 解决方法&#xff1a; 在/etc/ssh…

申请高德地图,报错INVALID_USER_SCODE处理

配置上key后 报错&#xff1a; 解决&#xff1a;将应用类型修改为出行&#xff0c;问题解决 扩展&#xff1a;应用申请 进入应用管理&#xff0c;创建新应用&#xff08;这里我选了导航&#xff0c;就报了上边的错误&#xff09; 新应用中添加 key&#xff0c;服务平台选择…

static和extern关键字详解

目录 创作不易&#xff0c;如对您有帮助&#xff0c;还望一键三连&#xff0c;谢谢&#xff01;&#xff01;&#xff01; 回顾 1.作用域和声明周期 1.1作用域 1.2生命周期 2.static和extern 2.1extern 2.2static 2.2-1static修饰局部变量 2.2-2static修饰全局变量 创…

解决在服务器中减少删除大文件夹耗时太久的问题

在数据驱动的现代商业环境中&#xff0c;企业对服务器的高效运作有着极高的依赖性。然而&#xff0c;IT管理员们常常面临一个棘手的问题&#xff1a;删除服务器上的大型文件夹过程缓慢&#xff0c;这不仅降低了工作效率&#xff0c;还可能对用户体验造成负面影响。本文将介绍一…

2024 年 Rust 开发者路线图

Rust 近年来因其对性能、安全性和并发性的关注而广受欢迎。作为一名开发人员&#xff0c;掌握 Rust 可以为各种机会打开大门&#xff0c;包括 Web 开发。 在 github 上发现了这个优秀的路线图&#xff0c;由 Anshul Goyal 创建&#xff0c;它提供了一条全面的路径&#xff0c;概…

MIEC CS172(Prolog)

Chapter 1 and 2 Fact Facts: Facts are statements that areassumed to be true. The dot ‘.’ character must come at the end of a fact. Example: We want to tell “John likes Mary” : English interpretation The standard form of fact in Prolog Likes (john, ma…

怎么用AI绘画进行人物修复?

用过AI绘画生成人物图片的朋友们是不是都碰到过这样的问题&#xff1a;诡异的造型、崩坏的五官、离谱的手指头、乱七八糟的背景...指望AI一次性生成百分百完美的图貌似有点难啊。 现在AI绘画有了【脸部修复】【手部修复】功能&#xff0c;就能够轻松解决这些的问题了&#xff0…

Facebook的时间机器:回溯社交媒体的历史

1. 社交媒体的起源与早期模式 社交媒体的历史可以追溯到互联网的早期发展阶段。在Web 1.0时代&#xff0c;互联网主要是一个信息发布平台&#xff0c;用户主要是被动地接收信息。但随着Web 2.0的兴起&#xff0c;互联网逐渐转变为一个互动和参与的平台&#xff0c;社交媒体应运…

2024.4.23 关于 LoadRunner 性能测试工具详解 —— VUG

目录 引言 LoadRunner 三大组件之间的关系 LoadRunner 脚本录制 启动并访问 WebTours 脚本录制 编译 运行&#xff08;回放&#xff09; LoadRunner 脚本加强 事务插入 插入集合点 插入检查点 参数化 ​编辑 打印日志 引言 问题&#xff1a; 此处为啥选择使用 Lo…

JdbcTemplate详解

1 概述 为了使JDBC更加易于使用&#xff0c;Spring在JDBC API上定义了一个抽象层&#xff0c;以此建立一个JDBC存取框架。 作为Spring JDBC框架的核心&#xff0c;JDBC模板的设计目的是为不同类型的JDBC操作提供模板方法&#xff0c;通过这种方式&#xff0c;可以在尽可能保留…

Linux安装Docker的多版本PHP和多版本MySQL共存

1: 先安装docker 安装完后执行,权限设置 sudo usermod -aG docker $USER或者sudo usermod -aG docker kentrl#添加当前用户到Docker用户组中 sudo newgrp docker#更新用户组数据,必须执行否则无效 sudo systemctl restart docker 先看目录结构: 2:按照目录结构挂载磁盘,…

【Qt常用控件】—— QWidget 核心属性

目录 &#xff08;一&#xff09;控件概述 1.1 关于控件体系的发展 &#xff08;二&#xff09;QWidget 核心属性 2.1 核心属性概览 2.2 enabled 2.3 geometry 2.4 windowTitle 2.5 windowIcon 2.6 windowOpacity 2.7 cursor 2.8 font 2.9 toolTip 2.10 focus…