图片处理不用愁,给你十个小帮手

本文阿宝哥会为小伙伴们隆重介绍用于图片处理的十个 “小帮手”,他们各个身怀绝技,拥有模糊、压缩、裁剪、旋转、合成、比对等技能。相信认识他们之后,你将能够轻松应对大多数的图片处理场景。

不过在介绍 “小帮手” 前,阿宝哥会先介绍一些图片相关的基础知识。此外,为了让小伙伴们能够学习更多图片相关的知识,阿宝哥精心准备了 “阿宝哥有话说” 章节。该章节你将会学到以下知识:

  • 如何区分图片的类型(非文件后缀名);
  • 如何获取图片的尺寸(非右键查看图片信息);
  • 如何预览本地图片(非图片阅读器);
  • 如何实现图片压缩(非图片压缩工具);
  • 如何操作位图像素数据(非 PS 等图片处理软件);
  • 如何实现图片隐写(非肉眼可见)。

十个图片处理 “小帮手” 已经已经迫不及待想与你见面,还在犹豫什么?赶紧出发吧!

一、基础知识

1.1 位图

位图图像(bitmap),亦称为点阵图像或栅格图像,是由称作像素(图片元素)的单个点组成的。 这些点可以进行不同的排列和染色以构成图样。当放大位图时,可以看见赖以构成整个图像的无数单个方块。扩大位图尺寸的效果是增大单个像素,从而使线条和形状显得参差不齐。

用数码相机拍摄的照片、扫描仪扫描的图片以及计算机截屏图等都属于位图。 位图的特点是可以表现色彩的变化和颜色的细微过渡,产生逼真的效果,缺点是在保存时需要记录每一个像素的位置和颜色值,占用较大的存储空间。常用的位图处理软件有 Photoshop、Painter 和 Windows 系统自带的画图工具等。

分辨率是位图不可逾越的壁垒,在对位图进行缩放、旋转等操作时,无法生产新的像素,因此会放大原有的像素填补空白,这样会让图片显得不清晰。

(图片来源:https://zh.wikipedia.org/wiki/%E4%BD%8D%E5%9B%BE)

图中的小方块被称为像素,这些小方块都有一个明确的位置和被分配的色彩数值,小方格颜色和位置就决定该图像所呈现出来的样子。

可以将像素视为整个图像中不可分割的单位或者是元素。不可分割的意思是它不能够再切割成更小单位抑或是元素,它是以一个单一颜色的小格存在。 每一个点阵图像包含了一定量的像素,这些像素决定图像在屏幕上所呈现的大小。

1.2 矢量图

所谓矢量图,就是使用直线和曲线来描述的图形,构成这些图形的元素是一些点、线、矩形、多边形、圆和弧线等,它们都是通过数学公式计算获得的,具有编辑后不失真的特点。 例如一幅画的矢量图形实际上是由线段形成外框轮廓,由外框的颜色以及外框所封闭的颜色决定画显示出的颜色。

矢量图以几何图形居多,图形可以无限放大,不变色、不模糊。 常用于图案、标志、VI、文字等设计。常用软件有:CorelDraw、Illustrator、Freehand、XARA、CAD 等。

这里我们以 Web 开发者比较熟悉的 SVGScalable Vector Graphics —— 可缩放矢量图形)为例,来了解一下 SVG 的结构:

可缩放矢量图形(英语:Scalable Vector Graphics,SVG)是一种基于可扩展标记语言(XML),用于描述二维矢量图形的图形格式。SVG 由 W3C 制定,是一个开放标准。

SVG 主要支持以下几种显示对象:

  • 矢量显示对象,基本矢量显示对象包括矩形、圆、椭圆、多边形、直线、任意曲线等;
  • 嵌入式外部图像,包括 PNG、JPEG、SVG 等;
  • 文字对象。

了解完位图与矢量图的区别,下面我们来介绍一下位图的数学表示。

1.3 位图的数学表示

位图的像素都分配有特定的位置和颜色值。每个像素的颜色信息由 RGB 组合或者灰度值表示。

根据位深度,可将位图分为1、4、8、16、24 及 32 位图像等。每个像素使用的信息位数越多,可用的颜色就越多,颜色表现就越逼真,相应的数据量越大。

1.3.1 二值图像

位深度为 1 的像素位图只有两个可能的值(黑色和白色),所以又称为二值图像。二值图像的像素点只有黑白两种情况,因此每个像素点可以由 0 和 1 来表示。

比如一张 4 * 4 二值图像:

1 1 0 1
1 1 0 1
1 0 0 0
1 0 1 0

1.3.2 RGB 图像

RGB 图像由三个颜色通道组成,其中 RGB 代表红、绿、蓝三个通道的颜色。8 位/通道的 RGB 图像中的每个通道有 256 个可能的值,这意味着该图像有 1600 万个以上可能的颜色值。有时将带有 8 位/通道(bpc)的 RGB 图像称作 24 位图像(8 位 x 3 通道 = 24 位数据/像素)。通常将使用 24 位 RGB 组合数据位表示的的位图称为真彩色位图。

RGB 彩色图像可由三种矩阵表示:一种代表像素中红色的强度,一种代表绿色,另一种代表蓝色。

(图片来源:https://freecontent.manning.com/the-computer-vision-pipeline-part-2-input-images/)

图像处理的本质实际上就是对这些像素矩阵进行计算。 其实位图中的图像类型,除了二值图像和 RGB 图像之外,还有灰度图像、索引图像和 YUV 图像。这里我们不做过多介绍,感兴趣的小伙伴,可以自行查阅相关资料。

二、图片处理库

2.1 AlloyImage

基于 HTML 5 的专业级图像处理开源引擎。

https://github.com/AlloyTeam/AlloyImage

AlloyImage 基于 HTML5 技术的专业图像处理库,来自腾讯 AlloyTeam 团队。它拥有以下功能特性:

  • 基于多图层操作 —— 一个图层的处理不影响其他图层;
  • 与 PS 对应的 17 种图层混合模式 —— 便于 PS 处理教程的无缝迁移;
  • 多种基本滤镜处理效果 —— 基本滤镜不断丰富、可扩展;
  • 基本的图像调节功能 —— 色相、饱和度、对比度、亮度、曲线等;
  • 简单快捷的 API —— 链式处理、API 简洁易用、传参灵活;
  • 多种组合效果封装 —— 一句代码轻松实现一种风格;
  • 接口一致的单、多线程支持 —— 单、多线程切换无需更改一行代码,多线程保持快捷 API 特性。

对于该库 AlloyTeam 团队建议的使用场景如下:

  • 桌面软件客户端内嵌网页运行方式 >>> 打包 Webkit 内核:用户较大头像上传风格处理、用户相册风格处理(处理时间平均 < 1s);
  • Win8 Metro 应用 >>> 用户上传头像,比较小的图片风格处理后上传(Win8 下 IE 10 支持多线程);
  • Mobile APP >>> Andriod 平台、iOS 平台小图风格 Web 处理的需求,如 PhoneGap 应用,在线头像上传时的风格处理、Mobile Web 端分享图片时风格处理等。

使用示例

// $AI或AlloyImage初始化一个AlloyImage对象
var ps = $AI(img, 600).save('jpg', 0.6);

// save将合成图片保存成base64格式字符串
var string = AlloyImage(img).save('jpg', 0.8);

// saveFile将合成图片下载到本地
img.onclick = function(){
   
  AlloyImage(this).saveFile('处理后图像.jpg', 0.8);
}

在线示例

http://alloyteam.github.io/AlloyImage/

(图片来源:http://alloyteam.github.io/AlloyImage/)

2.2 blurify

blurify.js is a tiny(~2kb) library to blurred pictures, support graceful downgrade from css mode to canvas mode.

https://github.com/JustClear/blurify

blurify.js 是一个用于图片模糊,很小的 JavaScript 库(约 2 kb),并支持从 CSS 模式到 Canvas 模式的优雅降级。该插件支持三种模式:

  • css 模式:使用 filter 属性,默认模式;
  • canvas 模式:使用 canvas 导出 base64;
  • auto 模式:优先使用 css 模式,否则自动切换到 canvas 模式。

使用示例

import blurify from 'blurify';

new blurify({
   
    images: document.querySelectorAll('.blurify'),
    blur: 6,
    mode: 'css',
});

// or in shorthand

blurify(6, document.querySelectorAll('.blurify'));

在线示例

https://justclear.github.io/blurify/

(图片来源:https://justclear.github.io/blurify/)

看到这里是不是有些小伙伴觉得只是模糊处理而已,觉得不过瘾,能不能来点更酷的。嘿嘿,有求必应!阿宝哥立马来个 “酷炫叼” 的库 —— midori,该库用于为背景图创建动画,使用 three.js 编写并使用 WebGL。本来是想给个演示动图,无奈单个 Gif 太大,只能放个体验地址,感兴趣的小伙伴自行体验一下。

midori 示例地址:https://aeroheim.github.io/midori/

2.3 cropperjs

JavaScript image cropper.

https://github.com/fengyuanchen/cropperjs

Cropper.js 是一款非常强大却又简单的图片裁剪工具,它可以进行非常灵活的配置,支持手机端使用,支持包括 IE9 以上的现代浏览器。它可以用于满足诸如裁剪头像上传、商品图片编辑之类的需求。

Cropper.js 支持以下特性:

  • 支持 39 个配置选项;
  • 支持 27 个方法;
  • 支持 6 种事件;
  • 支持 touch(移动端);
  • 支持缩放、旋转和翻转;
  • 支持在画布上裁剪;
  • 支持在浏览器端通过画布裁剪图像;
  • 支持处理 Exif 方向信息;
  • 跨浏览器支持。

可交换图像文件格式(英语:Exchangeable image file format,官方简称 Exif),是专门为数码相机的照片设定的文件格式,可以记录数码照片的属性信息和拍摄数据。Exif 可以附加于 JPEG、TIFF、RIFF 等文件之中,为其增加有关数码相机拍摄信息的内容和索引图或图像处理软件的版本信息。

Exif 信息以 0xFFE1 作为开头标记,后两个字节表示 Exif 信息的长度。所以 Exif 信息最大为 64 kB,而内部采用 TIFF 格式。

使用示例

// import 'cropperjs/dist/cropper.css';
import Cropper from 'cropperjs';

const image = document.getElementById('image');
const cropper = new Cropper(image, {
   
  aspectRatio: 16 / 9,
  crop(event) {
   
    console.log(event.detail.x);
    console.log(event.detail.y);
    console.log(event.detail.width);
    console.log(event.detail.height);
    console.log(event.detail.rotate);
    console.log(event.detail.scaleX);
    console.log(event.detail.scaleY);
  },
});

在线示例

https://fengyuanchen.github.io/cropperjs/

2.4 compressorjs

JavaScript image compressor.

https://github.com/fengyuanchen/compressorjs

compressorjs 是 JavaScript 图像压缩器。使用浏览器原生的 canvas.toBlob API 进行压缩工作,这意味着它是有损压缩。通常的使用场景是,在浏览器端图片上传之前对其进行预压缩。

在浏览器端要实现图片压缩,除了使用 canvas.toBlob API 之外,还可以使用 Canvas 提供的另一个 API,即 toDataURL API,它接收 typeencoderOptions 两个可选参数。

其中 type 表示图片格式,默认为 image/png。而 encoderOptions 用于表示图片的质量,在指定图片格式为 image/jpegimage/webp 的情况下,可以从 0 到 1 的区间内选择图片的质量。如果超出取值范围,将会使用默认值 0.92,其他参数会被忽略。

相比 canvas.toDataURL API 来说,canvas.toBlob API 是异步的,因此多了个 callback 参数,这个 callback 回调方法默认的第一个参数就是转换好的 blob 文件信息。canvas.toBlob 的签名如下:

canvas.toBlob(callback, mimeType, qualityArgument)

使用示例

import axios from 'axios';
import Compressor from 'compressorjs';

// <input type="file" id="file" accept="image/*">
document.getElementById('file').addEventListener('change', (e) => {
   
  const file = e.target.files[0];

  if (!file) {
   
    return;
  }
  new Compressor(file, {
   
    quality: 0.6,
    success(result) {
   
      const formData = new FormData();
      // The third parameter is required for server
      formData.append('file', result, result.name);

      // Send the compressed image file to server with XMLHttpRequest.
      axios.post('/path/to/upload', formData).then(() => {
   
        console.log('Upload success');
      });
    },
    error(err) {
   
      console.log(err.message);
    },
  }
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值