【图片展示优化】OutPutSize极大压缩图片体积

在这里插入图片描述
下面详细说明:

  1. 在 VueCropper 组件中新增了 outputSize 属性,并设置为 0.8,意思是输出图片的质量为 80%。默认情况下,outputSize 的值为 1(即100%的质量),通过降低这个值,可以在输出图片时对图片质量进行压缩,从而有效地减小生成图片的文件大小,而不会改变图片的像素尺寸或后端逻辑。

  2. 依然采用 webp 格式输出图片。webp 格式本身就比 JPEG 或 PNG 在相同画质下拥有更小的文件体积。配合降低的 outputSize,就能使硬盘占用进一步减少。

效果

    1. 图片一:

在这里插入图片描述
在这里插入图片描述
2. 图片二
在这里插入图片描述
在这里插入图片描述
总体图片大小缩小了20倍以上。

代码

<template>
  <Dialog :show="dialogConfig.show" :title="dialogConfig.title" :buttons="dialogConfig.buttons" width="1000px"
    @close="dialogConfig.show = false">
    <div class="cut-image-panel">
      <VueCropper ref="cropperRef" class="cropper" :img="sourceImage" outputType="webp" :outputSize="0.8"
        :autoCrop="true" :autoCropWidth="props.cutWidth" :autoCropHeight="Math.round(props.cutWidth * props.scale)" :fixed="true"
        :fixedNumber="[1, props.scale]" :centerBox="true" :full="false" :fixedBox="true" @realTime="prview" mode="100%">
      </VueCropper>
      <div class="preview-panel">
        <div class="preview-image">
          <img :src="previewsImage" />
        </div>
        <el-upload :multiple="false" :show-file-list="false" :http-request="selectFile" :accept="proxy.imageAccept">
          <el-button class="select-btn" type="primary" @click="">选择图片</el-button>
        </el-upload>
      </div>
    </div>
    <div class="info">
      建议上传至少{{ props.cutWidth }}*{{ Math.round(props.cutWidth * props.scale) }}的图片
    </div>
  </Dialog>
</template>

<script setup>
import 'vue-cropper/dist/index.css'
import { VueCropper } from 'vue-cropper'

import { ref, reactive, getCurrentInstance, nextTick, inject } from 'vue'
const { proxy } = getCurrentInstance()
import { useRoute, useRouter } from 'vue-router'
const route = useRoute()
const router = useRouter()

/**
 * 参数说明
  img: '', // 裁剪图片的地址 url 地址, base64, blob
  outputSize: 1, // 裁剪生成图片的质量
  outputType: 'jpeg', // 裁剪生成图片的格式 jpeg, png, webp
  info: true, // 裁剪框的大小信息
  canScale: false, // 图片是否允许滚轮缩放
  autoCrop: true, // 是否默认生成截图框
  autoCropWidth: 150, // 默认生成截图框宽度
  autoCropHeight: 150, // 默认生成截图框高度
  fixedBox: false, // 固定截图框大小 不允许改变
  fixed: false, // 是否开启截图框宽高固定比例,这个如果设置为true,截图框会是固定比例缩放的,如果设置为false,则截图框的宽高比例就不固定了
  fixedNumber: [1, 1], // 截图框的宽高比例 [ 宽度 , 高度 ]
  canMove: true, // 上传图片是否可以移动
  canMoveBox: true, // 截图框能否拖动
  original: false, // 上传图片按照原始比例渲染
  centerBox: true, // 截图框是否被限制在图片里面
  infoTrue: true, // true 为展示真实输出图片宽高 false 展示看到的截图框宽高
  full: true, // 是否输出原图比例的截图
  enlarge: '1', // 图片根据截图框输出比例倍数
  mode: 'contain' // 图片默认渲染方式 contain , cover, 100px, 100% auto
 */
const props = defineProps({
  cutWidth: {
    type: Number,
    default: 400,
  },
  // 高宽比例
  scale: {
    type: Number,
    default: 0.5,
  },
})

const dialogConfig = ref({
  show: false,
  title: '上传图片',
  buttons: [
    {
      type: 'primary',
      text: '确定',
      click: (e) => {
        cutImage()
      },
    },
  ],
})

const cropperRef = ref()
const previewsImage = ref()
const prview = (data) => {
  cropperRef.value.getCropData((data) => {
    previewsImage.value = data
  })
}

const sourceImage = ref()
const selectFile = (file) => {
  console.log(props.cutWidth, props.scale)
  file = file.file
  let img = new FileReader()
  img.readAsDataURL(file)
  img.onload = ({ target }) => {
    sourceImage.value = target.result
  }
}

const show = () => {
  dialogConfig.value.show = true
  sourceImage.value = ''
  nextTick(() => {
    previewsImage.value = ''
  })
}

defineExpose({
  show,
})

const cutImageCallback = inject('cutImageCallback')
// 裁剪
const cutImage = () => {
  // 截图的高宽
  const cropW = Math.round(cropperRef.value.cropW)
  const cropH = Math.round(cropperRef.value.cropH)
  if (cropW == 0 || cropH == 0) {
    proxy.Message.warning(`请选择图片`)
    return
  }
  if (
    cropW < props.cutWidth ||
    cropH < Math.round(props.cutWidth * props.scale)
  ) {
    proxy.Message.warning(
      `图片尺寸至少满足(${props.cutWidth}*${Math.round(
        props.cutWidth * props.scale
      )})`
    )
    return
  }
  cropperRef.value.getCropBlob((blob) => {
    const file = new File(
      [blob],
      'temp.' + blob.type.substring(blob.type.indexOf('/') + 1),
      { type: blob.type }
    )
    dialogConfig.value.show = false

    cutImageCallback({
      coverImage: file,
    })
  })
}
</script>

<style lang="scss" scoped>
.cut-image-panel {
  display: flex;
  .cropper {
    flex: 1;
    height: 500px;
  }
  .preview-panel {
    width: 200px;
    margin-left: 20px;
    text-align: center;
    .preview-image {
      width: 100%;
      height: 200px;
      background: #f6f6f6;
      display: flex;
      align-items: center;
    }
    img {
      width: 100%;
    }
  }
  .select-btn {
    margin-top: 20px;
  }
}
.info {
  color: #6b6b6b;
}
</style>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值