超文本编辑器如何上传图片?

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实现 带有话题的文本编辑 + 图片编辑(下)

 

本篇主要讲述九宫格上传图片

图片编辑实现效果:

 

 

 图片编辑实现原理:

  1. 实现九宫格编辑图片可以做成一个组件,使用原生的图片上传方式通过 input 标签上传图片
  2. 一般图片都挺大,避免用户等待时间过长,使用 canvas 将上传的图片进行压缩
  3. 每次成功上传一张图片 && 图片总量 < 9 就在图片数组后push 一个待编辑图片
  4. 由于上传图片的接口需要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>
View Code

 

父组件调用:

<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>
View Code

 

 

分享一刻:

浏览器禁用三方 Cookie 的分析

Safari 浏览器开始完全禁用第三方 Cookie,本文分析了有何影响,以及如何在没有 Cookie 的情况下,获取浏览器的指纹。

以上是关于超文本编辑器如何上传图片?的主要内容,如果未能解决你的问题,请参考以下文章

求一个jQuery文本编辑器???要能上传图片 视频 音频的。最好有中文文档。 当然要免费的。

wangEditor上传图片

KindEditor - 富文本编辑器 - 使用+上传图片

百度副文本编辑器自动缩放上传的图片

vue项目富文本编辑器vue-quill-editor之自定义图片上传

ueditor富文本编辑器跨域上传图片解决办法