返回顶部
首页 > 资讯 > 前端开发 > JavaScript >如何使用CSS实现图片马赛克风格化效果
  • 670
分享到

如何使用CSS实现图片马赛克风格化效果

2024-04-02 19:04:59 670人浏览 独家记忆
摘要

这篇文章主要介绍如何使用CSS实现图片马赛克风格化效果,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!一、image-rendering 介绍CSS 中有一个有趣的特性叫 image-

这篇文章主要介绍如何使用CSS实现图片马赛克风格化效果,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!

一、image-rendering 介绍

CSS 中有一个有趣的特性叫 image-rendering,它可以通过算法来更好地显示被缩放的图片。

假设我们有一张尺寸较小的二维码截图(下方左,仅为示意图不可扫),将其放大 10 倍后图像会被虚化(下方右):

如何使用CSS实现图片马赛克风格化效果

这时给放大的图片加上 image-rendering: pixelated 的特性,CSS 会通过算法将其像素化展示,使其图像轮廓具有更锐利的边缘:

如何使用CSS实现图片马赛克风格化效果

该特性非常适合应用在色彩单一、轮廓分明、需要被放大的图片上,可以营造出一种伪矢量的既视感(减少放大后的失真)。

对于色彩丰富、细节较多的照片,image-rendering: pixelated 使用后会营造出一种马赛克的外观:

如何使用CSS实现图片马赛克风格化效果

这离本文标题所希望实现的马赛克效果还有段距离 —— 目前图片需要被放大后才能显示出效果,而我们希望能在保有原图尺寸的基础上,给图片覆盖等尺寸马赛克。

然而 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 的画布,但它的内容实际被拉伸了(宽被拉伸了 2 倍,高被拉伸了 4 倍)。

如何使用CSS实现图片马赛克风格化效果

注:左边为画布,右边为原图

这也是 canvas 作为可替换元素的一个特性 —— CSS 无法修改其内容。试想一下,如果 CSS 可以动态地修改 canvas 内容的尺寸,意味着 canvas 的内容会被裁剪掉一部分,或者多出来一部分空白区域,这显然是不可取的。所以 canvas 在保留内容完整的前提下,整体伸缩到样式规定尺寸,是合理的浏览器行为。

利用 canvas 的这个特性,我们可以这样来实现等尺寸马赛克:

  • 创建一个画布,通过样式规定好其宽高,并设置 image-rendering: pixelated 特性;

  • 计算图片最佳展示尺寸(以类似 background-size: contain 的形式展示);

  • 将画布的宽高(非样式)设置为样式宽高的 1/N

  • 绘制图像,绘制的图像宽高为最佳展示尺寸的 1/N

如此一来,我们实际绘制了一个尺寸仅为最佳尺寸 1/N 的图像,再通过 canvasN 倍放大又变回了视觉上的最佳尺寸。图像因为走的 canvas 绘制,所以放大回最佳尺寸后会保持模糊,从而满足了 image-rendering 的匹配需求。

注:这里提到的“最佳尺寸”,指的是步骤 2 里“确保完整展示图像”所对应的最佳尺寸,而非图片原生尺寸。

四、代码实现

我们按照上方步骤来书写对应代码,当然我们希望灵活一些,例如上述的 N 可以由用户自定义。另外本章的代码可以在 GitHub 上获取。

4.1 HTML 部分

主要为选择图片的 <input> 控件、画布、方便画布获取图像的 <img>、供用户自定义缩放倍数的文本框、执行按钮:

  <input id="file" type="file" accept="image

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 插件使用页


<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="./assert/0.png" /></li>
    <li><img src="./assert/1.png" /></li>
    <li><img src="./assert/2.png" /></li>
    <li><img src="./assert/3.png" /></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>

执行效果:

如何使用CSS实现图片马赛克风格化效果

点击“铺上”或“移除”按钮,可以轻松实现/移除列表上各图片的像素风格化。

六、兼容性

image-rendering 的兼容性可以从 caniuse 上查到,目前覆盖率如下:

如何使用CSS实现图片马赛克风格化效果

以上是“如何使用CSS实现图片马赛克风格化效果”这篇文章的所有内容,感谢各位的阅读!希望分享的内容对大家有帮助,更多相关知识,欢迎关注编程网JavaScript频道!

--结束END--

本文标题: 如何使用CSS实现图片马赛克风格化效果

本文链接: https://lsjlt.com/news/89510.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • 如何使用CSS实现图片马赛克风格化效果
    这篇文章主要介绍如何使用CSS实现图片马赛克风格化效果,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!一、image-rendering 介绍CSS 中有一个有趣的特性叫 image-...
    99+
    2024-04-02
  • JavaCV如何实现照片马赛克效果
    小编给大家分享一下JavaCV如何实现照片马赛克效果,希望大家阅读完这篇文章之后都有所收获,下面让我们一起去探讨吧!准备工作我们先引入 JavaCV 的依赖库  <dependency>  ...
    99+
    2023-06-28
  • 怎么利用SVG实现图片马赛克效果
    这篇文章主要讲解了“怎么利用SVG实现图片马赛克效果”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“怎么利用SVG实现图片马赛克效果”吧!何为 image-r...
    99+
    2024-04-02
  • JavaCV实现照片马赛克效果
    目录前言准备工作代码实现完整代码前言 青空最近在逛一些社区的时候发现了有很多图片是像素图,感觉挺好玩的。正巧最近自己在学习JavaCV,所以在这里给大家演示一下如何使用JavaCV来...
    99+
    2024-04-02
  • 使用canvas怎么实现一个图片马赛克效果
    本篇文章为大家展示了使用canvas怎么实现一个图片马赛克效果,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。1. 原生canvas实现用到的API1) getContext(contextID) -...
    99+
    2023-06-09
  • Opencv 马赛克和毛玻璃效果与图片融合的实现
    目录1.马赛克效果2. 毛玻璃效果3. 图片的融合算法实现1.马赛克效果 马赛克的基本原理就是,用某一个区域的某一个像素点替代这个区域所有的像素点,从而导致图片出现模糊的效果,如下...
    99+
    2024-04-02
  • Python如何实现多张图片合成一张马赛克图片
    这篇文章将为大家详细讲解有关Python如何实现多张图片合成一张马赛克图片,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。图片素材4K高清原图开发环境Python 3.6Pycharm实现代码先导入所需模块...
    99+
    2023-06-22
  • 怎么实现Opencv马赛克和毛玻璃效果与图片融合
    这篇文章主要介绍“怎么实现Opencv马赛克和毛玻璃效果与图片融合”,在日常操作中,相信很多人在怎么实现Opencv马赛克和毛玻璃效果与图片融合问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”怎么实现Openc...
    99+
    2023-06-25
  • C++实现将图片转换为马赛克效果的示例代码
    这个程序将图片转换为马赛克效果。 算法原理:求出每个小方块内所有像素的颜色平均值,然后用来设置为该小方块的颜色。依次处理每个小方块,即可实现马赛克效果。 完整代码如下 // 程序名称...
    99+
    2023-01-14
    C++图片转马赛克 C++ 图片 马赛克
  • 如何使用CSS实现图片走马灯动态效果
    小编给大家分享一下如何使用CSS实现图片走马灯动态效果,希望大家阅读完这篇文章之后都有所收获,下面让我们一起去探讨吧!由于项目需要实现一个图片的走马灯效果。查看了大部份通用vue的组件库,比较少看到这类组件...
    99+
    2024-04-02
  • 如何使用CSS实现图片翻转效果
    在现代网站设计和开发中,图片翻转效果已经成为了一个非常流行和常见的设计元素。通过这种效果,用户可以更加直观地感受到网站的活力和动态感。在本文中,我们将重点讨论如何使用CSS实现这种图片翻转效果。首先,我们需要明确一下CSS3中提供了两种方式...
    99+
    2023-05-14
  • 如何使用css实现图片的滑动效果
    小编给大家分享一下如何使用css实现图片的滑动效果,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!   <!DOCTYPE...
    99+
    2024-04-02
  • 如何使用CSS实现图片的缩放效果
    如何使用CSS实现图片的缩放效果在网页设计中,图片的缩放效果是常见的需求之一。通过CSS的相关属性和技巧,我们可以轻松地实现图片的缩放效果。下面,将为大家详细介绍如何使用CSS来实现图片的缩放效果,并给出具体的代码示例。使用transfor...
    99+
    2023-11-21
    图片缩放 CSS缩放 CSS图片效果
  • 如何使用CSS实现图片的旋转效果
    如何使用CSS实现图片的旋转效果CSS(Cascading Style Sheets)是一种用于设置网页样式和布局的标记语言。通过CSS,我们可以实现许多吸引人的网页效果,其中包括图片的旋转效果。在本文中,我们将讨论如何使用CSS来实现图片...
    99+
    2023-11-21
    CSS 图片 旋转
  • 基于Html5 canvas如何实现裁剪图片和马赛克功能
    这篇文章主要介绍了基于Html5 canvas如何实现裁剪图片和马赛克功能,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。1.核心功能  此组件功能包含:    图片裁剪(裁剪...
    99+
    2023-06-09
  • css如何实现图片选中效果
    这篇文章主要介绍css如何实现图片选中效果,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!css实现图片选中效果.demo{width:114px;height:114px;position:relative;}&nb...
    99+
    2023-06-27
  • 如何利用CSS实现紫罗兰风格导航条效果
    本篇内容主要讲解“如何利用CSS实现紫罗兰风格导航条效果”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“如何利用CSS实现紫罗兰风格导航条效果”吧!这是一款紫罗兰...
    99+
    2024-04-02
  • CSS如何实现图片高亮光弧效果
    这篇文章主要介绍了CSS如何实现图片高亮光弧效果,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。 CSS3实现的一个高亮光弧效果,当鼠标ho...
    99+
    2024-04-02
  • css如何实现图片边缘模糊效果
    本篇内容介绍了“css如何实现图片边缘模糊效果”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成! ...
    99+
    2024-04-02
  • CSS如何实现网格效果
    这篇文章主要介绍“CSS如何实现网格效果”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“CSS如何实现网格效果”文章能帮助大家解决问题。   CSS   .gri...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作