前端图片处理

这篇文章有几个功能,第一个是支持拖拽,第二个是压缩,第三个是裁剪编辑,第四个是上传和上传进度显示。

1、拖拽上传

拖拽读取图片的功能主要是监听HTML5的 drag 事件,这个没什么好说的,查查API就知道怎么做的,主要在于怎么读取用户拖过来的图片并他把转成base64以在本地显示出来,代码如下:

2、压缩图片

压缩图片可以借助canvas,canvas可以很方便的实现压缩,其原理是把一张图片画到一个小的画布,然后再把这个画布的内容导出base64,就能够拿到一张被压小的图片了,修改上面代码如下

3、裁剪图片

裁剪图片,使用了一个 cropper 插件,这个插件还是挺强大的,支持裁剪、旋转、翻转,但是他并没有对图片真正的处理,只是记录了用户做了哪些变换,然后你自己再去处理,官方文档在这里,只要仔细阅读就可以上手了,

下面附上完整代码

<html lang="en"><head>
 <meta charset="UTF-8">
 <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
 <meta http-equiv="X-UA-Compatible" content="ie=edge">
 <title>Document</title>
 <link href="cropper.css" rel="stylesheet">
 <script src="http://code.jquery.com/jquery-2.2.4.min.js"></script>
 <script src="cropper.js"></script>
 <style>
  .box{
   width: 200px;
   height: 200px;
   border: 1px #333 dashed;
  }
  .box img{
   width: 100%;
  }
  .mini{
   width: 360px;
   height: 360px;
  }
  .btn{
   margin-top: 20px;
  }
  .small{
   width: 100px;
   height: 100px;
   overflow:hidden;
   border: 1px solid #333;
   margin: 10px;
  }
 </style>
</head>
<body>
 <h3>拖拽过来的图片</h3>
 <div class="box"><img src=""></div>
 <h3>裁剪预览图</h3>
 <div class="small"></div>
 <h3>压缩过后的图片</h3>
 <div class="mini"><img src=""></div>
 <div class="btn"><button>裁剪</button></div>
 <h4>裁剪后的图</h4>
 <div class="output"><img src=""></div>
<script>
 let cropper = ''
 let handler = {
  init: function(dom){
   dom.on('dragover', function(event){
    console.log('拖拽中')
    event.preventDefault()
   })
   dom.on('drop', function(event){
    event.preventDefault()
    let file = event.originalEvent.dataTransfer.files[0]
    console.log('拖拽结束')
    handler.handleDrop($(this), file)
   })
  },
  handleDrop: function(dom, file) {
   let $img = dom.find('img')
   handler.readImgFile(file, $img)
  },
  readImgFile: function(file, $img){
   let reader = new FileReader(file)
   console.log('显示图片')
   if(!file || file.type.split("/")[0] !== 'image') {
    alert('请选择图片')
    return
   }
   reader.readAsDataURL(file)
   reader.onload = function(event) {
    let base64 = event.target.result;
    $img.attr('src', base64)             // 显示拖拽进来的图片
    handler.compress($img[0], 1500, file.type)
   }
  },
  compress: function(img, maxWidth, mimeType) {
   let cvs = document.createElement('canvas')
   img.onload = function(){
    let width = img.naturalWidth
    let height = img.naturalHeight
    imgRatio = width / height
    if(width > maxWidth){
     width = maxWidth
     height = width / imgRatio
    }
    cvs.width = width
    cvs.height = height
    let ctx = cvs.getContext('2d')
    ctx.drawImage(img, 0, 0, img.naturalWidth, img.naturalHeight, 0, 0, width, height)
    let quality = width >= 1500 ? 0.5 : width > 600 ? 0.6 : 1
    let newImageData = cvs.toDataURL(mimeType, quality)
    // let resultImg = new Image()
    // resultImg.src = newImageData
    $(".mini img").attr('src',newImageData)      // 显示压缩过的图片
    let $image = $(".mini img");
    $image.cropper({
     preview: '.small',
     viewMode: 1,
     aspectRatio: 300 /300,
     autoCropArea: 0.9,
     ready() {
      cropper = $image.data('cropper');
     },
     crop: function(event) {
      console.log(event.detail.x);
      console.log(event.detail.y);
      console.log(event.detail.width);
      console.log(event.detail.height);
      console.log(event.detail.rotate);
      console.log(event.detail.scaleX);
      console.log(event.detail.scaleY);
     }
    });
   }
  }
 }
 handler.init($('.box'))
 $('.btn button').on('click',function() {
  let result = cropper.getCroppedCanvas({
   width: 200,
   height: 200,
  })
  let imgurl = result.toDataURL("image/jpeg", 0.5);
  $(".output img").attr("src",imgurl)          // 显示裁剪后的图片
 })
</script>
</body>
</html>

以上代码并不完美,有很多瑕疵,只供参考。