How to edit a picture when uploading a picture by the background management system?

how do I edit a picture when uploading a picture by the background management system? That is, when the user is uploading a picture, he can edit the picture and choose any area to mark the picture (text) and upload it to the backend

.

such as pictures

clipboard.png

Apr.14,2022

html2canvas

this library can do this. With FileReader API, you can read uploaded images

.

< template >

<div :id="container?container:'SelectContainer'" v-if="!type || type == 'default'">
  <el-button icon="el-icon-upload" :size="button_size?button_size:'small'" :type="theme?theme:'info'" :plain="plain" :id="buttonID?buttonID:'pl_upload_button'">{{button_text?button_text:''}}</el-button>
</div>
<!--  -->
<div :id="container?container:'SelectContainer'" v-if="type == 'drag'">
  <div :id="buttonID?buttonID:'pl_upload_button'" class="el-upload el-upload--text">
    <div class="el-upload-dragger">
      <i class="el-icon-upload"></i>
      <div class="el-upload__text">
        <em></em>
      </div>
    </div>
  </div>
</div>
<!--  -->
<div class="avatar-uploader" :id="container?container:'SelectContainer'" v-if="type == 'photo'">
  <div :id="buttonID?buttonID:'pl_upload_button'" class="el-upload el-upload--text">
    <i class="fa fa-image avatar-uploader-icon"></i>
  </div>
</div>

< / div >
< / template >
< script >
export default {
/ / parameters allowed to be received when the component is called externally
/ * *

  • @ author [leo]

*

  • [props component allows passing parameters]

*

  • @ type [string] upload button style, optional. Default is normal button. Transferable parameters are [default default button mode], [drag drag mode], [phone avatar mode]
  • .
  • @ buttonID [sting] generates a unique id for upload buttons. If there are multiple upload buttons on a page, note that their id cannot be repeated. If there is only one button, parameters can not be passed. Default is "pl_upload_button"
  • .
  • @ max_file_size [sting] allows you to upload the maximum value of a single file. Pay attention to the unit, such as "1mb, 500kb", etc., which defaults to partner 100mb. If you do not use "filters" for filtering settings, you can use this parameter directly. In general, use "filters" to set
  • .
  • @ container [string] upload file area. There are multiple uploads on one page. Please set it to different values. If there is only one upload, there is no need to pass parameters
  • .
  • @ chunk_size [string] shard size. Note that the unit is written down. Default is "1mb", but no parameter
  • is passed.
  • @ button_text [string] the text displayed on the upload button. The parameter
  • is not available by default.
  • @ button_size [string] upload button. The size of the button in element-ui is optional. Default is small, but no parameters are passed
  • @ filters [object] sets the filtering information of the current upload button, such as upload file type, format, size, etc. Refer to the following example
  • The style of
  • @ theme [string] button is the same as the button option in element-ui. It is: primary/info/success/warning/danger, etc., and defaults to info
  • Whether
  • @ plain [boller] turns on the wireframe button is the same as the parameter in the button component in element-ui. If you need to turn it on, simply write the attribute plain on the button.

* /

props: [

"type",
"buttonID",
"max_file_size",
"container",
"drop_element",
"chunk_size",
"button_text",
"button_size",
"filters",
"theme",
"plain"

],
data: function () {

return {
  filter: {}
};

},
methods: {},
mounted () {

//this 
var _self = this;

var uploader = new plupload.Uploader({
  runtimes: "html5,flash,silverlight,html4",
  browse_button: this.buttonID ? this.buttonID : "pl_upload_button", // 
  container: this.container ? this.container : "SelectContainer", // DOM IDbrowser_button
  url: this.API_ROOT + "/admin-api/upload",
  flash_swf_url: "../assets/js/Moxie.swf",
  silverlight_xap_url: "../assets/js/Moxie.xap",
  max_file_size: this.max_file_size, // 
  dragdrop: true, // 
  drop_element: this.drop_element ? this.drop_element : "SelectContainer", // ID
  chunk_size: this.chunk_size ? this.chunk_size : "1mb", // 
  auto_start: true, // 
  filters: this.filters ? this.filters : this.filter,
  headers: this.$store.getters.Request_Head,
  /*
        
        filters: {
            max_file_size: '10mb',
            mime_types: [
                { title: "Image files", extensions: "jpg,gif,png" },
                { title: "Zip files", extensions: "zip" }
            ]
        },*/

  init: {
    //
    FilesAdded: function(up, files) {
      plupload.each(files, function(file) {
        // 
        _self.$emit("Callback-FilesAdded", file);
      });
    },
    //
    BeforeUpload: function(up, file) {
      // 
      // 
      _self.$emit("Callback-BeforeUpload", file);
    },
    //
    UploadProgress: function(up, file) {
      var id = up._options.browse_button[0].id;
      // 
      _self.$emit("Callback-UploadProgress", file, id);
    },
    //
    FileUploaded: function(up, file, info) {
      var id = up._options.browse_button[0].id;
      //
      var up_info = eval("(" + info.response + ")");
      _self.$emit("Callback-GetFileInfo", up_info, id);
    },
    //
    Error: function(up, err) {
      var str = "";
      switch (err.code) {
        case -600:
          str = " > " + up.settings.filters.max_file_size;
          break;
        case -601:
          var s = up.settings.filters.mime_types.regexp
            .toString()
            .replace(/[\\]/g, "")
            .replace("/", "")
            .replace("$/i", "");
          str = ":" + s;
          break;
        default:
          str = "";
      }
      _self.$message.error({
        message: ":" + str,
        duration: 5000
      });
    }
  }
});
uploader.init();

}
};
< / script >

this is an encapsulated plupload component. You can call the component directly

clipboard.pngjs

clipboard.png index.html reference

< Upload VMI if = "! form.file.url" button_size= "small" plain button_text= "Import form": filters= "filters"

                    @Callback-UploadProgress="CB_UploadProgress" @Callback-GetFileInfo="CB_GetFileInfo"></Upload>
                <el-row v-else-if="form.file.url">
                    <el-col>
                        <ul class="el-upload-list el-upload-list--text">
                            <li class="el-upload-list__item is-success">
                                <a class="el-upload-list__item-name blue" :href="form.file.url" target="_blank">
                                    <i class="el-icon-document"></i>
                                    {{form.file.name}}
                                </a>
                                <i class="el-icon-close" @click="file_close"></i>
                                <label class="el-upload-list__item-status-label">
                                    <i class="el-icon-upload-success el-icon-circle-check"></i>
                                </label>
                            </li>
                        </ul>
                    </el-col>
                </el-row>
                

references to child components

/ / upload progress

    CB_UploadProgress(file) {
        this.percent = file.percent;
    },
    //
    CB_GetFileInfo(res) {
        if (res && res.url) {
            this.form.file = res;
            this.percent = 0;
            this.status = "success";
            this.$forceUpdate();
            this.$message({ message: "", type: "success" });
        } else {
            this.form.file.name = "";
            this.form.file.url = "";
            this.form.file.path = "";
            this.percent = 0;
            this.status = "exception";
            this.$message({ message: "", type: "error" });
        }
    },
    
    

to explain, I am using

in conjunction with element.
Menu