프론트엔드/Vue

이미지 리사이즈 input (image input 리사이즈)

짱구를왜말려? 2022. 10. 15. 12:19
반응형
SMALL

# What?

이미지 업로드 시 파일 용량을 줄이고 싶을 때

 

# How?

@ InputResizeImg.vue

<template>
    <div class="upload">
        <label for="a" class="find-file">
            파일 선택
            <input type="file" id="a" accept="image/*" @change="changeFile">
        </label>
    </div>
</template>
<script>
export default {
    props: ["maxWidth"],

    data(){
        return {
            file: "",
            reader: new FileReader(),
            image : new Image(),
            canvas: document.createElement("canvas")
        }
    },

    methods: {
        changeFile(event) {
            let self = this;

            this.reader.onload = function (readerEvent) {
                self.image.onload = function () {
                    let result = self.resize();

                    self.$emit("change", result);

                    return result;
                };
                self.image.src = readerEvent.target.result;
            };

            let dataURL = this.reader.readAsDataURL(event.target.files[0]);

            /*this.files = [];

            Array.from(event.target.files).map(file => {
                this.files.push({
                    file: file,
                    img: URL.createObjectURL(file)
                })
            })

            this.$emit("change", this.files.map(file => file.file));*/
        },

        remove(index){
            this.files = this.files.filter((img, indexData) => indexData != index);

            this.$emit("change", this.files.map(file => file.file));
        },

        resize(){
            let width = this.image.width;
            let height = this.image.height;
            height *= this.maxWidth / width;
            width = this.maxWidth;

            /*if (width > height) {
                if (width > this.maxSize) {
                    height *= this.maxSize / width;
                    width = this.maxSize;
                }
            } else {
                if (height > this.maxSize) {
                    width *= this.maxSize / height;
                    height = this.maxSize;
                }
            }*/
            this.canvas.width = width;
            this.canvas.height = height;
            this.canvas.getContext('2d').drawImage(this.image, 0, 0, width, height);
            const dataUrl = this.canvas.toDataURL('image/png');

            return this.dataURLtoBlob(dataUrl);
        },

        dataURLtoBlob(dataURI){
            const bytes =
                dataURI.split(',')[0].indexOf('base64') >= 0
                    ? atob(dataURI.split(',')[1])
                    : unescape(dataURI.split(',')[1]);
            const mime = dataURI.split(',')[0].split(':')[1].split(';')[0];
            const max = bytes.length;
            const ia = new Uint8Array(max);
            for (let i = 0; i < max; i++) ia[i] = bytes.charCodeAt(i);

            return new Blob([ia], { type: mime });
        }
    },

}
</script>

@ 사용할 컴포넌트.vue

<template>
    <input-resize-img :max-width="300" @change="changeFile" />

</template>
<script>
import {Link} from '@inertiajs/inertia-vue';
import Pagination from "../../Components/Pagination";
import Avatar from "../../Components/Avatar";
import Navigation from "../../Components/Navigation";
import Board from "../../Components/Board";
import InfiniteLoading from "vue-infinite-loading";
import Sidebar from "../../Components/Sidebar";
import {resizeImage} from '../../utils/resize';
import InputResizeImg from "../../Components/Form/InputResizeImg";

export default {
    components: {InputResizeImg, Sidebar, Board, Navigation, Avatar, Link, Pagination, InfiniteLoading},
    data(){
        return {
     
            form: this.$inertia.form({
                file: "",
            }),

          
        }
    },
    methods:{
     

      

        changeFile(file) {
            this.form.file = file;

            this.form.post("/boards/create", {
                preserveScroll: true,
                preserveState: true,
                replace: true,
                onSuccess: (page) => {

                }
            })
        },

    },
    mounted() {

    }
}
</script>
LIST