Как читать размеры и размеры изображений с помощью 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, тем больше она мне нравится.
:::информация Также опубликовано здесь.
:::
Оригинал