超文本编辑器如何上传图片?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了超文本编辑器如何上传图片?相关的知识,希望对你有一定的参考价值。
药监局注册申报软件想插入曲线图,所以截的图片,但是插入不成功,
首先,实现文章发布或编辑的form表单,初始化layui富文本编辑器,效果如下:文章发布表单对应的html代码如下:thinkphp富文本编辑器如何实现上传图片
thinkphp富文本编辑器如何实现上传图片
其中是layedit的目标元素,建立编辑器以及表单提交的js代码如下:
实现layedit插入图片接口需要在建立编辑器之前配置uploadImage,本例中配置代码如上图JS代码所示。
thinkphp富文本编辑器如何实现上传图片
layedit不提供服务端的图片接受,需要我们在接口中实现,图片上传成功后返回指定格式的JSON信息,格式如下:
"code": 0, //0表示成功,其它失败
"msg": "", //提示信息 //一般上传失败后返回
"data":
"src": "图片路径",
"title": "图片名称" //可选
thinkphp富文本编辑器如何实现上传图片
本例中用thinkPHP5实现编辑器插入图片接口的代码如下:
我创建了一个资源上传的控制器,专门用来处理文件上传相关业务,其中有关thinkPHP5上传文件的代码请参考TP的官方文档,这里不做过多解释。
thinkphp富文本编辑器如何实现上传图片
然后,发布一篇科技互联网新闻,演示一下效果。
在第一段后面添加一张图片,提交后效果如下: 参考技术A Jota [1] 是一个为超长文本文件设计的文本编辑器。她的名字发音为 "i-o-ta"。
特性:
- 支援多达 100 万个字符(能否成功解码取决于android 系统的实现方式).
- 变更字符编码。
- 自动检测换行符。
- 变更换行符。
- 保留换行符直至保存档案。
- 保存档案的同时保存光标位置。
- 保存档案的历史记录。
- 使用外部应用程式分享。
分享 (ACTION_SEND)
搜寻 (ACTION_SEARCH)
打开 (ACTION_VIEW)
- Direct Intent : 您可以从MENU 菜单中启动任意一个应用程式。 参考技术B 超本文编辑器如何上传图片?首先还是按照他的编辑规则和制度可以 参考技术C 超文本编辑器如何上传图片?超文本编辑器你要想上传图片,你就下载个这样的软件,他就帮你上传图片了追问
这个超文本是固定软件,不能更换,官网系统里带的。
JS实现 带有话题的文本编辑 + 图片编辑(下)
本篇主要讲述九宫格上传图片
图片编辑实现效果:
图片编辑实现原理:
- 实现九宫格编辑图片可以做成一个组件,使用原生的图片上传方式通过 input 标签上传图片
- 一般图片都挺大,避免用户等待时间过长,使用 canvas 将上传的图片进行压缩
- 每次成功上传一张图片 && 图片总量 < 9 就在图片数组后push 一个待编辑图片
- 由于上传图片的接口需要formData 格式的文件,就需要将压缩后的base64格式的图片 通过dataURLtoBlob blobToFile 这两个函数转换成file文件,此方法不存在浏览器不兼容问题
子组件封装:
<template> <div class="addImg_wrap"> <div class="occupy_img" v-if="!info.imgUrl"> <img src="//nkb-yunpan.oss-cn-beijing.aliyuncs.com/d6de603efa86935328b439f276339c2b.png" alt @click.self.prevent="addImgEvent" class="img1" /> <input class="file" type="file" id="add_input2" accept="image/*" ref="avatarInput" @change="changeImage($event)" /> </div> <div class="real_img" v-if="info.imgUrl"> <img :src="info.imgUrl" alt class="img2" /> <img src="https://nkb-yunpan.oss-cn-beijing.aliyuncs.com/1595a0b56803644173f839f27655754b.png" alt class="close" @click.self.prevent="closeEvent(index)" /> </div> </div> </template> <script> export default { props: { info: { type: Object, default: null }, index: { type: Number, default: null }, isLoading: { type: Boolean, default: null }, }, data() { return {}; }, methods: { addImgEvent() { this.$refs.avatarInput.click(); }, changeImage(e) { const self = this; let imgFile = ""; let file = e.target.files[0]; let filename = file.name; if (file) { let reader = new FileReader(); reader.readAsDataURL(file); reader.onload = function() { // 这里的this 指向reader let pic = new Image(); pic.src = this.result; pic.onload = function() { var bitmap = new Image(); bitmap.src = self.compress(pic); self.dataUrl = bitmap.src }; }; // 不加定时器获取不到dataurl setTimeout(() => { console.log(\'dataUrl\'); console.log(self.dataUrl); let blob = self.dataURLtoBlob(self.dataUrl); imgFile = self.blobToFile(blob, filename); let data = new FormData(); data.append("file", imgFile, filename); self.getImgUrl(data); }, 500); } }, // 先将base64转换成blob,再将blob转换成file文件,此方法不存在浏览器不兼容问题 dataURLtoBlob(dataUrl) { var arr = dataUrl.split(","), mime = arr[0].match(/:(.*?);/)[1], bstr = atob(arr[1]), n = bstr.length, u8arr = new Uint8Array(n); while (n--) { u8arr[n] = bstr.charCodeAt(n); } return new Blob([u8arr], { type: mime }); }, blobToFile(theBlob, fileName) { theBlob.lastModifiedDate = new Date(); theBlob.name = fileName; return theBlob; }, //压缩图片 compress(img) { let canvas = document.createElement("canvas"); let ctx = canvas.getContext("2d"); let width = img.width; let height = img.height; canvas.width = width; canvas.height = height; ctx.drawImage(img, 0, 0, width, height); //进行压缩 var ndata = canvas.toDataURL("image/jpeg", 0.5); // console.log("已压缩"); return ndata; }, closeEvent(index) { this.$emit("imgDel", index); }, async getImgUrl(data) { this.$emit("loadingEvent", true); const res = await this.fetch.post("Upload/UploadImage",data, "post",); if (res && res.success) { // Toast("上传成功"); this.$emit("imgAdd", { imgUrl: res.result.path, index: this.index,isLoading:false }); } } } }; </script> <style lang="less" scoped> .addImg_wrap { width: 31%; margin-right: 3%; margin-bottom: 4%; &:nth-child(3n) { margin-right: 0; } .occupy_img, .real_img { width: 100%; height: 200px; position: relative; .img1 { width: 100%; height: 206px; box-sizing: border-box; // border: 2px dashed #888888; } .img2 { box-sizing: border-box; width: 100%; height: 206px; border: 0; } } .close { position: absolute; width: 32px; height: 32px; top: 0; right: 0; z-index: 9; } .file { opacity: 0; width: 1px; height: 1px; } } </style>
父组件调用:
<template> <div class="nineImgs_wrap"> <div class="edit_img"> <addImgComponent v-for="(item,index) in imgList" :key="index" :info.sync="item" @imgDel="imgDel" @imgAdd="imgAdd" @loadingEvent="loadingEvent" :index="index" :isLoading="isLoading" ></addImgComponent> </div> <div class="loading" v-if="isLoading"> <van-loading type="spinner" size="30px" vertical></van-loading> </div> </div> </template> <script> import addImgComponent from "@/components/addImg.vue"; export default { name: "nineImgs", components: { addImgComponent }, data() { return { imgList: [ { imgUrl: "" } ], isLoading: false }; }, methods: { loadingEvent(val){ this.isLoading = val }, imgAdd(val) { this.isLoading = val.isLoading this.imgList.forEach((v, i) => { if (i === val.index) { v.imgUrl = val.imgUrl; } }); const a = { imgUrl: null }; this.imgList.push(a); }, imgDel(d) { this.imgList.forEach((v, i) => { if (i === d) { this.imgList.splice(i, 1); } }); } } }; </script> <style lang="less" scoped> .nineImgs_wrap { width: 100%; padding: 30px; font-size: 18px; .edit_img { display: flex; flex-wrap: wrap; margin-top: 20px; .real_img, .occupy_img .img1 { height: 200px !important; } } .loading{ width: 100%; } } </style>
分享一刻:
Safari 浏览器开始完全禁用第三方 Cookie,本文分析了有何影响,以及如何在没有 Cookie 的情况下,获取浏览器的指纹。
以上是关于超文本编辑器如何上传图片?的主要内容,如果未能解决你的问题,请参考以下文章
求一个jQuery文本编辑器???要能上传图片 视频 音频的。最好有中文文档。 当然要免费的。