vue+elementUI(el-upload)图片压缩,默认同比例压缩

20 篇文章 3 订阅
5 篇文章 1 订阅

这个需求针对用户上传手机拍摄照片等不便修改图片大小的情况,我们允许上传10M以内的图片由前端对图片进行压缩再传给后台存储,结合elementUI的el-upload组件实现图片上传功能(简单来说就是用户是老大)

1、提取出压缩方法,放在公共方法.js文件里

/** 图片压缩,默认同比例压缩
 *  @param {Object} fileObj
 *  图片对象
 *  回调函数有一个参数,base64的字符串数据
 */
export function compress(fileObj, callback) {
  try {
    const image = new Image()
    image.src = URL.createObjectURL(fileObj)
    image.onload = function() {
      const that = this
      // 默认按比例压缩
      let w = that.width
      let h = that.height
      const scale = w / h
      w = fileObj.width || w
      h = fileObj.height || (w / scale)
      let quality = 0.7 // 默认图片质量为0.7
      // 生成canvas
      const canvas = document.createElement('canvas')
      const ctx = canvas.getContext('2d')
      // 创建属性节点
      const anw = document.createAttribute('width')
      anw.nodeValue = w
      const anh = document.createAttribute('height')
      anh.nodeValue = h
      canvas.setAttributeNode(anw)
      canvas.setAttributeNode(anh)
      ctx.drawImage(that, 0, 0, w, h)
      // 图像质量
      if (fileObj.quality && fileObj.quality <= 1 && fileObj.quality > 0) {
        quality = fileObj.quality
      }
      // quality值越小,所绘制出的图像越模糊
      const data = canvas.toDataURL('image/jpeg', quality)
      // 压缩完成执行回调
      const newFile = convertBase64UrlToBlob(data)
      callback(newFile)
    }
  } catch (e) {
    console.log('压缩失败!')
  }
}
function convertBase64UrlToBlob(urlData) {
  const bytes = window.atob(urlData.split(',')[1]) // 去掉url的头,并转换为byte
  // 处理异常,将ascii码小于0的转换为大于0
  const ab = new ArrayBuffer(bytes.length)
  const ia = new Uint8Array(ab)
  for (let i = 0; i < bytes.length; i++) {
    ia[i] = bytes.charCodeAt(i)
  }
  return new Blob([ab], { type: 'image/png' })
}

2、el-upload上传组件

<el-form-item ref="uploadElement" prop="picUrl" class="upload-img-form" label-width="0">
  <el-upload
    ref="uploadxls"
    class="avatar-uploader upload-img"
    :disabled="disabled"
    :auto-upload="false"
    :style="{height:'66px', backgroundImage:'url(' + dialogImageUrl + ')', backgroundRepeat:'no-repeat', backgroundPosition:'center', backgroundSize: '100%,100%'}"
    action="aaa"
    ::limit="1"
    :show-file-list="false"
    :on-change="handlePictureCardPreview"
    :before-upload="beforeupload"
    accept="image/png,image/gif,image/jpg,image/jpeg"
  >
    <!--<img v-if="dialogImageUrl" :src="dialogImageUrl" class="avatar">-->
    <i v-if="!dialogImageUrl" class="el-icon-plus avatar-uploader-icon" />
    <!--<i v-show="!dialogImageUrl" class="upload-icon" />
    <div v-show="!dialogImageUrl" slot="tip" class="el-upload__text upload__tip">上传实景图</div>-->
    <div v-if="showDelete" class="remove-img"><i class="el-icon-delete" @click.stop="removeImg" /></div>
    <div slot="tip" class="el-upload__tip">
      <p><span style="color:#F5222D;">*</span>上传楼宇实景图</p>
      <p>支持:.jpg .png .gif格式 建议比例:16:9,小于10M</p>
    </div>
  </el-upload>
</el-form-item>

3、主要在handlePictureCardPreview方法里调用压缩方法

先在当前vue页面import公共js文件

import { compress } from '@/utils'

然后

// 图片预览
handlePictureCardPreview(file) {
  const _that = this
  const isLt10M = file.size / 1024 / 1024 < 10
  if (!isLt10M) {
    this.$message.error('上传图片大小不能超过 10M!')
    return false
  } else {
    this.dialogImageUrl = URL.createObjectURL(file.raw)
    compress(file.raw, function(val) {
      _that.theForm.picUrl = val
      _that.imgFile = val
      _that.showDelete = true
      _that.$refs['addBuildingForm'].validateField('picUrl')
    })
  }
}

compress传入file.raw作为fileObj

这样只要上传图片就进行图片压缩

  • 4
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 29
    评论
在ASP.NET上传图片并生成缩略的C#源码 <FONT size=4><FONT size=4><FONT size=4>using System; using System.Collections; using System.ComponentModel; using System.Data; using System.Drawing; using System.Web; using System.Web.SessionState; using System.Web.UI; using System.Web.UI.WebControls; using System.Web.UI.HtmlControls; using System.IO; using System.Drawing.Imaging; namespace eMeng.Exam { /// <summary> /// Thumbnail 的摘要说明。 /// </summary> public class Thumbnail : System.Web.UI.Page { protected System.Web.UI.WebControls.Label Label1; protected System.Web.UI.WebControls.Button Button1; private void Page_Load(object sender, System.EventArgs e) { // 在此处放置用户代码以初始化页面 Label1.Text = "<h3>在ASP.NET里轻松实炙趼酝?lt;/h3>"; Button1.Text = "上载并显示缩略"; } #region Web 窗体设计器生成的代码 override protected void OnInit(EventArgs e) { // // CODEGEN: 该调用是 ASP.NET Web 窗体设计器所必需的。 // InitializeComponent(); base.OnInit(e); } /// <summary> /// 设计器支持所需的方法 - 不要使用代码编辑器修改 /// 此方法的内容。 /// </summary> private void InitializeComponent() { this.Button1.Click += new System.EventHandler(this.Button1_Click); this.Load += new System.EventHandler(this.Page_Load); } #endregion private void Button1_Click(object sender, System.EventArgs e) { HttpFileCollection MyFileColl = HttpContext.Current.Request.Files; HttpPostedFile MyPostedFile = MyFileColl[0]; if (MyPostedFile.ContentType.ToString().ToLower().IndexOf("image") < 0) { Response.Write("无效的形格式。"); return; } GetThumbNail(MyPostedFile.FileName, 100, 100, MyPostedFile.ContentType.ToString(), false, MyPostedFile.InputStream); } private System.Drawing.Imaging.ImageFormat GetImageType(object strContentType) { if ((strContentType.ToString().ToLower()) == "image/pjpeg") { return System.Drawing.Imaging.ImageFormat.Jpeg; } else if ((strContentType.ToString().ToLower()) == "image/gif") { return System.Drawing.Imaging.ImageFormat.Gif; } else if ((strContentType.ToString().ToLower()) == "image/bmp") { return System.Drawing.Imaging.ImageFormat.Bmp; } else if ((strContentType.ToString().ToLower()) == "image/tiff") { return System.Drawing.Imaging.ImageFormat.Tiff; } else if ((strContentType.ToString().ToLower()) == "image/x-icon") { return System.Drawing.Imaging.ImageFormat.Icon; } else if ((strContentType.ToString().ToLower()) == "image/x-png") { return System.Drawing.Imaging.ImageFormat.Png; } else if ((strContentType.ToString().ToLower()) == "image/x-emf") { return System.Drawing.Imaging.ImageFormat.Emf; } else if ((strContentType.ToString().ToLower()) == "image/x-exif") { return System.Drawing.Imaging.ImageFormat.Exif; } else if ((strContentType.ToString().ToLower()) == "image/x-wmf") { return System.Drawing.Imaging.ImageFormat.Wmf; } else { return System.Drawing.Imaging.ImageFormat.MemoryBmp; } } private void GetThumbNail(string strFileName, int iWidth, int iheight, string strContentType, bool blnGetFromFile, System.IO.Stream ImgStream) { System.Drawing.Image oImg; if (blnGetFromFile) { oImg = System.Drawing.Image.FromFile(strFileName); } else { oImg = System.Drawing.Image.FromStream(ImgStream); } oImg = oImg.GetThumbnailImage(iWidth, iheight, null, IntPtr.Zero); string strGuid = System.Guid.NewGuid().ToString().ToUpper(); string strFileExt = strFileName.Substring(strFileName.LastIndexOf(".")); Response.ContentType = strContentType; MemoryStream MemStream = new MemoryStream(); oImg.Save(MemStream, GetImageType(strContentType)); MemStream.WriteTo(Response.OutputStream); } } } </FONT></FONT></FONT><FONT color=#ff0000 size=4></FONT><FONT size=4>功能: 1。把片文件(JPG GIF PNG)上传, 2。保存到指定的路径(在web.config设置路径,以文件的原有格式保存), 3。并自动生成指定宽度的(在web.config设置宽度) 4。和指定格式的(在web.config指定缩略的格式) 5。和原比例相同的缩略(根据宽度和原的宽和高计算所略的高度) 6。可以判断是否已经存在文件 7。如果不覆盖,则给出错误 8。如果选"覆盖原"checkbox,则覆盖原。 9。可以根据要求,在webform上设置1个以上的file input和相应的checkbox 10。并在文件上传完毕后,显示原的文件名,尺寸,字节,和 11。缩略的文件名尺寸。 12。缩略的文件名格式:原+"_thumb."+指定格式,如:test.jpg_thumb.gif,以便于管理。 -------------------- public void UploadFile(object sender, System.EventArgs e) { string imgNameOnly, imgNameNoExt, imgExt; string imgThumbnail; int erroNumber = 0; System.Drawing.Image oriImg, newImg; string strFePicSavePath = ConfigurationSettings.AppSettings["FePicSavePath"].ToString(); string strFePicThumbFormat = ConfigurationSettings.AppSettings["FePicThumbFormat"].ToString().ToLower(); int intFeThumbWidth = Int32.Parse(ConfigurationSettings.AppSettings["FePicThumbWidth"]); string fileExt; StringBuilder picInfo = new StringBuilder(); if(Page.IsValid) { for(int i = 0;i < Request.Files.Count; i++) { HttpPostedFile PostedFile = Request.Files[i]; fileExt = (System.IO.Path.GetExtension(PostedFile.FileName)).ToString().ToLower(); imgNameOnly = System.IO.Path.GetFileName(PostedFile.FileName); if(fileExt == ".jpg" || fileExt == ".gif" || fileExt == ".png") { if(System.IO.File.Exists(strFePicSavePath + imgNameOnly) && (checkboxlistRewrite.Items[i].Selected == false)) { erroNumber = erroNumber + 1; picInfo.Append("<b>错误:</b>文件("+ (i+1) +") " + imgNameOnly + " 已经存在,请修改文件名<br/>" ); } } else { erroNumber = erroNumber + 1; picInfo.Append("<b>错误:</b>文件("+ (i+1) +") " + imgNameOnly + " 扩展名 " + fileExt + " 不被许可<br/>" ); } } if(erroNumber > 0) { picInfo.Append("<font color=red>全部操作均未完成,请修改错误,再进行操作</font><br/>"); } else { for(int i = 0;i < Request.Files.Count; i++) { HttpPostedFile PostedFile = Request.Files[i]; imgNameOnly = System.IO.Path.GetFileName(PostedFile.FileName); imgNameNoExt = System.IO.Path.GetFileNameWithoutExtension(PostedFile.FileName); imgExt = System.IO.Path.GetExtension(PostedFile.FileName).ToString().ToLower(); oriImg = System.Drawing.Image.FromStream(PostedFile.InputStream); newImg = oriImg.GetThumbnailImage(intFeThumbWidth, intFeThumbWidth * oriImg.Height/oriImg.Width,null,new System.IntPtr(0)); switch(imgExt) { //case ".jpeg": case ".jpg": oriImg.Save(strFePicSavePath + imgNameOnly , System.Drawing.Imaging.ImageFormat.Jpeg); break; case ".gif": oriImg.Save(strFePicSavePath + imgNameOnly , System.Drawing.Imaging.ImageFormat.Gif); break; case ".png": oriImg.Save(strFePicSavePath + imgNameOnly , System.Drawing.Imaging.ImageFormat.Png); break; } //oriImg.Save(ConfigurationSettings.AppSettings["FePicSavePath"] + imgNameNoExt + ".jpg", System.Drawing.Imaging.ImageFormat.Jpeg); switch(strFePicThumbFormat) { //jpeg format can get the smallest file size, and the png is the largest size //case "jpeg": case "jpg": newImg.Save(strFePicSavePath + imgNameOnly + "_thumb.jpg",System.Drawing.Imaging.ImageFormat.Jpeg); imgThumbnail = imgNameOnly + "_thumb.jpg"; break; case "gif": newImg.Save(strFePicSavePath + imgNameOnly + "_thumb.gif",System.Drawing.Imaging.ImageFormat.Gif); imgThumbnail = imgNameOnly + "_thumb.gif"; break; case "png": newImg.Save(strFePicSavePath + imgNameOnly + "_thumb.png",System.Drawing.Imaging.ImageFormat.Png); imgThumbnail = imgNameOnly + "_thumb.png"; break; default: newImg.Save(strFePicSavePath + imgNameOnly + "_thumb.jpg",System.Drawing.Imaging.ImageFormat.Jpeg); imgThumbnail = imgNameOnly + "_thumb.jpg"; break; }//switch picInfo.Append("<b>文件 名:</b>" + imgNameOnly + " ( " + oriImg.Width + " x " + oriImg.Height + " ) " + PostedFile.ContentLength/1024 + "KB<br/>"); picInfo.Append("<b>缩略名:</b>" + imgThumbnail + " ( " + newImg.Width + " x " + newImg.Height + " )<br/><br/>"); oriImg.Dispose(); newImg.Dispose(); }//for picInfo.Append("<font color=red>所有操作成功</font><br/>"); }// if erronumber = 0 } else { picInfo.Append("<font color=red>有错误,请检查。操作未成功</font><br/>"); } lblPicInfo.Text = picInfo.ToString(); } </FONT> 资料引用:http://www.knowsky.com/5723.html
el-upload可以通过before-upload属性对用户上传的片进行压缩处理。具体实现方法如下: 1.在Vue组件定义beforeUpload方法,该方法接收一个file参数,表示用户选择的片文件。 2.在beforeUpload方法,可以使用HTML5的FileReader对象读取片文件,并使用canvas对片进行压缩处理。 3.压缩完成后,将压缩后的片文件作为参数传递给compressAccurately回调函数,该函数会在el-upload上传之前被调用。 下面是一个示例代码: ```html <template> <el-upload action="#" :show-file-list="false" :before-upload="beforeUpload" accept=".jpg,.jpeg,.png" > <el-button size="small">选择片</el-button> </el-upload> </template> <script> export default { methods: { beforeUpload(file) { return new Promise((resolve, reject) => { const reader = new FileReader() reader.readAsDataURL(file) reader.onload = (event) => { const img = new Image() img.src = event.target.result img.onload = () => { const canvas = document.createElement('canvas') const ctx = canvas.getContext('2d') canvas.width = img.width canvas.height = img.height ctx.drawImage(img, 0, 0, img.width, img.height) canvas.toBlob((blob) => { resolve({ file: blob }) }, 'image/jpeg', 0.7) } } }) } } } </script> ``` 在上面的代码,我们使用了Promise对象来异步处理图片压缩。在beforeUpload方法,我们首先使用FileReader对象读取用户选择的片文件,并将其转换为base64编码的字符串。然后,我们创建一个Image对象,并将其src属性设置为base64编码的字符串。当Image对象加载完成后,我们创建一个canvas对象,并使用canvas的drawImage方法将片绘制到canvas上。最后,我们使用canvas的toBlob方法将canvas对象转换为Blob对象,并将其作为参数传递给resolve方法。在resolve方法,我们将Blob对象封装为一个对象,并将其作为Promise对象的返回值。 需要注意的是,在canvas的toBlob方法,第三个参数表示压缩质量,取值范围为0到1,1表示最高质量,0表示最低质量。在上面的代码,我们将压缩质量设置为0.7。
评论 29
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

辣姐什么鬼

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值