CSS를 사용하여 이미지 모자이크 스타일화를 달성하는 방법을 살펴보겠습니다.
CSS를 사용하여 이미지에 모자이크를 추가하는 방법은 무엇입니까? 다음 기사에서는 CSS를 능숙하게 사용하여 이미지 모자이크의 스타일을 지정하는 방법을 공유할 것입니다. 도움이 되기를 바랍니다.
1. 이미지 렌더링 소개
CSS에는 image-rendering이라는 흥미로운 기능이 있는데, 이 기능은 알고리즘을 사용하여 크기가 조정된 이미지를 더 잘 표시할 수 있습니다. (권장 학습: css 비디오 튜토리얼)
QR 코드의 더 작은 스크린샷이 있다고 가정합니다(아래 왼쪽에는 회로도만 있고 스캔할 수 없음). 10배 확대하면 이미지가 흐려집니다(오른쪽 아래). ) :
이때 확대된 이미지에 image-rendering: pixelated
기능을 추가하면 CSS가 알고리즘을 통해 이를 픽셀화하여 이미지 윤곽선의 가장자리를 더 선명하게 만듭니다. image-rendering: pixelated
的特性,CSS 会通过算法将其像素化展示,使其图像轮廓具有更锐利的边缘:
该特性非常适合应用在色彩单一、轮廓分明、需要被放大的图片上,可以营造出一种伪矢量的既视感(减少放大后的失真)。
对于色彩丰富、细节较多的照片,image-rendering: pixelated
使用后会营造出一种马赛克的外观:
这离本文标题所希望实现的马赛克效果还有段距离 —— 目前图片需要被放大后才能显示出效果,而我们希望能在保有原图尺寸的基础上,给图片覆盖等尺寸马赛克。
然而 image-rendering
特性对尺寸未发生缩放的元素是不会生效的:
MDN - This property has no effect on non-scaled images.
二、踩坑等尺寸马赛克的实现
等尺寸马赛克的原理相当于先把一张照片模糊化,然后再经过锐化算法处理得到各种小方格。
image-rendering: pixelated
帮我们实现了“锐化”的步骤,我们得想想怎么实现“模糊”。
首先使用滤镜的模糊方案是行不通的,因为 image-rendering
和图像缩放系数强相关,所以应当思考可以怎样利用图片的缩放能力。
这里得说一句,WEB 上的图片像极了 Photoshop 里的智能对象 —— 你可以任意修改它的尺寸(例如放大很多倍让其变模糊),但最后再把图片改回原本的大小时,图片会变回原来的样子(没有任何失真)。
如何保留图片放大后的“模糊”信息,是优先需要解决的问题。
聪明的小伙伴已经想到了可以尝试使用 canvas
来处理,毕竟 canvas
可以轻松获取、绘制图像,且绘制出来的图像信息是纯数据的,而非图形对象(Image
),故经其放大绘制的图片数据再进行缩小绘制(到原尺寸)会失真(这正好是我们所希望发生的)。
但这里也存在一些坑:
- 外部图像通过
image-rendering: pixelated
算法处理后显示的信息,canvas
是无法拿到的,因为那是显示层的东西。canvas
拿到的依旧是未经锐化的、模糊的原生图像内容; -
canvas
本身如果没有缩放的话,给canvas
添加image-rendering: pixelated
没有任何意义。
这意味着你无法把图片在 canvas
外面放大锐化,然后再写入 canvas
去缩小绘制(并不断迭代处理)来得到锐化后的原尺寸图片。
三、有趣的 canvas 拉伸
在解决上述问题时,我们先来看看 canvas
一个有趣的特性。
如果我们在 canvas
标签里定义了宽高:
<canvas width="100" height="50" ></canvas>
同时又给 canvas
在样式中定义了另一个宽高:
canvas { width: 200px; height: 200px; }
那么 canvas
会以哪个尺寸来显示呢?
答案是以 CSS 的尺寸来显示,但画布的内容尺寸会以画布标签内定义的宽高为准。这意味着虽然我们看到的是 200px * 200px

image-rendering: pixelated
를 사용하면 모자이크 모양이 생성됩니다. 🎜🎜
이미지 렌더링
기능은 크기가 조정되지 않은 요소에는 적용되지 않습니다. 🎜🎜🎜MDN🎜 - 이 속성은 크기가 조정되지 않은 이미지에는 영향을 미치지 않습니다.🎜< / blockquote>🎜🎜2. 구덩이를 밟아 균일한 크기의 모자이크 구현 🎜🎜🎜균등한 크기의 모자이크의 원리는 먼저 사진을 흐리게 한 다음 샤프닝 알고리즘으로 처리하여 다양한 작은 사각형을 얻는 것과 같습니다. . 🎜🎜image-rendering: pixelated
는 "선명화" 단계를 달성하는 데 도움이 되지만 "흐림"을 달성하는 방법에 대해 생각해야 합니다. 🎜🎜우선,이미지 렌더링
은 이미지 배율 요소와 밀접한 관련이 있기 때문에 필터를 사용한 흐림 솔루션은 작동하지 않으므로 이미지의 배율 기능을 어떻게 사용할 것인지 생각해야 합니다. 🎜🎜여기서 웹상의 사진은 Photoshop의 스마트 개체와 매우 유사하다는 점을 말씀드리고 싶습니다. 크기를 마음대로 수정할 수 있지만(예를 들어 여러 번 확대하여 흐릿하게 만드는 등) 결국에는 크기를 변경할 수도 있습니다. 사진을 원래 크기로 되돌리면 사진이 왜곡 없이 원래 모양으로 돌아갑니다. 🎜🎜사진을 확대한 후 "흐릿한" 정보를 유지하는 방법은 해결해야 할 최우선 문제입니다. 🎜🎜똑똑한 친구들은 이미캔버스
를 사용하여 처리하는 것을 생각해 봤습니다. 결국캔버스
는 이미지를 쉽게 얻고 그릴 수 있으며, 그려진 이미지 정보는 순수한 데이터입니다. 은 그래픽 개체(Image
)가 아니므로 확대했다가 원래 크기로 축소하여 그린 이미지 데이터는 왜곡됩니다(정확히 우리가 원하는 일입니다). 🎜🎜그러나 여기에도 몇 가지 함정이 있습니다: 🎜🎜즉,
image-rendering: pixelated
알고리즘으로 외부 이미지를 처리한 후에 표시되는 정보는canvas<로 얻을 수 없습니다. /code> , 그것이 디스플레이 레이어이기 때문입니다. <code>캔버스
는 여전히 선명하지 않고 네이티브 이미지 콘텐츠를 흐리게 합니다.캔버스
자체는 크기가 조정되지 않은 경우 크기가 조정되지 않습니다. >이미지 렌더링: 픽셀화는 의미가 없습니다.캔버스
외부에서는 이미지를 확대하고 선명하게 한 다음캔버스
에 써서 축소하고 그릴 수 없습니다(그리고 계속해서 )을 반복하여 선명한 원본 크기 이미지를 얻습니다. 🎜🎜🎜3. 흥미로운 캔버스 스트레칭🎜🎜🎜위 문제를 해결하면서 먼저캔버스
의 흥미로운 기능을 살펴보겠습니다. 🎜🎜canvas
태그에서 너비와 높이를 정의하는 경우: 🎜🎜 동시에 스타일에서<input id="file" type="file" accept="image/*" /> <canvas id="canvas"></canvas> <img src="/static/imghw/default1.png" data-src="./assert/0.png" class="lazy" id="img-raw" / alt="CSS를 사용하여 이미지 모자이크 스타일화를 달성하는 방법을 살펴보겠습니다." > <label for="compress-times">压缩倍数:</label> <input id="compress-times" type="number" value="12"> <button>马赛克化</button>로그인 후 복사로그인 후 복사canvas
에 대해 다른 너비와 높이를 정의하는 경우: 🎜🎜 그러면canvas { display: block; border: gray solid 1px; width: 600px; height: 600px; image-rendering: pixelated; } img { display: none; }로그인 후 복사로그인 후 복사캔버스
는 어떤 크기로 표시되나요? 🎜🎜답은 CSS 크기를 표시하는 것이지만, 캔버스의 콘텐츠 크기는 캔버스 태그에 정의된 너비와 높이를 기반으로 합니다. 즉,200px * 200px
의 캔버스가 표시되지만 실제로는 내용이 늘어납니다(너비 2배, 높이 4배). 🎜
注:左边为画布,右边为原图
这也是
canvas
作为可替换元素的一个特性 —— CSS 无法修改其内容。试想一下,如果 CSS 可以动态地修改canvas
内容的尺寸,意味着canvas
的内容会被裁剪掉一部分,或者多出来一部分空白区域,这显然是不可取的。所以canvas
在保留内容完整的前提下,整体伸缩到样式规定尺寸,是合理的浏览器行为。利用
canvas
的这个特性,我们可以这样来实现等尺寸马赛克:
- 创建一个画布,通过样式规定好其宽高,并设置
image-rendering: pixelated
特性;- 计算图片最佳展示尺寸(以类似
background-size: contain
的形式展示);- 将画布的宽高(非样式)设置为样式宽高的
1/N
;- 绘制图像,绘制的图像宽高为最佳展示尺寸的
1/N
。如此一来,我们实际绘制了一个尺寸仅为最佳尺寸
1/N
的图像,再通过canvas
的N
倍放大又变回了视觉上的最佳尺寸。图像因为走的canvas
绘制,所以放大回最佳尺寸后会保持模糊,从而满足了image-rendering
的匹配需求。注:这里提到的“最佳尺寸”,指的是步骤 2 里“确保完整展示图像”所对应的最佳尺寸,而非图片原生尺寸。
四、代码实现
我们按照上方步骤来书写对应代码,当然我们希望灵活一些,例如上述的
N
可以由用户自定义。另外本章的代码可以在 Github 上获取。4.1 HTML 部分
主要为选择图片的
<input>
控件、画布、方便画布获取图像的<img src="/static/imghw/default1.png" data-src="./assert/0.png" class="lazy" alt="CSS를 사용하여 이미지 모자이크 스타일화를 달성하는 방법을 살펴보겠습니다." >
、供用户自定义缩放倍数的文本框、执行按钮:<input id="file" type="file" accept="image/*" /> <canvas id="canvas"></canvas> <img src="/static/imghw/default1.png" data-src="./assert/0.png" class="lazy" id="img-raw" / alt="CSS를 사용하여 이미지 모자이크 스타일화를 달성하는 방법을 살펴보겠습니다." > <label for="compress-times">压缩倍数:</label> <input id="compress-times" type="number" value="12"> <button>马赛克化</button>로그인 후 복사로그인 후 복사4.2 CSS 部分
我们需要通过样式规定好画布的外观尺寸,并配置
image-rendering: pixelated
特性。另外<img src="/static/imghw/default1.png" data-src="./assert/0.png" class="lazy" alt="CSS를 사용하여 이미지 모자이크 스타일화를 달성하는 방법을 살펴보겠습니다." >
标签只是一个传递用户所选图片到画布的中介,可以直接隐藏:canvas { display: block; border: gray solid 1px; width: 600px; height: 600px; image-rendering: pixelated; } img { display: none; }로그인 후 복사로그인 후 복사4.3 JS 部分
let imgBlobUrl; const file = document.getElementById('file'); const img = document.getElementById('img-raw'); const compressTimes = document.getElementById('compress-times'); const defaultCompressTimes = compressTimes.value | 0; const canvas = document.getElementById('canvas'); const button = document.querySelector('button'); const boundingRect = canvas.getBoundingClientRect(); const ctx = canvas.getContext('2d'); const canvas_w = boundingRect.width; const canvas_h = boundingRect.height; // 以 background-size: contain 形式设置图片尺寸 function matchImgSizeToCanvas(imgElem = img) { let w = imgElem.width; let h = imgElem.height; if (w > canvas_w || h > canvas_h) { let radio = Math.max(h / canvas_h, w / canvas_w); radio = Number(radio.toFixed(2)); imgElem.width = parseInt(w / radio); imgElem.height = parseInt(h / radio); } } // 绘制 1/N 大小的图像,画布宽高属性设为样式宽高的 1/N,从而实现画布内容的 N 倍放大 function run() { let ct = parseInt(compressTimes.value) || defaultCompressTimes; canvas.width = parseInt(canvas_w / ct); canvas.height = parseInt(canvas_h / ct); ctx.drawImage(img, 0, 0, parseInt(img.width / ct), parseInt(img.height / ct)); } function cleanCanvas() { ctx.clearRect(0, 0, canvas_w, canvas_h); } function reset() { img.removeAttribute('width'); img.removeAttribute('height'); cleanCanvas(); matchImgSizeToCanvas(img); run(); } file.addEventListener('change', function (e) { window.URL.revokeObjectURL(imgBlobUrl); const picFile = this.files[0]; imgBlobUrl = window.URL.createObjectURL(picFile); img.onload = function init() { reset(); } img.src = imgBlobUrl; }, false); button.addEventListener('click', reset, false);로그인 후 복사执行效果:
选中文件/点击按钮后,能按压缩倍数得到对应的像素风格艺术照。
五、Mosaic 插件封装
通过上方示例我们学习了如何利用
canvas
特性来设计等尺寸的马赛克效果,现在我们尝试把该功能封装为一个简易插件,可以让页面上的图片列表一键 Mosaicing。插件的实现方案也很简单 —— 用户点击按钮时,往图片容器上插入一个和容器等尺寸的画布(尺寸通过样式设置),再绘制覆盖画布的图像,并缩小画布的宽高属性来放大画布内容:
5.1 插件脚本
/** @file mosaic.js **/ class Mosaic { constructor(url, container, options = {}) { if (typeof container === 'string') { container = document.querySelector(container); } if (!url || !container?.style) { console.error('参数不正确'); } this.url = url; this.options = options; this.container = container; this.init(); } init() { const img = new Image(); const canvas = document.createElement('canvas'); canvas.style.position = 'absolute'; canvas.style.zIndex = 999; canvas.style.imageRendering = 'pixelated'; this.img = img; this.canvas = canvas; this.ctx = canvas.getContext('2d'); const containerBoundingRect = this.container.getBoundingClientRect(); const container_w = containerBoundingRect.width; const container_h = containerBoundingRect.height; // 通过样式初始化画布尺寸为容器尺寸 canvas.style.width = container_w + 'px'; canvas.style.height = container_h + 'px'; img.onload = () => { this.run(container_w, container_h); } img.src = this.url; } run(w, h) { // 缩小倍数,可以由参数传入,默认为 12 const compressTimes = parseInt(this.options.compressTimes) || 12; let compress_w = parseInt(w / compressTimes); let compress_h = parseInt(h / compressTimes); // 修改画布尺寸属性为 1/缩小倍数 this.canvas.width = compress_w; this.canvas.height = compress_h; // 绘制图片覆盖缩小后的画布 this.ctx.drawImage(this.img, 0, 0, compress_w, compress_h); this.container.prepend(this.canvas); this.img = null; } remove() { this.container.removeChild(this.canvas); this.canvas = null; } } export default Mosaic;로그인 후 복사5.2 插件使用页
/** @file plugin-demo.html **/ <head> <style> ul { list-style: none; margin: 0; padding: 0; } li { float: left; line-height: 0; margin: 0 20px 20px 0; } li>img { max-height: 180px; } div { display: block; clear: both; } </style> </head> <body> <ul> <li><img src="/static/imghw/default1.png" data-src="./assert/0.png" class="lazy" / alt="CSS를 사용하여 이미지 모자이크 스타일화를 달성하는 방법을 살펴보겠습니다." ></li> <li><img src="/static/imghw/default1.png" data-src="./assert/1.png" class="lazy" / alt="CSS를 사용하여 이미지 모자이크 스타일화를 달성하는 방법을 살펴보겠습니다." ></li> <li><img src="/static/imghw/default1.png" data-src="./assert/2.png" class="lazy" / alt="CSS를 사용하여 이미지 모자이크 스타일화를 달성하는 방법을 살펴보겠습니다." ></li> <li><img src="/static/imghw/default1.png" data-src="./assert/3.png" class="lazy" / alt="CSS를 사용하여 이미지 모자이크 스타일화를 달성하는 방법을 살펴보겠습니다." ></li> </ul> <div> <button id="generate">铺上马赛克</button> <button id="remove">移除马赛克</button> </div> <script type="module"> import Mosaic from './mosaic.js'; let liElems = document.querySelectorAll('li'); let mosaicList = []; document.querySelector('#generate').onclick = () => { remove(); for (let i = 0; i < liElems.length; i++) { let liElem = liElems[i]; let url = liElem.querySelector('img').src; let mosaic = new Mosaic(url, liElem); mosaicList.push(mosaic); } } function remove() { mosaicList.forEach((mosaic) => { mosaic.remove(); }); mosaicList.length = 0; } document.querySelector('#remove').onclick = remove; </script> </body>로그인 후 복사执行效果:
点击“铺上”或“移除”按钮,可以轻松实现/移除列表上各图片的像素风格化。
六、兼容性
image-rendering
的兼容性可以从 caniuse 上查到,目前覆盖率如下:
影响较大的主要还是在 IE、UC,以及安卓 4.4.4 版本的浏览器,需要酌情考虑是否在产品上使用此 CSS 特性。
以上便是本文全部内容,相关代码可以在 Github 上获取(地址:https://github.com/VaJoy/BlogDemo3/tree/main/220226-pixelated)。
希望能令你有所收获,共勉~
(학습 영상 공유: 웹 프론트엔드 입문 튜토리얼)
위 내용은 CSS를 사용하여 이미지 모자이크 스타일화를 달성하는 방법을 살펴보겠습니다.의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

핫 AI 도구

Undresser.AI Undress
사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover
사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool
무료로 이미지를 벗다

Clothoff.io
AI 옷 제거제

AI Hentai Generator
AI Hentai를 무료로 생성하십시오.

인기 기사

뜨거운 도구

메모장++7.3.1
사용하기 쉬운 무료 코드 편집기

SublimeText3 중국어 버전
중국어 버전, 사용하기 매우 쉽습니다.

스튜디오 13.0.1 보내기
강력한 PHP 통합 개발 환경

드림위버 CS6
시각적 웹 개발 도구

SublimeText3 Mac 버전
신 수준의 코드 편집 소프트웨어(SublimeText3)

뜨거운 주제











Vue.js에서 placeholder 속성은 사용자가 콘텐츠를 입력하지 않을 때 표시되는 입력 요소의 자리 표시자 텍스트를 지정하고 입력 팁이나 예제를 제공하며 양식 접근성을 향상시킵니다. 사용법은 입력 요소에 자리 표시자 속성을 설정하고 CSS를 사용하여 모양을 사용자 정의하는 것입니다. 모범 사례에는 입력과 관련성, 짧고 명확함, 기본 텍스트 방지, 접근성 고려 등이 포함됩니다.

스팬 태그는 텍스트에 스타일, 속성 또는 동작을 추가할 수 있습니다. 색상 및 글꼴 크기와 같은 스타일을 추가하는 데 사용됩니다. ID, 클래스 등의 속성을 설정합니다. 클릭, 호버 등과 같은 관련 동작 추가 처리 또는 인용을 위해 텍스트를 표시합니다.

CSS의 REM은 루트 요소(html)의 글꼴 크기에 상대적인 단위입니다. 여기에는 다음과 같은 특징이 있습니다. 루트 요소의 글꼴 크기를 기준으로 하며 상위 요소의 영향을 받지 않습니다. 루트 요소의 글꼴 크기가 변경되면 REM을 사용하는 요소가 그에 따라 조정됩니다. 모든 CSS 속성과 함께 사용할 수 있습니다. REM 사용의 장점은 다음과 같습니다. 반응성: 다양한 장치 및 화면 크기에서 텍스트를 읽을 수 있도록 유지합니다. 일관성: 웹사이트 전체에서 글꼴 크기가 일관되게 유지되어야 합니다. 확장성: 루트 요소 글꼴 크기를 조정하여 전역 글꼴 크기를 쉽게 변경할 수 있습니다.

Vue에 이미지를 도입하는 방법에는 URL, 필수 함수, 정적 파일, v-bind 지시어 및 CSS 배경 이미지 등 5가지 방법이 있습니다. 동적 이미지는 Vue의 계산된 속성이나 리스너에서 처리할 수 있으며, 번들 도구를 사용하여 이미지 로딩을 최적화할 수 있습니다. 경로가 올바른지 확인하세요. 그렇지 않으면 로딩 오류가 나타납니다.

SPAN 태그는 스타일, 색상, 글꼴 크기 등의 속성을 적용하여 텍스트를 강조 표시하는 데 사용되는 인라인 HTML 태그입니다. 여기에는 텍스트 강조, 텍스트 그룹화, 호버 효과 추가 및 동적인 콘텐츠 업데이트가 포함됩니다. 강조하려는 텍스트 주위에 <span>, </span> 태그를 배치하여 사용하며, CSS 스타일링이나 JavaScript를 통해 조작됩니다. SPAN 태그의 이점에는 의미의 명확성, 스타일 유연성 및 유지 관리 용이성이 포함됩니다.

JavaScript에서 프롬프트() 메서드를 사용할 때 다음 세 가지 방법을 통해 줄 바꿈을 수행할 수 있습니다. 1. 줄을 끊으려는 위치에 "\n" 문자를 삽입합니다. 2. 줄 바꿈 문자를 사용합니다. 프롬프트 텍스트; 3. CSS의 "white" -space: pre" 스타일을 사용하여 줄바꿈을 강제합니다.

노드는 HTML 요소를 나타내는 JavaScript DOM의 엔터티입니다. 이는 페이지의 특정 요소를 나타내며 해당 요소에 액세스하고 조작하는 데 사용될 수 있습니다. 일반적인 노드 유형에는 요소 노드, 텍스트 노드, 주석 노드 및 문서 노드가 포함됩니다. getElementById()와 같은 DOM 메서드를 통해 노드에 액세스하고 속성 수정, 하위 노드 추가/제거, 노드 삽입/교체, 노드 복제 등의 작업을 수행할 수 있습니다. 노드 순회는 DOM 구조 내에서 탐색하는 데 도움이 됩니다. 노드는 페이지 콘텐츠, 이벤트 처리, 애니메이션 및 데이터 바인딩을 동적으로 생성하는 데 유용합니다.

브라우저 플러그인은 일반적으로 다음 언어로 작성됩니다. 프런트엔드 언어: JavaScript, HTML, CSS 백엔드 언어: C++, Rust, WebAssembly 기타 언어: Python, Java
