vue-labeling-image
v0.1.1
Published
Vue component for labeling data in images
Maintainers
Keywords
Readme
Vue markup document
English | Русский
Vue labeling image - это компонент для vue.js, позволяющий маркировать данные на картинках. Проще говоря, это UI для нейронок. Примером для создания данного компонента послужил данный проект, сейчас он уже не актуален. Eсли вам интересна данная тема, я рекомендую вам обратить внимание вот на этот репозиторий. По большей части я разрабатывал компоненты для маркирования текста, поэтому основное предназначение моего компонента это OCR, но он подойдет и для других похожих задач. Как пример, я могу указать на yandex и google картинки. Там можно загрузить свою картирку, а после выделить какую-то определенную её область, мой компонент вполне с этой задачей справится.
Для корректной работы данного компонента нужен vue.js версии 3.5 и выше (я использую useTemplateRef и defineModel). При разработке данного компонента я использовал vue.js версии 3.5.17.
Чтобы не переписывать код в пустую, я бы вам посоветовал открыть страницу примеров и самим посмотреть, что может мой компонент. Я укажу ссылки на примеры с кодом, так наверное будет проще.
И так, откройте страницу примеров, выберите какую-нибудь картинку, и разметьте произвольные области (нажмите левую кнопку мыши, и не отпуская её выделите произвольную область. Если вы смотрите страницу примеров с мобильного телефона, то проведите пальцем по картинке). Маркированные области можно переносить по картинке и менять их размеры, для этого потяните их за края.
Установка, минимальная настройка
Как и положено, наверное стоит сказать, что для установки данного компонента нужен Node.js и NPM, но вы наверное и сами это знаете. Установить данный компонент можно следующим способом:
npm install vue-labeling-image;Если у вас нет проблем с интернетом, то компонент вы установите. Дальше нужно будет его подключить, это можно будет сделать следующим способом:
<template>
<labeling-image
:image-src="file"
v-model="areas"
/>
</template>
<script setup>
import { ref } from 'vue';
import LabelingImage from 'vue-labeling-image';
import 'vue-labeling-image/lib/styles.css';
const file = ref(null);
const areas = ref([]);
</script>Если вы планируете использовать мой компонент более чем на одной странице, то имеет смысл подключить CSS глобально, в main.js, или App.vue, тут выбирайте как вам будет удобнее.
Как можно заметить, важными являются 2 строчки, image-src="file" и v-model="areas".
Image-src - входной параметр, в который нужно передать картинку которую нужно маркировать. В подавляющем большинстве случаев, это будет двоичный файл, но возможно передать и путь к картинке, и саму картинку в формате base64. Вполне естественно, что без этого параметра ничего маркировать не получится. Саму картинку вы скорее всего отправите на сервер через FormData. Я бы порекомендовал вам посмотреть код примера. Если вы начинающий frontend-разработчик, то я рекомендую вам посмотреть код того, как работает стилизованный input выбора файла.
Areas - это массив объектов. Он содержит параметры маркированных областей и обязательно должен содержать следующие поля:
const areas = [
{
id: 1759337013345,
x: 15,
y: 15,
width: 30,
height: 30,
}
];Тут нужно оговориться, что единого API для нейронок не существует. Когда я первый раз писал UI для нейронки, мне нужно было указать координаты начальной и конечной точки (X1, Y1, X2, Y2). После, для одного НИИ нужно было создать UI, который бы принимал и отдавал начальую и конечную точку в следующем виде: [[X1, Y1], [X2, Y2]]. Это массив, в котором находятся координаты начальной и конечной точки, первый массив это начальная точка, второй массив это конечная точка. На аутсорсе я писал UI которое бы принимало и отдавало координаты в следующем виде:
{
name_area: [
{
x: "10",
y: "10"
},
{
x: "10",
y: "40"
},
{
x: "40",
y: "40"
},
{
x: "40",
y: "10"
}
]
}Чтобы вы не ломали голову, это массив, в котором 4 объекта, это точки. Они идут от верхней левой, к нижней левой точке, затем к правой нижней точке, и последняя точка - правая верхняя. Как не трудно догадаться, получается прямоугольник, мне нужно было его построить. Возвращать маркированные области мне нужно было в этих форматах, в зависимости от API. Последнее из того, что я делал, нейронке была нужна начальная точка (координаты X, Y) и ширина с высотой маркированной области.
Если подводить не большой итог, можно выделить, что для всех нейронок, координаты точек должны быть представлены в относительных величинах (процентах). Смотрите, картинки могут быть разными, возможно загрузить картинку в 2000px и в 300px. Если область в которую нужно вставить картинку 600px, то на картинке в 2000px при точных величинах (px), нейронка не сможет понять, где искать текст, она же сожмется до 600px. Нужно будет ещё отправить размеры области в которую картинка вставляется. Это лишние расчеты. Гораздо проще отправить данные в относительных величинах, а нейронка эти данные разметит как нужно.
В моём случае id - это id маркированной области, по умолчанию, во время маркирования, это текущая дата в милисекундах, но если back вернет что-то другое, то ничего страшного. Главное, чтобы id-ки у маркированных областей были уникальными. X и y - это координаты начальной точки, width и height это ширина и высота маркированной области.
Как можно догадаться, за основу я взял последнее из того, что я делал. На мой взгляд такое API более понятно человеку. В будующем я планирую сделать так, чтобы мой компонент подстраивался под любое API, но пока что, мой компонент будет строить маркированные области так.
Рекомендации по использованию
Eсли вы планируете использовать мой компонент на мобильном устройстве или планшете, то имейте в виду следующее. Когда картинка не выбрана, вы можете прокручивать вниз когда касаетесь моего компонента. Когда же картинка выбрана, то вниз прокрутить вы уже не сможете, скорее всего при касании моего компонента у вас будут появляться маркированные области. Для того, чтобы картинку можно было маркировать, мне приходится отключать обычное поведение для touch, иначе маркировать ничего не получится, при маркировании будет происходить прокрутка вниз/вверх. Самый простой вариант, это оставить по краям не большое расстояние, оно нужно для того, чтобы касаясь его можно было прокручивать вниз/вверх. Как вариант, можно добавить кнопку, которая бы включала/отключала возможность редактирования компонента. Для этого просто добавьте к моему компоненту :is-readonly="true", или просто is-readonly. Самый радикальный вариант, это определить высоту компонента, высоту экрана, и если высота компонента сильно больше высоты экрана, то в таком случае можно отключить возможность маркирования картинок, и вывести текст, что-то вроде "маркирование на мобильном устройтве не доступно". Но это совсем крайняя мера.
Желательно, чтобы блок (div, main, article, section) в котором будет находиться мой компонент не имел position: relative. При маркировании, когда вы выходите за пределы блока, процесс маркирования не останавливается, вы можете отпустить кнопку в любом месте, тогда будет создана маркированная область. Если вы отпустите левую кнопку мыши на блоке, который имеет больший z-index, чем блок в котором лежит мой компонент, то мой компонент про это ничего не узнает, и процесс маркирования не прекратится. Имейте это ввиду.
Методы, более полная настройка
Скорее всего, данный раздел вам не пригодится, но написать про него стоит. Ниже я приведу пример, он условный, и нужен для того, чтобы объяснить как добавлять методы к моему компоненту. Для того, чтобы посмотреть как работают методы, откройте страницу примеров и кликнете по заголовку "методы". Посмотреть код примера можно по следующей ссылке.
<template>
<labeling-image
:image-src="file"
v-model="areas"
v-model:active-id="activeId"
@is-load-image="changeIsLoadImage"
@get-sizes="changeSizes"
/>
</template>
<script setup>
import { ref } from 'vue';
import LabelingImage from 'vue-labeling-image';
import 'vue-labeling-image/lib/styles.css';
const file = ref(null);
const areas = ref([]);
const activeId = ref(null);
const isLoadImg = ref(false);
const widthImg = ref(null);
const heightImg = ref(null);
const realWidthImg = ref(null);
const realHeightImg = ref(null);
const changeIsLoadImage = (isLoad) => isLoadImg.value = isLoad;
const changeSizes = ({
widthImage,
heightImage,
realWidthImage,
realHeightImage,
}) => {
widthImg.value = widthImage;
heightImg.value = heightImage;
realWidthImg.value = realWidthImage;
realHeightImg.value = realHeightImage;
}
</script>@is-load-image - данный метод нужен для того, чтобы узнать загрузилась картинка, или нет. Он возвращает булево значение true, если картинка загрузилась, и false, если возникла ошибка при загрузке картинки. Я бы посоветовал вам открыть страницу настроек, и вставить в поле "imageSrc" путь к какой-нибудь картинке. Если у вас нет никаких идей вставьте вот этот путь:
https://lapkins.ru/upload/resize_cache/uf/c8f/293_293_2/c8f2a2f9868aec552e5819f100a9652c.jpg У вас должен подгрузиться фокстерьер. Когда он подгрузится, кнопка "Выберите файл" станет зеленой, что говорит о том, что картинка подгрузилась. Попробуйте удалить какую-нибуль букву, кнопка снова станет синей. Это делается заменой переменной isLoadImg с true на false. Если вдруг по этому адресу картинки не будет, то попробуйте вставить свою картинку. Сайт не мой, а за картинкой я следить не могу.
Как не трудно догадаться, этот метод нужен для определения правильно ли подгрузилась картинка, или нет. Если file не равен null, а значение возвращаемое этим методом равно false, значит что-то пошло не так. Обычно если для поля выбора файла задать accept="image/*", то на компьютере будут видны только картинки, а вот на мобильном устройстве, пользователь сможет выбрать не только картинки, но и документы. PDF к примеру. В таком случае можно выводить сообщение, что "произошла ошибка во время загрузки картинки". Если же картинка подгрузилась нормально, то можно вывести какой-нибудь блок. В примерах я вывожу блок для маркированных областей.
@get-sizes - данный метод скорее всего вам не пригодится. Он возвращает размеры картинки для маркирования. Возвращаются её реальные размеры и размеры при масштабировании (когда она вставлена в блок). Соответственно widthImage и heightImage это размеры когда она вставлены в блок (масштабирована). RealWidthImage и realHeightImage - это реальные размеры картинки. Если ширина картинки 2000px, а она вставляется в блок в 600px, то ее реальная ширина (realWidthImage) будет равна 2000px, а масштабированная ширина (widthImage) будет равна ширине блока, соответственно 600px.
Как я выше писал, для большинства нейронок будут нужны относительные величины (проценты). Но не исключено, что по техническому заданию вам нужно будет передать масштабированные размеры картинки. Данный метод для этого.
У меня был такой случай, я отправлял на сервер картинку с маркированными областями, а на сервере программист не мог определить её реальные размеры. Так хорошо язык java он не знал. Меня попросили передавать реальные размеры картинки. В принципе это был единственный раз, и как я выше писал вероятность того, что вы будете этот метод использовать очень мала.
v-model:active-id - возвращает id активной области, доступен для редактирования. По умолчанию, когда я добавляю маркированные области (в моем примере я их добавляю в начало массива areas), я возвращаю id-ик добавленной области, и делаю её активной. Если вы откроете страницу примеров, и разметите какую-нибудь картинку, то у вас появятся блоки с маркированными областями. Если вы будете по ним кликать, то активная маркированная область будет меняться, это можно заметить по тому, что маркированные области будут менять цвет. Активная область у меня имеет красный цвет. Как пример, вам пришла с сервера какая-нибудь картинка с маркированными областями. Вы их вывели, и вам нужно узнать где какая область находится на картинке. Кликая по блокам можно будет это определить. Или другой пример, вам пришла картинка с маркированными областями, и кликая по ним, вам нужно будет подгружать данные в зависимости от выбранного id-ка.
Входные параметры
Прежде чем я буду описывать входные параметры, я бы посоветовал вам открыть страницу настроек. Выберите какую-нибудь картинку. Попробуйте разметить несколько облаcтей на картинке, а дальше поиграйте с параметрами. Я старался делать мой компонент максимально настраиваемым. Попробуйте поменять тему. Поменяйте минимальные размеры для маркированных областей. Поменяейте разрешение для блока маркировки картинок. Поменяйте параметры растягивания и перемещения маркированных областей. Посмотрите, что при этом изменится. Я больше практик, и считаю, что так информация лучше усвоится, так будет более наглядно.
Маркирование картинки, работа с маркированными областями
isMarkup - возможность создавать маркированные области на картинке. По умолчанию равно true. Для маркирования, сперва нужно выбрать файл. Может пригодиться, если нужно создавать маркированные области в зависимости от какого-нибудь условия. К примеру, мы создали область, и нельзя создать новую, пока мы не введём имя области, или какой-то другой параметр. Маркированные области можно будет растягивать и переносить в рамках картинки. Если данное поведение не требуется, смотрите параметры ниже.
isResizeArea - возможность растягивания маркированных областей. По умолчанию равно true. Маркированные области можно растянуть потянув за края области. Если вы посмотрите на yandex, или google картинки, то там растягивание можно осуществить потянув за углы маркированной области. Как я уже выше писал, основное предназначение моего компонента это OCR. Область для маркирования на картинке может быть очень маленькая, тут нужна особая точность. Представьте, что вы вставили картинку ширина которой составляет 10000px в область, ширина которой составляет 400px. Картинка сожмётся в 25 раз. Если вы потяните за левый, или за правый край, то изменится только ширина маркированной области, она никуда не сдвинется. Это даёт некоторую точность при маркировании картинки.
isDraggingArea - возможность переносить маркированные области. По умолчани равно true. Переносить области можно только в пределах картинки. Имеет смысл отменить перетаскивание (:is-dragging-area="false"), если нужно лучше выделить какую-нибудь область на картинке. Потянув за края области, изменится высота, или ширина, но сама она не сдвинется, так можно точнее маркировать картинку.
isReadonly - возможность отмены создания новых областей. Отмена перетаскивания и растягивания существующих маркированных областей. По умолчанию равно false. В большинстве случаев, этот параметр нужен тогда, когда нам нужно отобразить маркированные области без возможности их редактирования. К примеру мы получили с сервера картинку, и маркированными областями (текст который нейронка смогла распознать), и нам нужно это отобразить без возможности редактирования. Просто добавьте этот параметр к моему компоненту, или задайте для него значение true.
Eсли isMarkup, isResizeArea и isDraggingArea будут равны false, то вы не сможете создавать, растягивать и переносить маркированные области, по сути это будет почти тоже самое, что добавлен параметр isReadonly или :is-readonly="true". Отличие заключается в том, что при isReadonly равном true, клик по маркированной области не сделает её активной. А если вы отключите isMarkup, isResizeArea и isDraggingArea, то при клике по маркированной области она будет становиться активной. Это может пригодиться, если вам пришли с сервера картинка, маркированные области, и вам нужно понять, где какая маркированная область находится на картинке. Или при клике по маркированным областям нужно будет подгружать какие-то данные с сервера.
Так-же имейте ввиду, что на мобильном устройстве, или планшете, вы не сможете прокручивать вниз/вверх, если будете касаться моего компонента. Для маркирования картинки, я отменяю стандартное поведение touch. Прокрутка будет возможна, если вы отключите isMarkup, isResizeArea и isDraggingArea, или добавите isReadonly к моему компоненту.
Настройка разрешения для блока маркирования картинок
Resolution - разрешение для блока маркирования документа. Если изображение, которое нужно маркировать отсутствует, то блок займет необходимое пространство согласно указанному разрешению. По умолчанию данный параметр равен "HD". Возможны следующие значения:
- 16:9 - область для маркирования будет иметь соотношение 16 к 9, где 16 это ширина области, а 9 это высота области.
- HD - область для маркирования будет иметь такое же соотношение как и 16:9.
- 10:9 - область для маркирования будет иметь соотношение 10 к 9, где 10 это ширина области, а 9 это высота области.
- CIF - область для маркирования будет иметь такое же соотношение как и 10:9.
- 8:5 - область для маркирования будет иметь соотношение 8 к 5, где 8 это ширина области, а 5 это высота области.
- QHD - область для маркирования будет иметь такое же соотношение как и 8:5.
- 5:6 - область для маркирования будет иметь соотношение 5 к 6, где 5 это ширина области, а 6 это высота области.
- MPEG2 - область для маркирования будет иметь такое же соотношение как и 5:6.
- 5:4 - область для маркирования будет иметь соотношение 5 к 4, где 5 это ширина области, а 4 это высота области.
- SXGA - область для маркирования будет иметь такое же соотношение как и 5:4.
- 5:3 - область для маркирования будет иметь соотношение 5 к 3, где 5 это ширина области, а 3 это высота области.
- WVGA - область для маркирования будет иметь такое же соотношение как и 5:3.
- 4:3 - область для маркирования будет иметь соотношение 4 к 3, где 4 это ширина области, а 3 это высота области
- VGA - область для маркирования будет иметь такое же соотношение как и 4:3.
- 3:1 - область для маркирования будет иметь соотношение 3 к 1, где 3 это ширина области, а 1 это высота области.
- WSXGA - область для маркирования будет иметь такое же соотношение как и 3:1.
- 2:1 - область для маркирования будет иметь соотношение 2 к 1, где 2 это ширина области, а 1 это высота области.
- 2K - область для маркирования будет иметь такое же соотношение как и 2:1.
- 1:1 - область для маркирования будет иметь соотношение 1 к 1. Как правило это нужно для для маркирования аватарок, была у меня такая задача.
Как правило большая часть картинок для маркировани будут иметь какое-то конкретное разрешение (соотношение сторон). В большинстве случаев это будет HD, его я и сделал по умолчанию. Если картинка для маркирования не выбрана, то будет отображаться заглушка согласно этому разрешению. А если картинка будет выбрана, то блок для маркирования документа примет размеры этой картинки. К примеру разрешение у нас 16:9, а мы выбрали вертикальную картинку с разрешением 9:16, тогда блок для маркирования примет размеры выбранной картинки.
Vertical - возможность сделать блок для маркирования картинки вертикальным. По умолчани равно false. Давайте я объясню на конкретном примере. Представим, что у нас разрешение по умолчанию установлено в HD, что соответствует разрешению 16:9, если мы включим этот параметр, то разрешение поля для разметки будет соответствовать разрешению 9:16. Как я уже выше писал, большая часть картинок у нас будет иметь одинаковые разрешения, за редким исключением. Если большая часть картинок имеет разрешени 9:16, то этот параметр может пригодиться. Как и resolution, после загрузки реальной картинки, поле для разметки примет размеры загруженной картинки, и этот параметр не будет иметь значение, пока мы не сбросим картинку.
Выбор темы
Theme - тема для маркированных областей. Если мы посмотрим на другие UI для OCR, то можно обратить внимание, что маркированные области как правило имеют синий цвет, а активная маркированная область имеет как правило зелёный цвет. Это не для всех документов подходит. Как правило, в мире большая часть документов имеет зеленый, или красный цвет. Меньше докуметов имеют синий цвет, но они есть, к примеру синяя карта. Вполне естественно, что для разных документов и тема должна быть разная. К примеру, у нас в России СНИЛС зеленый, если активная область на нем будет зеленой, то она просто будет не очень заметна на данном документе. Логично, что на красном документе, маркированные области красными быть не могут, иначе они будут сливаться. На основании своего опыта, я выделил 5 разных тем:
- Default - тема для зеленых документов, к примеру СНИЛС. Она стоит по умолчанию, и будет применяться, если данный параметр отсутствует.
- Red - тема для красных документов, у нас в России это паспорт, водительские права.
- Blue - тема для синих документов, как я выше писал, это синяя карта для автомобилистов.
- White - это тема для любого документа на листе формата А4, как-то трудовой договор, договор при покупке сим карты, договор оказания медицинских услуг, и тд.
- Black - такие документы реже встречаются, это черный фон и белый цвет на нём, видимо делается инверсия для отсканированных документов. Так же данная тема подойдёт для документов которые сделаны через принтер. Если принтер плохой, документы будут выглядеть темнее обычных.
Все темы которые я выше перечислил делались для Российских документов. Когда я на аутсорсе работал с ребятами из Эстонии, выяснилось, что некоторые темы для их документов не подходят. Поэтому я предусмотрел возможность создания своей кастомной темы, для этого в данном параметре нужно указать название своей кастомной темы. К примеру, если мы запишем в theme="castomTheme", то нужно будет прописать стили для класса "mark-up_theme_castomTheme". Стили для кастомной темы можно подобрать на странице настроек, в блоке "Стили для блока маркировки изображения".
Включение/отключение тени для маркированных областей
Выше я писал, что не может быть одной темы для всех типов документов. Однако бывают такие случаи, когда у нас по дизайну маркированные области имеют определённые цвета и менять их нельзя. Дизайн согласован, есть техническое задание. Может так получиться, что пользователь загрузил паспорт, у нас в России он красный. При маркировании документа, у него активная область получается красная, как следствие она не много будет сливаться с документом, что не очень хорошо. В таком случае, как вариант, можно включить тень для маркированных областей. В таком случае маркированные области не будут сливаться. Для большинства тем, тень будет черной, исключение только темная тема, при ней тень будет белой. Главный принцип это контрастность тени и маркированной области.
IsShadow - включение/отключение тени для маркированных областей. По умолчанию данный параметр равен false.
Настройки минимальных размеров для маркированных областей
Данные параметры нужны для задания минимальной ширины и высоты маркированной области. Вы можете случайно щелкнуть мышью на моём компоненте, без этих параметров будет создана маркированная область, которая вам не нужна. Нейронка ничего не сможет распознать в блоке 1 на 1 px.
MinWidth - минимальная ширина маркированной области. По умолчанию равно 10. Измеряется в px. Мой компонент нужен для разметки текста или выделения лиц на документах. Как-то сомнительно, что-бы область которая меньше 10px можно как-то распознать. Если в этом есть какая-то необходимость, то нужно задать 0.
MinHeight - минимальная высота маркированной области. По умолчанию равно 10. Измеряется в px. Мой компонент нужен для разметки текста или лиц на документах. Как-то сомнительно, что-бы область которая меньше 10px можно как-то распознать. Если в этом есть какая-то необходимость, то нужно задать 0.
Настройка подсказок для маркированный областей
Тут нужно оговориться, что подсказки будут появляться только на стационарном компьютере, при наведении мыши на маркированные области. На мобильном устройстве, или планшете, вы их не увидите.
IsTitle - возможность включения/отключения подсказки при наведении на маркированные области. По умолчанию равно true.
KeyTitle - ключ, по которому будет отображаться подсказка. По умолчанию, данный параметр равен "title". Можно поменять, на что угодно. Как правило на моменте отладки можно ввести id, чтобы видеть id-ки маркированных областей.
Сетка для блока маркирования картинок
Данный раздел скорее всего вам не пригодится. Он нужен для включения и настройки сетки. Данную вещь меня просили сделать только для одного проекта. Он нужен был для отладки. Пользователю после маркирования картинки нужно было определить, правильно ли мой компонент определяет размеры маркированных областей. Это был один очень старый сотрудник одного НИИ. Я допускаю, что это может пригодиться для лучшего маркирования документа.
EnableGrid - возможность включения/отключения сетки. По умолчанию сетка отключена, значение равно false.
GridSize - размер сетки. Возможны значения от 5 до 50. Значения должны быть кратны 5, т.е. можно ввести 5, 10, 15, 20, 25 и так до 50, но не 11, 12, 13, 14. Больше 50, делать размер сетки я не вижу смысла. По умолчанию равно 10. если вы введете не допустимое значение, к примеру 12, то сетка будет равна 5. Размеры сетки могут быть представлены как строкой, так и числом. Этот параметр может пригодиться, если нужно более точно маркировать картинку. Чтобы посмотреть данный параметр, нужно включить enableGrid.
Сетку можно включить и при отсутствии картинки. При наличии картинки, слой сетки будет находиться над картинкой, но под маркированными областями.
Стилизация
Как я выше писал, всего я смог выделить 5 тем для документов. Все эти темы делались для российских документов, и вам они могут не подойти. Возможно у вас будет вполне конкретный дизайн, и вам нужно будет стилизовать мой компонент под него. Этот раздел как раз этому и посвящён.
Я рекомендую вам придумать какое-нибудь название темы и добавить его в параметр "theme". К примеру, если вы назовёте вашу тему "castomTheme", то нужно будет переопределить стили для класса "mark-up_theme_castomTheme". Возможно обернуть мой компонент каким-нибудь блоком, задать для этого блока какой-нибудь класс, и переопределять стили для этого класса. К примеру, на разных страницах у нас разные стили, и чтобы не прописывать параметр "theme" для каждого экземпляра компонента, имеет смысл сделать это для всего блока. Так тоже можно. Выбирайте как вам будет удобнее, но я бы посоветовал вам первый вариант, с параметром "theme".
Чтобы вам было удобнее, я советую открыть страницу настроек, выбрать какую-нибудь картинку, и попробовать поменять параметры для блока "Стили для блока маркировки изображения". Наиболее часто изменяемые свойства я вынес в CSS переменные. Под моим компонентом есть кнопка "Показать стили для маркированной области". Нажав на неё можно будет посмотреть CSS переменные для стилизации моего компонента, и скопировать их, если вас всё устраивает.
Если посмотреть ниже, то можно заметить, что сперва идут стили для "блока маркирования картинок". Это сам блок, в котором будет лежать картинка для маркирования, и маркированные области. Когда мы начинаем маркировать картинку, к создаваемой маркированной области будут применяться стили, для "области в момент маркирования данных". Как правило данные стили, чуть-чуть темнее чем активная маркированная область. Тут можно задать любые стили, я сделал так. После того, когда вы закончили маркирование (отпустили левую кнопку мыши), область станет активной, применятся стили для активной области. Область можно сделать активной просто кликнув на неё. Это поведение по умолчанию, его можно переопределить, смотрите описание параметров. Если вы сделаете 4-5 маркированные области, то одна область будет активной, а к остальным областям будут применяться "общие стили для маркированных областей". Я писал документацию исходя их этого.
Стилизация блока маркирования картинок
В данном разделе идёт речь о стилизации блока в котором будет находиться картинка для маркирования. Как стилизовать области для маркирования будет описано ниже.
--mu-bg - background для блока маркирования картинок.
--mu-border - border для блока маркирования картинок.
--mu-box-shadow - box-shadow для блока маркирования картинок.
Стили для области в момент маркировки данных на картинке
Стили для маркированной области в момент её создания (маркировки). Так будет выглядеть маркированная область, в тот момент, когда мы начинаем маркировать документ, как правило, она будет чуть-чуть темнее, чем активная маркированная область. Для того, что-бы увидеть данные стили, нужно сперва выбрать картинку, затем нажать левую кнопку мыши и провети мышью по картинке не отпуская левую кнопку мыши. Параметр isMarkup должен быть равен true, isReadonly должен находиться в значении false, иначе маркировать картинку не получится.
--mu-marking-rect-dragging-fill - цвет заливки в момент маркирования картинки.
--mu-marking-rect-dragging-stroke - цвет линии в момент маркирования картинки, можно сказать цвет border в момент маркирования.
--mu-marking-rect-dragging-fill-opacity - прозрачность заливки в момент маркирования картинки. Как не трудно догадаться, если задать значение 0, то заливки не будет, будет видна только обводка маркированной области (border).
--mu-marking-rect-dragging-stroke-opacity - прозрачность линии в момент маркирования картинки. Можно задать значение 0, тогда у маркированной области будет отображаться только заливка.
Стили для активной маркированной области
Посмотреть данные стили можно после того, как процесс маркирования завершится. Последняя созданная область станет активной. Также данные стили будут применяться к области когда мы по ней кликнем. Параметр isReadonly должен находиться в значении false, иначе стили для активной области вы не увидите, да и разметить области вы не сможете. Так-же параметр isMarkup должен находиться в значении true, иначе картинку вы маркировать не сможете.
--mu-marking-rect-active-fill - заливка активной маркированной области.
--mu-marking-rect-active-stroke - цвет линии активной маркированной области, по другому border.
--mu-marking-rect-active-fill-opacity - прозрачность заливки активной маркированной области.
--mu-marking-rect-active-stroke-opacity - прозрачность линии активной маркированной области.
Общие стили для маркированных областей
В данном блоке будут находиться общие стили для маркированных областей. Если маркированная область не активная, и вы её уже создали, то стили для неё можно посмотреть тоже здесь. Из всего того, что я делал, могу сказать, что маркированные области отличаются только цветом заливки, цветом линий (border), и прозрачностью линий и заливки. Такие вещи как закругления, толщина линий, везде были одинаковыми.
--mu-marking-rect-fill - заливка маркированных областей, этот параметр переопределяется для активной области, и области в момент маркирования.
--mu-marking-rect-stroke - цвет линий маркированной областей, этот параметр переопределяется для активной области, и области в момент маркирования.
--mu-marking-rect-stroke-width - толщина линий маркированных областей, этот параметр применяется и для автивной области, и для области в момент маркирования. Будет как-то странно, если у активной области толщина линии будет больше, чем у обычных областей.
--mu-marking-rect-stroke-opacity - прозрачность линий маркированных областей, этот параметр переопределяется для активной области, и области в момент маркирования.
--mu-marking-rect-fill-opacity - прозрачность заливки маркированных областей, этот параметр переопределяется для активной области, и области в момент маркирования.
--mu-marking-rect-rx - border-radius по оси X или закругление по оси X, этот парамерт применяется и для активной области, и для области в момент маркирования.
--mu-marking-rect-ry - border-radius по оси Y или закругление по оси Y, этот парамерт применяется и для активной области, и для области в момент маркирования.
В большинстве случаев --mu-marking-rect-rx и --mu-marking-rect-ry будут одинаковыми, если вам не нужны закругления, то установите значения в 0.
Стили для тени маркированных областей
В данном блоке я задаю только цвет линии для тени, её толщину и прозрачность. При стилизации учитывайте, что цвет для тени должен быть конрастным с цветом линии маркированной области. В большинстве случаев тень стоит включать только тогда, когда вы не знаете какие точно документы будет загружать пользователь. К примеру, если загрузить документ с преобладанием красного, у нас в России это к примеру паспорт, то активная маркированная область будет не очень заметна. Тень нужна для того, чтобы выделить маркированную область на документе, сделать так, чтобы она не сливалась с ним.
--mu-marking-rect-shadow-stroke - цвет линии для тени, в большинстве случаев будет черный, но вы можете задать любое удобное для вас значение.
--mu-marking-rect-shadow-stroke-width - толщина линии для тени. Можете писать здесь любое значение, но оно должно быть больше, чем "--mu-marking-rect-stroke-width", иначе тени вы не увидите.
--mu-marking-rect-shadow-stroke-opacity - прозрачность линии для тени.
Стили сетки
Здесь можно задать цвет сетки. Чтобы увидеть данные стили, параметр "enableMarking" должен находиться в значении true.
--mu-grid-color - цвет линии сетки.
Слоты
Слоты могут пригодиться для того, чтобы вставить в мой компонент логотип компании, подсказки к маркированным областям во время отладки, какие-то картинки, элементы управления маркированием в виде иконок, или что-то подобное. Для начала откройте страницу примеров, и посмотрите примеры со слотами. Тут всё должно быть достаточно просто.
Мой компонент под капотом использует SVG. Если вы посмотрите yandex, или google картинки, то там компоненты для выделения области на картинке сделаны обычными div-ми. При такой разметке можно выделять прямоугольные области, а вот произвольные области выделить не получится. У меня в планах такое реализовать, а иначе как через SVG это сделать не получится.
Я реализовал 2 слота, "first" и "last". Слот "first" будет самым первым слоем, всё, что вы туда добавите будет находиться под всеми остальными элементами. Он будет находиться под маркированными областями, под активной маркированной областью, и под областью в момент маркирования картинки. Слот "last" будет находиться над всеми остальными элементами, он будет их перекрывать. Скорее всего вы будете пользоваться слотом "last", туда можно будет добавить логотип компании, элементы управления маркированием картинки, если это потребуется.
Пример ниже весьма условный, если вы хотите более детально разобраться в том, как работать со слотами откройте страницу примеров, и посмотрите все примеры со слотами, там есть ссылка на код примеров. Делается это следующим образом:
<template>
<div class="theme-slots">
<labeling-image
:image-src="file"
v-model="areas"
>
<template #first >
<text
v-for="{ x, y, id, title } in hints"
:key="id"
:x="`${x}%`"
:y="`${y}%`"
>
{{ title }}
</text>
</template>
<template #last >
<image
:href="the path to the image or the picture in base64"
width="80"
height="40"
x="100%"
y="10"
/>
</template>
</labeling-image>
</div>
</template>
<script setup>
import { ref } from 'vue';
import LabelingImage from '';
import 'vue-labeling-image/lib/styles.css';
const file = ref(the path to the image or the picture in base64);
const areas = ref([
{
id: 1759337197573,
name: "Photo",
width: 15.934959349593496,
height: 40.46242774566473,
x: 5.853658536585367,
y: 23.410404624277454,
},
{
id: 1759337204073,
name: "First name",
width: 25.853658536585368,
height: 8.38150289017341,
x: 50.40650406504065,
y: 28.901734104046245,
},
{
id: 1759337222917,
name: "Last name",
width: 20.48780487804878,
height: 7.225433526011561,
x: 53.98373983739837,
y: 10.982658959537572,
},
{
id: 1759337232429,
name: "Surname",
width: 13.658536585365855,
height: 6.9364161849710975,
x: 55.447154471544714,
y: 39.017341040462426,
},
{
id: 1759337240377,
name: "Gender",
width: 5.040650406504065,
height: 6.358381502890173,
x: 39.67479674796748,
y: 50,
},
{
id: 1759337248220,
name: "Birthplace",
width: 30.081300813008134,
height: 6.9364161849710975,
x: 49.43089430894309,
y: 58.67052023121387,
},
{
id: 1759337254262,
name: "Date of birth",
width: 30.24390243902439,
height: 7.225433526011561,
x: 57.56097560975609,
y: 48.554913294797686,
},
{
id: 1759337260502,
name: "Series",
width: 3.577235772357723,
height: 59.53757225433526,
x: 92.84552845528455,
y: 21.965317919075144,
},
]);
const hints = [
{
id: 1759337197573,
x: 23,
y: 38,
title: 'Photo',
},
{
id: 1759337222917,
x: 54,
y: 9,
title: 'Last name',
},
{
id: 1759337204073,
x: 51,
y: 26,
title: 'First name',
},
{
id: 1759337232429,
x: 42,
y: 44,
title: 'Surname',
},
{
id: 1759337254262,
x: 71,
y: 47,
title: 'Date of birth',
},
{
id: 1759337248220,
x: 50,
y: 71,
title: 'Birthplace',
},
{
id: 1759337240377,
x: 38.5,
y: 62,
title: 'Gender',
},
{
id: 1759337260502,
x: 89,
y: 88,
title: 'Series',
},
]
</script>
<style lang="scss" scoped>
.theme-slots {
image {
cursor: default;
transform: translateX(-85px);
}
text {
fill: #006fff;
font-weight: bold;
}
}
</styleВыше получился достаточно длинный пример. Я вставил кусок кода из одного примера со слотами. Кода много, но в данном примере важны секции "template". В слоте "first", я вывожу текст с подсказками, для этого я ниже добавил массив "hints", он занимает много места. В слоте "last" я вовожу картинку, в реальных примерах это логотип Бэтмена, здесь я не знаю какую картинку указать. Всё остальное не принципиально. В реальных примерах я взял паспорт с Бендером, вставил туда маркированные области (areas), в примере выше они тоже занимают много места. Я думаю, что всё должно быть наглядно и понятно.
Элементы SVG стилизуются не много не так, как HTML элементы. К примеру, для того, чтобы изменить цвет текста, используется свойство "fill", а не "color". Различия не сильные, посмотрите другие примеры со слотами, я думаю всё станет понятнее.
