Skip to content
0

Graph

图像相关的包

pdf2image ---> pdf 转为图片

将 pdf 转为图片的库

import { fromPath } from "pdf2pic";

const options = {
  density: 100,
  saveFilename: "untitled",
  savePath: "./images",
  format: "png",
  width: 600,
  height: 600
};
const convert = fromPath("/path/to/pdf/sample.pdf", options);
const pageToConvertAsImage = 1;

convert(pageToConvertAsImage, { responseType: "image" })
  .then((resolve) => {
    console.log("Page 1 is now converted as image");

    return resolve;
  });

pixijs ---> WebGL 2D

import { Application, Sprite, Assets } from 'pixi.js';

// The application will create a renderer using WebGL, if possible,
// with a fallback to a canvas render. It will also setup the ticker
// and the root stage PIXI.Container
const app = new Application();

vis-network ---> 创建网络视图

Case 参考 antfu 的项目:https://yak.antfu.me

import { DataSet } from 'vis-data'
import { Network } from 'vis-network'

var nodes = new DataSet([
  { id: 1, label: "Node 1" },
  { id: 2, label: "Node 2" },
  { id: 3, label: "Node 3" },
  { id: 4, label: "Node 4" },
  { id: 5, label: "Node 5" },
]);

// create an array with edges
var edges = new DataSet([
  { from: 1, to: 3 },
  { from: 1, to: 2 },
  { from: 2, to: 4 },
  { from: 2, to: 5 },
  { from: 3, to: 3 },
]);

// create a network
var container = document.getElementById("mynetwork");
var data = {
  nodes: nodes,
  edges: edges,
};
var options = {};
var network = new Network(container, data, options);

blurhash ---> 图片模糊

显示一张模糊后的 canvas

使用方式为例如后端除了返回图片的 URL,还需要返回一个由 blurhash 为图片生成的简短字符串

前端根据这个字符串渲染一个 canvas, 用来优化图片加载时的体验

import { decode } from "blurhash";

const pixels = decode("LEHV6nWB2yk8pyo0adR*.7kCMdnj", 32, 32);

const canvas = document.createElement("canvas");
const ctx = canvas.getContext("2d");
const imageData = ctx.createImageData(width, height);
imageData.data.set(pixels);
ctx.putImageData(imageData, 0, 0);
document.body.append(canvas);

pngjs ---> 在浏览器和 NodeJs 处理 png

import { PNG } from 'pngjs/browser';

fs.createReadStream("in.png")
  .pipe(
    new PNG({
      filterType: 4,
    })
  )
  .on("parsed", function () {
    for (var y = 0; y < this.height; y++) {
      for (var x = 0; x < this.width; x++) {
        var idx = (this.width * y + x) << 2;

        // invert color
        this.data[idx] = 255 - this.data[idx];
        this.data[idx + 1] = 255 - this.data[idx + 1];
        this.data[idx + 2] = 255 - this.data[idx + 2];

        // and reduce opacity
        this.data[idx + 3] = this.data[idx + 3] >> 1;
      }
    }

    this.pack().pipe(fs.createWriteStream("out.png"));
  });

penrose ---> 通过普通文本生成图表

type Set

predicate NotIntersecting(Set s1, Set s2)
predicate Intersecting(Set s1, Set s2)
predicate IsSubset(Set s1, Set s2)
Set A, B, C, D, E, F, G

IsSubset(B, A)
IsSubset(C, A)
IsSubset(D, B)
IsSubset(E, B)
IsSubset(F, C)
IsSubset(G, C)

NotIntersecting(E, D)
NotIntersecting(F, G)
NotIntersecting(B, C)

AutoLabel All
canvas {
  width = 800
  height = 700
}

forall Set x {
  shape x.icon = Circle { }
  shape x.text = Equation {
    string : x.label
    fontSize : "32px"
  }
  ensure contains(x.icon, x.text)
  encourage norm(x.text.center - x.icon.center) == 0
  layer x.text above x.icon
}

forall Set x; Set y
where IsSubset(x, y) {
  ensure disjoint(y.text, x.icon, 10)
  ensure contains(y.icon, x.icon, 5)
  layer x.icon above y.icon
}

forall Set x; Set y
where NotIntersecting(x, y) {
  ensure disjoint(x.icon, y.icon)
}

forall Set x; Set y
where Intersecting(x, y) {
  ensure overlapping(x.icon, y.icon)
  ensure disjoint(y.text, x.icon)
  ensure disjoint(x.text, y.icon)
}

svgo ---> 优化 SVG

SVG 文件,尤其是从矢量编辑器导出的文件,通常包含大量冗余信息。这包括编辑器元数据、注释、隐藏元素、默认值或次优值以及可以安全删除或转换而不影响渲染的其他内容

svgo 去除这些数据,以此来缩小 SVG 体积大小

import { optimize } from 'svgo';

const result = optimize(svgString, {
  path: 'path-to.svg', // recommended
  multipass: true, // all other config fields are available here
});

const optimizedSvgString = result.data;

iconify ---> 集大成图标库

超级海量的图标库,可以通过如下用法,使用 CDN 加载,所有的 name 可以在这里找到

// https://api.iconify.design/${name}.svg?color=%23${logoColor}
// https://api.iconify.design/material-symbols:wifi-rounded.svg

当然也支持例如 vue、react、svelte 等框架

<template>
	<Icon :icon="areaChartOutlined" height="24" />
</template>

<script lang="ts" setup>
import { Icon } from '@iconify/vue';
import areaChartOutlined from '@iconify-icons/ant-design/area-chart-outlined';
</script>

如果你想使用这里面的图标,我建议可以使用 unplugin/unplugin-icons 这个库,帮助你自动导入

simple-icons ---> 图标库

支持直接 CDN 使用:simple-icons,自定义颜色等

// 官方 CDN:
// https://cdn.simpleicons.org/simpleicons/00ccff99
// jsdelivr:
// https://cdn.jsdelivr.net/npm/simple-icons/icons/${logoName}.svg
<!--  -->
<img height="32" width="32" src="https://cdn.simpleicons.org/simpleicons/hotpink" />

也支持 NodeJs:

import { siActigraph, siSimpleicons } from 'simple-icons'
console.log(siSimpleicons);

/*
{
    title: 'Simple Icons',
    slug: 'simpleicons',
    hex: '111111',
    source: 'https://simpleicons.org/',
    svg: '<svg role="img" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">...</svg>',
    path: 'M12 12v-1.5c-2.484 ...',
    guidelines: 'https://simpleicons.org/styleguide',
    license: {
        type: '...',
        url: 'https://example.com/'
    }
}

satori ---> React 组件到 SVG

可以用于用于生成 OG 图片

// api.jsx
import satori from 'satori'

const svg = await satori(
  <div style={{ color: 'black' }}>hello, world</div>,
  {
    width: 600,
    height: 400,
    fonts: [
      {
        name: 'Roboto',
        // Use `fs` (Node.js only) or `fetch` to read the font as Buffer/ArrayBuffer and provide `data` here.
        data: robotoArrayBuffer,
        weight: 400,
        style: 'normal',
      },
    ],
  },
)

Released under the MIT License.