Nodejs下使用gm圆形裁剪并合成图片的示例


Posted in NodeJs onFebruary 22, 2018

说到Nodejs下的图片处理可能第一想到就是gm,gm底层可以是GraphicsMagic(其实也是gm的由来),也可以是ImageMagick(其实GraphicsMagic本身也是从ImageMagic分割而来,现在独立了)。虽然这两个工具本身都不是js实现,所以需要额外安装,不过此工具非常常见,可能已经预装在linux系统下,而且安装也很方便,所以不用因为看到是“第三方”就放弃。虽然说这两个软件都只是底层,无需关心,可笔者在实践中发现必须得用GraphicsMagic,所以这里就只介绍GraphicsMagics的安装与使用。

GaphicsMagic 安装

GraphicsMagic 官网是: http://www.graphicsmagick.org/

官网和网上大多数教程都是教如何编译,可个人觉得可以直接通过软件库安装,比如

apt-get install graphicsmagic

如果要学习用命令行的方式使用GraphicsMagic可以看这里:https://3water.com/LINUXjishu/120332.html

Nodejs下的gm安装

gm是一个node库,所以可用npm安装

npm install gm

官方文档: http://aheckmann.github.io/gm/

圆形剪裁原理

gm是对GraphicsMagic的封装,所以理论上GraphicsMagic有的功能都能通过gm以接口的形式实现。gm本身不支持圆形剪裁(至少笔者不知如何实现),同样意味着其底层也不直接支持。

gm比较常用的功能是:缩放、方形裁剪、格式转换。

所以本教程的圆形裁剪的核心是 借助SVG ,通过svg构建一个圆形的图片,然后通过gm转化为png,即利用svg变换图片格式。

SVG是可以实现圆形图片的裁剪的,网上查到有两种方式实现圆形裁剪

1、通过clip-path

定义一个圆形的路径,然后在图片的style中设置clip-path,也就是通过这个这样实现图片裁剪,理论上是真正意义上的“裁剪”

<svg>
  <defs>
    <clipPathid="clipPath">
      <circlecx="5"cy="5"r="5"/>
    </clipPath>
  </defs>
  <imagestyle="clip-path: url(#clipPath);"href="{{icon_img}}" rel="external nofollow" rel="external nofollow" x="0"y="0"width="10"height="10"/> 
</svg>

如果用clip-path可以看这个教程

可是这样的配置在浏览器上看没有丝毫问题,但是发现通过gm转化为png后,style没有任何效果,还是方形的。

2、通过circle标签

<svg>
  <defs>
    <patternpatternUnits="userSpaceOnUse"id="raduisImage"x="0"y="0"width="10"height="10">
      <imagehref="{{icon_img}}" rel="external nofollow" rel="external nofollow" x="0"y="0"width="10"height="10"/>
    </pattern>
  </defs>
  <circlecx="5"cy="5"r="5"fill="url(#raduisImage)"></circle>
</svg>

先定义一个图案,也就是原来的图片,然后创建个圆形,并用刚刚定义的图案填充在这个圆形里面即可。

合成图片原理

懂的上述剪裁的原理,合成就变得简单了。直接把想要合成的图片以svg的方式拼凑在一起即可。虽然gm本身支持图片合成,使用compose或者mosaic (详见这个 教程 )不过感觉不如svg更加明了。

注意笔者尝试通过svg加上文字,不过发现中文字无法被识别,所以仍然只能通过gm添加,添加时需要设置字体(详见下一章代码实现)

如果要在一个大图里嵌入两张圆形的图片,则需要设置两个pattern,这时有个经验:

  1. pattern的x和y设置为0,0
  2. pattern的width和height设置的和 画布 一样
  3. image的x,y设置为其 “实际位置” ,也就是对应 circle 的 cx-r 以及 cy-r ,剪 r 是因为cx和cy指的是圆形中心,而x,y是图形的左上角位置。

代码实现

const gm = require('gm')
const fs = require('fs')
let templateSVG = "/path/to/original.svg"
let outputSVG = "/path/to/repalced.svg"
let input = "/path/to/icon.png"
let font = "/path/to/font.ttf"
let fontColor = "white"
let fontSize = 10

fs.readFile(templateSVG,'utf-8',function(err,data){
  if (err) throw err
  var d = data.replace('{{icon_img}}',input)
  fs.writeFile(outputSVG,d,function(err){
    if (err) throw err
    gm(outputSVG)
    .font(font)
    .fill(fontColor)
    .fontSize(fontSize)
    .drawText(textPosition[0], textPosition[1], text)//
    .write(output,function(err){
      if(err) cb(err)
      // next
    })
  })
})

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

NodeJs 相关文章推荐
Nodejs+express+html5 实现拖拽上传
Aug 08 NodeJs
轻松创建nodejs服务器(10):处理上传图片
Dec 18 NodeJs
Nodejs关于gzip/deflate压缩详解
Mar 04 NodeJs
Nodejs express框架一个工程中同时使用ejs模版和jade模版
Dec 28 NodeJs
NodeJS与HTML5相结合实现拖拽多个文件上传到服务器的实现方法
Jul 26 NodeJs
NodeJs的优势和适合开发的程序
Aug 14 NodeJs
nodejs个人博客开发第二步 入口文件
Apr 12 NodeJs
nodejs个人博客开发第三步 载入页面
Apr 12 NodeJs
nodejs Assert中equal(),strictEqual(),deepEqual(),strictDeepEqual()比较
Sep 18 NodeJs
独立部署小程序基于nodejs的服务器过程详解
Jun 24 NodeJs
nodejs环境使用Typeorm连接查询Oracle数据
Dec 05 NodeJs
Nodejs + sequelize 实现增删改查操作
Nov 07 NodeJs
nodejs微信扫码支付功能实现
Feb 17 #NodeJs
nodejs+express搭建多人聊天室步骤
Feb 12 #NodeJs
nodeJs实现基于连接池连接mysql的方法示例
Feb 10 #NodeJs
NodeJS简单实现WebSocket功能示例
Feb 10 #NodeJs
nodejs使用redis作为缓存介质实现的封装缓存类示例
Feb 07 #NodeJs
nodejs中Express与Koa2对比分析
Feb 06 #NodeJs
nodejs实现的连接MySQL数据库功能示例
Jan 25 #NodeJs
You might like
php 表单验证实现代码
2009/03/10 PHP
PHP 面向对象程序设计(oop)学习笔记 (二) - 静态变量的属性和方法及延迟绑定
2014/06/12 PHP
php检查字符串中是否有外链的方法
2015/07/29 PHP
Zend Framework上传文件重命名的实现方法
2016/11/25 PHP
Yii框架操作cookie与session的方法实例详解
2019/09/04 PHP
简单JS代码压缩器
2006/10/12 Javascript
JS获取scrollHeight问题想到的标准问题
2007/05/27 Javascript
设置下载不需要倒计时cookie(倒计时代码)
2008/11/19 Javascript
js字符串转换成数字与数字转换成字符串的实现方法
2014/01/08 Javascript
JavaScript函数的一些注意要点小结及js匿名函数
2015/11/10 Javascript
谈谈JavaScript类型系统之Math
2016/01/06 Javascript
javascript实现仿百度图片的瀑布流加载效果
2016/04/20 Javascript
JS提示:Uncaught SyntaxError:Unexpected token ) 错误的解决方法
2016/08/19 Javascript
解决同一页面中两个iframe互相调用jquery,js函数的方法
2016/12/12 Javascript
jQuery的中 is(':visible') 解析及用法(必看)
2017/02/12 Javascript
JS判断键盘是否按的回车键并触发指定按钮点击操作的方法
2017/02/13 Javascript
Angular.js与node.js项目里用cookie校验账户登录详解
2017/02/22 Javascript
yarn的使用与升级Node.js的方法详解
2017/06/04 Javascript
用原生 JS 实现 innerHTML 功能实例详解
2019/04/03 Javascript
Vue实现固定定位图标滑动隐藏效果
2019/05/30 Javascript
你了解vue3.0响应式数据怎么实现吗
2019/06/07 Javascript
bootstrapValidator表单校验、更改状态、新增、移除校验字段的实例代码
2020/05/19 Javascript
[05:20]卡尔工作室_DOTA2新手教学_DOTA2超强新手功能
2013/04/22 DOTA
深入学习Python中的上下文管理器与else块
2017/08/27 Python
Python数据可视化实现正态分布(高斯分布)
2019/08/21 Python
Django中从mysql数据库中获取数据传到echarts方式
2020/04/07 Python
Pandas将列表(List)转换为数据框(Dataframe)
2020/04/24 Python
使用SQLAlchemy操作数据库表过程解析
2020/06/10 Python
基于python图书馆管理系统设计实例详解
2020/08/05 Python
详解Pycharm安装及Django安装配置指南
2020/09/15 Python
全面总结使用CSS实现水平垂直居中效果的方法
2016/03/10 HTML / CSS
求职自荐信怎么写
2014/03/06 职场文书
幼儿园老师个人总结
2015/02/28 职场文书
2015年超市工作总结
2015/04/09 职场文书
交通事故赔偿起诉书
2015/05/20 职场文书
spring boot项目application.properties文件存放及使用介绍
2021/06/30 Java/Android