Как читать размеры и размеры изображений с помощью Alpine.js

Как читать размеры и размеры изображений с помощью Alpine.js

20 декабря 2022 г.

Прошло несколько недель с тех пор, как я это сделал, но, просматривая мою новую статистику, я увидел один из моих старых Vue.js. публикации получают некоторую активность: Чтение размеров и размеров изображения с помощью Vue.js . В этом сообщении в блоге я показал, как взять выбранный пользователем файл и проверить размер файла и размеры изображения. Поскольку я медленно просматривал свои сообщения о Vue.js и создавал версии Aline.js, я подумал, что это идеально подойдет.

Я не буду повторять все из предыдущей записи, но позвольте мне резюмировать основные моменты.

* Очевидно, что ваш код на стороне клиента не может зайти на машину пользователя и прочитать специальные файлы. Что он может сделать, так это получить информацию о выбранном пользователем файле. Это можно сделать с помощью тега input, используя type=file. * Сразу после выбора файла ваш код имеет доступ к размеру файла. * Чтобы получить размеры, вам нужно немного поработать. Сначала создайте новый объект Image. * Вам необходимо установить источник изображения на содержимое файла. Это можно сделать с помощью URL-адреса данных. * Когда изображение загружено (помните, изображения имеют событие onload), вы можете проверить размеры.

Итак, учитывая вышеизложенное, давайте создадим быструю демонстрацию. Во-первых, HTML. У меня будет только поле ввода и место для распечатки сведений об изображении.

<div x-data="app">

    <input type="file" x-ref="myFile" x-on:change="selectedFile" accept="image/*"><br/>

    <template x-if="imageLoaded">
        <p>
        Image size is <span x-text="image.size"></span><br/>
        Image width and height is <span x-text="image.width"></span> / <span x-text="image.height"></span>
        </p>
  </template>
</div>

Несколько вещей, на которые следует обратить внимание. Как и в случае с Vue, нам иногда нужно обращаться к DOM, и, как и в случае с Vue, это делается с помощью refs. Вы можете увидеть мою настройку x-ref="myFile", чтобы получить прямой доступ к полю ввода. Также обратите внимание, что я использую событие change. Это сработает, когда пользователь выберет файл. Теперь давайте посмотрим на код.

document.addEventListener('alpine:init', () => {
  Alpine.data('app', () => ({
        imageLoaded:false,
        image: {
            size:null,
            width:null,
            height:null
        },
        selectedFile() {
            this.imageLoaded = false;

            let file = this.$refs.myFile.files[0];
            if(!file || file.type.indexOf('image/') !== 0) return;

            this.image.size = file.size;

            let reader = new FileReader();
            reader.readAsDataURL(file);

            reader.onload = evt => {
                let img = new Image();
                img.onload = () => {
                    this.image.width = img.width;
                    this.image.height = img.height;
                    this.imageLoaded = true;
                }
                img.src = evt.target.result;
            }

            reader.onerror = evt => {
                console.error(evt);
            }

        }

    }))
});

В моем приложении Alpine есть две основные переменные: imageLoaded и image. Единственная реальная логика находится в selectedFile. Это будет использовать $refs для захвата поля ввода и выбранного изображения. Затем я использую объект FileReader для чтения битов, устанавливаю его для изображения, и когда onload запускается, я могу обновить свои переменные для интерфейсных дисплеев. Например, с учетом этого исходного изображения:

Если я выберу его, я увижу это:

Вы можете проверить это самостоятельно, используя CodePen ниже:

https://codepen.io/cfjedimaster/pen/ExRMeZO?embedable=true

Итак, как я сделал в предыдущем сообщении. , давайте рассмотрим простой пример, добавляющий валидацию. В частности, максимальный размер файла, максимальная ширина и максимальная высота. HTML в основном такой же, за исключением того, что теперь я показываю ошибку при сбое проверки:

<div x-data="app">

    <input type="file" x-ref="myFile" x-on:change="selectedFile" accept="image/*"><br/>

    <template x-if="imageError">
    <p class="imageError" x-text="imageError">
    </p>
    </template>
</div>

В JavaScript я добавил константы для своих максимальных значений:

const MAX_SIZE = 100000;
const MAX_WIDTH = 500;
const MAX_HEIGHT = 300;

А вот и само приложение Alpine:

document.addEventListener('alpine:init', () => {
    Alpine.data('app', () => ({
        imageError:'',
        image: {
            size:null,
            width:null,
            height:null
        },
        selectedFile() {
            this.imageError = '';

            let file = this.$refs.myFile.files[0];
            if(!file || file.type.indexOf('image/') !== 0) return;

            this.image.size = file.size;
            if(this.image.size > MAX_SIZE) {
                this.imageError = `The image file size (${this.image.size}) is too much (max is ${MAX_SIZE}).`;
                return;
            }

            let reader = new FileReader();
            reader.readAsDataURL(file);

            reader.onload = evt => {
                let img = new Image();

                img.onload = () => {
                    this.image.width = img.width;
                    this.image.height = img.height;

                    if(this.image.width > MAX_WIDTH) {
                        this.imageError = `The image width (${this.image.width}) is too much (max is ${MAX_WIDTH}).`;
                        return;
                    }
                    if(this.image.height > MAX_HEIGHT) {
                        this.imageError = `The image height (${this.image.height}) is too much (max is ${MAX_HEIGHT}).`;
                        return;
                    }

                }
                img.src = evt.target.result;
            }

            reader.onerror = evt => {
                console.error(evt);
            }
        }
    }))
});

По большей части это то же самое, за исключением того, что теперь я проверяю различные свойства и устанавливаю новую переменную imageError, когда что-то не проходит проверку. Вы можете проверить это ниже:

https://codepen.io/cfjedimaster/pen/rNKRYYz?embedable=true

Я повторюсь, мои читатели знают, что я люблю это делать, но чем больше я использую Alpine, тем больше она мне нравится.

:::информация Также опубликовано здесь.

:::


Оригинал
PREVIOUS ARTICLE
NEXT ARTICLE