前端选择本地图片并压缩

项目中需要本地选择文件并压缩,这里在Vue项目下面做了一个简单实现,记录一下

Step1:布局文件

<template>
    <div class="box">
        <input type="file" id="file" @change="selectFile" accept="image/png,image/jpg,image/jpeg,image/gif" multiple/>
        <div class="img-grid">
            <div class="img-item" v-for="item in imgList">
                <img :src="item.base64">
                <span>{{item.name}}</span>
            </div>
        </div>
    </div>
</template>
html
  • input 接受类型为image/png,image/jpg,image/jpeg,image/gif

  • multiple设置数量不限,监听回调函数为selectFile

  • 回显布局为img-grid,遍历回显数组imgList数据显示即可

  • imgList数组基本字段为base64name,分别存放图片数据和名称

Step2:selectFile实现

  • 首先设置压缩尺寸
//压缩后的最大尺寸
var MAX_SIZE = 1024
js
  • 获取选择的文件数据
 //获取文件列表
 var fileInputList = document.getElementById("file").files
js
  • 初始化imgList
 var that = this
 //初始化数据
 that.imgList = []
js
  • 编写写入数据函数
    采用递归形式,保证顺序处理
 //递归顺序写入数据
 function setImgData(input) {
     var index = that.imgList.length
     if (input.length > index) {
         console.log(fileInputList[index].name, "压缩前:", (fileInputList[index].size / 1024).toFixed(0) + "KB")
         var name = fileInputList[index].name
         compress(fileInputList[index]).then(res => {
             blobToDataUrl(res, base64 => {
                 console.log(name, "压缩后:", (res.size / 1024).toFixed(0) + "KB")
                 that.imgList.push({
                     name,
                     base64
                 })
                 if (input.length > index) {
                     //递归
                     setImgData(input)
                 }
             })
         })
     }
 }
js

其中compress:

//压缩
function compress(target) {
    return new Promise(resolve => {
        if (target.size / 1024 < MAX_SIZE) {
            resolve(target);
        }
        // 压缩到MAX_SIZE KB,这里的MAX_SIZE就是要压缩的大小,可自定义
        imageConversion
            .compressAccurately(target, MAX_SIZE)
            .then(res => {
                resolve(res);
            });
    });
}
js

且blobToDataUrl:

//blob转为base64
function blobToDataUrl(blob, output) {
    let reader = new FileReader()
    reader.onload = function (evt) {
        let base64 = evt.target.result
        output(base64)
    }
    reader.readAsDataURL(blob)
}
js
  • 调用写入数据函数
setImgData(fileInputList)
js
  • 完整selectFile:
selectFile() {
    //压缩后的最大尺寸
    var MAX_SIZE = 1024
    //获取文件列表
    var fileInputList = document.getElementById("file").files
    var that = this
    //初始化数据
    that.imgList = []
    //开始写入数据
    setImgData(fileInputList)
    //递归顺序写入数据
    function setImgData(input) {
        var index = that.imgList.length
        if (input.length > index) {
            console.log(fileInputList[index].name, "压缩前:", (fileInputList[index].size / 1024).toFixed(0) + "KB")
            var name = fileInputList[index].name
            compress(fileInputList[index]).then(res => {
                blobToDataUrl(res, base64 => {
                    console.log(name, "压缩后:", (res.size / 1024).toFixed(0) + "KB")
                    that.imgList.push({
                        name,
                        base64
                    })
                    if (input.length > index) {
                        //递归
                        setImgData(input)
                    }
                })
            })
        }
    }
    //压缩
    function compress(target) {
        return new Promise(resolve => {
            if (target.size / 1024 < MAX_SIZE) {
                resolve(target);
            }
            // 压缩到MAX_SIZE KB,这里的MAX_SIZE就是要压缩的大小,可自定义
            imageConversion
                .compressAccurately(target, MAX_SIZE)
                .then(res => {
                    resolve(res);
                });
        });
    }
    //blob转为base64
    function blobToDataUrl(blob, output) {
        let reader = new FileReader()
        reader.onload = function (evt) {
            let base64 = evt.target.result
            output(base64)
        }
        reader.readAsDataURL(blob)
    }
}
js

Step3:Style样式

<style scoped>
    body {
        margin: 0;
        padding: 0;
        overflow: auto !important;
    }

    .box {
        display: flex;
        flex-direction: column;
        justify-content: center;
        align-items: center;
    }

    .box input {
        margin: 20px;
    }

    .box .img-grid {
        display: grid;
        grid-template-columns: repeat(4, 1fr);
    }

    .box .img-grid .img-item {
        margin: 10px;
        display: flex;
        flex-direction: column;
        justify-content: center;
        align-items: center;
    }

    .box img {
        width: 200px;
        height: 120px;
    }

    .box span {
        margin: 5px;
    }
</style>
css

完整实现

<template>
    <div class="box">
        <input type="file" id="file" @change="selectFile" accept="image/png,image/jpg,image/jpeg,image/gif" multiple/>
        <div class="img-grid">
            <div class="img-item" v-for="item in imgList">
                <img :src="item.base64">
                <span>{{item.name}}</span>
            </div>
        </div>
    </div>
</template>

<script>
    import * as imageConversion from "image-conversion";

    export default {
        data() {
            return {
                imgList: []
            }
        },
        methods: {
            selectFile() {
                //压缩后的最大尺寸
                var MAX_SIZE = 1024
                //获取文件列表
                var fileInputList = document.getElementById("file").files
                var that = this
                //初始化数据
                that.imgList = []
                //开始写入数据
                setImgData(fileInputList)

                //递归顺序写入数据
                function setImgData(input) {
                    var index = that.imgList.length
                    if (input.length > index) {
                        console.log(fileInputList[index].name, "压缩前:", (fileInputList[index].size / 1024).toFixed(0) + "KB")
                        var name = fileInputList[index].name
                        compress(fileInputList[index]).then(res => {
                            blobToDataUrl(res, base64 => {
                                console.log(name, "压缩后:", (res.size / 1024).toFixed(0) + "KB")
                                that.imgList.push({
                                    name,
                                    base64
                                })
                                if (input.length > index) {
                                    //递归
                                    setImgData(input)
                                }
                            })
                        })
                    }
                }

                //压缩
                function compress(target) {
                    return new Promise(resolve => {
                        if (target.size / 1024 < MAX_SIZE) {
                            resolve(target);
                        }
                        // 压缩到MAX_SIZE KB,这里的MAX_SIZE就是要压缩的大小,可自定义
                        imageConversion
                            .compressAccurately(target, MAX_SIZE)
                            .then(res => {
                                resolve(res);
                            });
                    });
                }

                //blob转为base64
                function blobToDataUrl(blob, output) {
                    let reader = new FileReader()
                    reader.onload = function (evt) {
                        let base64 = evt.target.result
                        output(base64)
                    }
                    reader.readAsDataURL(blob)
                }

            }
        }
    }
</script>

<style scoped>
    body {
        margin: 0;
        padding: 0;
        overflow: auto !important;
    }

    .box {
        display: flex;
        flex-direction: column;
        justify-content: center;
        align-items: center;
    }

    .box input {
        margin: 20px;
    }

    .box .img-grid {
        display: grid;
        grid-template-columns: repeat(4, 1fr);
    }

    .box .img-grid .img-item {
        margin: 10px;
        display: flex;
        flex-direction: column;
        justify-content: center;
        align-items: center;
    }

    .box img {
        width: 200px;
        height: 120px;
    }

    .box span {
        margin: 5px;
    }
</style>
html

效果

test.gif

image.png

image.png

微信公众号原创文章传送门

2022-05-05 前端选择本地文件并显示

2022-05-01 写了一个很简易的Markdown编辑器

2022-04-30 Java 生成二维码(已优化)

2022-04-30 Java 生成二维码

2022-04-30 写了一个纯前端的验证码

2022-04-30 Nuxtjs docker 部署

打赏
  • 微信
  • 支付宝
评论
来发评论吧~
···

歌手: