Как вырезать картинку из фона
HTML и CSSXSLTJavaScriptИзображенияСофтEtc
| Задача. | Показать универсальный и быстрый способ вырезания картинки из макета для точного совмещения с фоном. | ||
Часто технологам приходится готовить GIFы из картинок непрямоугольной формы, которые нужно наложить на неоднородный фон. Чтобы получить меньший объем файла и убрать края стыковки, фон из картинки необходимо вырезать:
Классический вариант решения этой задачи — использование инструментов Magic Wand или Magic Eraser. Но что делать, когда они бессильны?
Однажды я получил от дизайнера такой макет:
Исходник в PSD (ZIP, 525 КБ)
Для макета мне нужно было сохранить ленточку и коробочку (вместе с тенью) отдельной картинкой, которая накладывается поверх открытки и листа бумаги.
Сложная, на первый взгляд, проблема решается довольно просто. Все, что нужно сделать, — это найти разность между картинкой с ленточкой и коробочкой и картинкой без них.
| 1. | Выделяем все изображение (Ctrl+A), копируем видимую область (Edit → Copy Merged или жмем Shift+Ctrl+C), создаем новый документ (Ctrl+N) и вставляем в него картинку (Ctrl+V). |
| 2. | Возвращаемся в исходный макет и, не снимая выделения, отключаем слои ribbon and box и shadow (то есть все, что связано с вырезаемыми объектами). |
| 3. | Выделяем верхний слой (Layer 2) и меняем режим наложения с Normal на Difference: |
| 4. | Жмем на иконку внизу палитры Layers и выбираем из выпадающего списка Threshold. В появившемся окошке перетаскиваем ползунок в крайнее левое положение: |
| 5. | В результате мы получаем битовую маску, где черный цвет как раз представляет собой область отсечения: |
Хозяйке на заметку | С помощью режима наложения Difference (разность) мы подсветили те области, которые отличаются в наших двух слоях. | |
И наконец, не снимая выделения со слоя Threshold в палитре Layers, выделяем все черные области с помощью Magic Wand (или с помощью Select → Color Range), отключаем слои Threshold и Layer 2, выделяем слой Layer 1 и жмем кнопку Delete. Смотрим на результат:
Мы получили изображение, которое идеально стыкуется с фоном. Этим методом я пользуюсь постоянно, он не раз выручал меня и в более сложных случаях.
Получить все изображения в DOM (включая фон)
09 марта 2017 г.
«Если бы я мог хранить молнии в банках, я бы продал их больным светлячкам, чтобы они освещали им путь. Только платить за это им нечем, кроме жизни».![]()
— Посоветую, здесь ничего нет…
- img
- фоновое изображение
- iframe
- Вместе
Весьма полезно, если вы пишете расширение для браузера или что-то в этом роде.
Чтобы получить все изображения в DOM, мы рассмотрим три места: элемент,
background-image свойство CSS и . Да, за каждым iframe скрывается волшебное королевство.
Если вы хотите получить изображения только в , вы можете выбрать два варианта:
Вы можете выполнить поиск в DOM для img tag:
function getImgs (doc) {
вернуть Array.from (doc.getElementsByTagName ('img'))
.карта (изображение =>
({
src: img.currentSrc, // img.src, если вы хотите источник
ширина: img.naturalWidth,
высота: img.naturalHeight
}))
}
getImgs(документ) Или просто используйте document.images:
function getImgs (doc) {
вернуть Array.
from(doc.images)
.карта (изображение => ({
src: img.currentSrc, // img.src, если вы хотите источник
ширина: img.naturalWidth,
высота: img.naturalHeight
}))
}
getImgs(document) Для background-image нам нужно проверить каждый узел в DOM:
function getBgImgs (doc) {
const srcChecker = /url\(\s*?['"]?\s*?(\S+?)\s*?["']?\s*?\)/i
вернуть Array.from(
Array.from(doc.querySelectorAll('*'))
.reduce((коллекция, узел) => {
let prop = window.getComputedStyle (узел, ноль)
.getPropertyValue («фоновое изображение»)
// соответствует `url(...)`
пусть соответствует = srcChecker.exec (реквизит)
если (совпадение) {
collection.add (соответствие [1])
}
возврат коллекции
}, новый набор())
)
}
getBgImgs(документ) Мы не можем просто получить ширину и высоту фонового изображения. Если они вам нужны, вы должны загрузить их.
Поскольку изображения, которые вы получаете в DOM, скорее всего, уже находятся в кеше браузера, процесс загрузки должен быть довольно быстрым.
функция loadImg (источник, время ожидания = 500) {
var imgPromise = новое обещание ((разрешить, отклонить) => {
пусть img = новое изображение ()
img.onload = () => {
решать({
источник: источник,
ширина: img.naturalWidth,
высота: img.naturalHeight
})
}
img.onerror = отклонить
img.src = источник
})
var timer = new Promise((разрешить, отклонить) => {
setTimeout (отклонить, тайм-аут)
})
вернуть Promise.race([imgPromise, таймер])
}
функция loadImgAll (imgList, время ожидания = 500) {
вернуть новое обещание ((разрешить, отклонить) => {
Обещание.все(
imgList
.map(источник => loadImg(источник, время ожидания))
.map(p => p.catch(e => false))
).then(результаты => разрешить(результаты.фильтр(г => г)))
})
}
loadImgAll(getBgImgs(документ)).then(imgs => console.log(imgs)) Просто рекурсивный поиск во всех фреймах
function searchIframes (doc) {
переменная imgList = []
doc.
querySelectorAll('iframe')
.forEach(iframe => {
пытаться {
iframeDoc = iframe.contentDocument || iframe.contentWindow.document
imgList = imgList.concat(getImgs(iframeDoc) || []) // или getBgImgs(iframeDoc)
imgList = imgList.concat (searchIframes (iframeDoc) || [])
} поймать (е) {
// просто игнорировать ошибки (например, кросс-происхождение)
}
})
вернуть imgList
}
searchIframes(документ) Можно использовать из коробки. Это было сделано, когда я писал расширение для Chrome.
функция getImgAll (документ) {
вернуть новое обещание ((разрешить, отклонить) => {
loadImgAll(Array.from(searchDOM(doc)))
.then(разрешить, отклонить)
})
функция searchDOM (doc) {
const srcChecker = /url\(\s*?['"]?\s*?(\S+?)\s*?["']?\s*?\)/i
вернуть Array.from(doc.querySelectorAll('*'))
.reduce((коллекция, узел) =>
{
// источник бг
let prop = window.getComputedStyle (узел, ноль)
.getPropertyValue («фоновое изображение»)
// соответствует `url(.
frame$/i.test(node.tagName)) {
// iframe
пытаться {
searchDOM(node.contentDocument || node.contentWindow.document)
.forEach (изображение => {
если (изображение) { коллекция.добавить (изображение) }
})
} поймать (е) {}
}
возврат коллекции
}, новый набор())
}
функция loadImg (источник, время ожидания = 500) {
var imgPromise = новое обещание ((разрешить, отклонить) => {
пусть img = новое изображение ()
img.onload = () => {
решать({
источник: источник,
ширина: img.naturalWidth,
высота: img.naturalHeight
})
}
img.onerror = отклонить
img.src = источник
})
var timer = new Promise((разрешить, отклонить) => {
setTimeout (отклонить, тайм-аут)
})
вернуть Promise.race([imgPromise, таймер])
}
функция loadImgAll (imgList, время ожидания = 500) {
вернуть новое обещание ((разрешить, отклонить) => {
Обещание.
все(
imgList
.map(источник => loadImg(источник, время ожидания))
.map(p => p.catch(e => false))
).then(результаты => разрешить(результаты.фильтр(г => г)))
})
}
}
getImgAll(document).then(list => console.log(list)) [EOF]
#Recommended#Image#JavaScript#DOM
NEWER获取 DOM 里所有图片(包括背景和iframe)
OLDER倒腾 Vue Webpack2 单元测试
评论没有加载,检查你的局域网
Невозможно загрузить комментарии. Проверьте свою сеть.
Как предварительно загрузить фоновые изображения CSS
Часть 7 из 7 в AmplitudeJS: с нуляДэн Пастори 27 сентября 2018 г.
#AmplitudeJS
Это может быть самый маленький учебник в серии, но также и один из самых важных. Предварительная загрузка изображений чрезвычайно важна при установке их в качестве фонового изображения.
В AmplitudeJS мы рекомендуем дизайнерам/разработчикам устанавливать фоновое изображение элемента с помощью CSS.
Таким образом, обработчик кликов остается с элементом и не может быть неправильно истолкован при нажатии на изображение. Например, когда мы реализуем кнопку амплитуда-воспроизведение-пауза , и у нас есть состояние воспроизведения . Мы хотим, чтобы состояние воспроизведения было представлено кнопкой паузы , чтобы пользователь знал, когда воспроизводится звук, он может приостановить его. Мы хотим, чтобы они были фоновым изображением, чтобы события щелчка, привязанные к родительскому элементу, не интерпретировались неправильно при нажатии на дочерний элемент изображения. Если вы помещаете изображение внутрь родительского элемента, javascript может работать неправильно.
Проблема с использованием фоновых изображений заключается в том, что при первом переключении (с пауза на воспроизведение ) происходит вспышка во время загрузки нового значка. Это не оптимальный UX. Мы хотим предварительно загрузить все фоновые изображения, чтобы не получить эту вспышку и получить упрощенное изменение между состояниями.![]()
Настройка элемента предварительной загрузки
Вам нужно будет найти все фоновые изображения, используемые вашим плеером. В нашем синем плейлисте их много, и мы будем использовать их в качестве примера. Следующее, что нам нужно сделать, это добавить их все как теги изображений и обернуть их в предварительная загрузка элемент вроде этого:
<дел>![]()
![]()
![]()
![]()
![]()
![]()
![]()
![]()
![]()
![]()
svg" />
![]()

А с помощью настроечного слоя Threshold (порог) мы одновременно выполнили две задачи: закрасили области с яркостью больше единицы в белый цвет и подготовили слой для создания выделения (попробуйте, не создав этого слоя, выделить черный цвет в слое Layer 2).
from(doc.images)
.карта (изображение => ({
src: img.currentSrc, // img.src, если вы хотите источник
ширина: img.naturalWidth,
высота: img.naturalHeight
}))
}
getImgs(document)
frame$/i.test(node.tagName)) {
// iframe
пытаться {
searchDOM(node.contentDocument || node.contentWindow.document)
.forEach (изображение => {
если (изображение) { коллекция.добавить (изображение) }
})
} поймать (е) {}
}
возврат коллекции
}, новый набор())
}
функция loadImg (источник, время ожидания = 500) {
var imgPromise = новое обещание ((разрешить, отклонить) =>
все(
imgList
.map(источник => loadImg(источник, время ожидания))
.map(p => p.catch(e => false))
).then(результаты => разрешить(результаты.фильтр(г => г)))
})
}
}
getImgAll(document).then(list => console.log(list))