ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 이미지 리사이즈 input (image input 리사이즈)
    프론트엔드/Vue 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

    댓글

Designed by Tistory.