纯客户端
处理全在浏览器,服务端零图片库,能力随浏览器能力走。
@easyx/image-toolkit 把图片处理全部放在浏览器:服务端零图片库、零原生依赖。内置引擎基于 @imagemagick/magick-wasm(ImageMagick 编译为 WebAssembly),运行在自建 Worker 中,不阻塞主线程。
| 入口 | 内容 | 依赖 |
|---|---|---|
@easyx/image-toolkit | 同构纯逻辑:魔数嗅探、格式判定、操作归一化、缩放换算 | 零重量依赖(服务端可安全引用) |
@easyx/image-toolkit/ui | 浏览器侧:引擎客户端、hooks、图片编辑内容区 | React + wasm 引擎(惰性加载) |
纯客户端
处理全在浏览器,服务端零图片库,能力随浏览器能力走。
不阻塞主线程
wasm 实例化与处理都在 Worker 中,主线程只负责带进度的下载。
预览即所得
拖动对比原图与结果,同区域对齐;参数变化后防抖自动预览。
自研裁切台
裁切框可拖动、可拖边与角改尺寸,比例可选锁定或自由,支持键盘操作。
无损优先
PNG / WebP / TIFF 逐像素无损;界面按格式实时提示可用策略。
UI 自研
除 React 外不依赖任何 UI 库,表单控件基于原生元素。
pnpm add @easyx/image-toolkitreact / react-dom 为 peer 依赖,需宿主自行安装(仅 ./ui 入口需要)。样式编译后内联进 JS,宿主无需单独引入。
import { IMAGE_LIMITS, isProcessableFormat, sniffImage } from '@easyx/image-toolkit';
const meta = sniffImage(bytes); // 魔数嗅探:非图片返回 nullsniffImage 以魔数判定类型与尺寸,不信任客户端声明的 MIME,是阻止存储型 XSS 的第一道闸门。
包内只提供编辑内容区 <ImageEditor>,容器与保存动作都由宿主负责:
import { ImageEditor, type ImageEditorResult } from '@easyx/image-toolkit/ui';import { useState } from 'react';
function CoverEditor() { const [preview, setPreview] = useState<ImageEditorResult | null>(null);
return ( <> <ImageEditor src={sourceUrl} onResultChange={setPreview} />
{/* 保存 / 下载由宿主自行实现 */} <button disabled={!preview?.result || preview.pending} onClick={() => preview?.result && download(preview.result)} > 保存 </button> </> );}内容区内部已含 ImageEngineGate:引擎加载进度、错误与重试都在内部处理。onResultChange 返回 { result, pending, noop, unsupported, error },result 为 null 表示当前设置未产生变更或尚不可保存。
样式走包内 SCSS + CSS 变量(--easyx-image-toolkit-*),覆盖变量即可定制外观。暗色按三级判定,命中即生效:
easyx-image-toolkit-dark classdata-theme 以 dark 结尾(如 dark / admin-dark)prefers-color-scheme若宿主用类名等 CSS 覆盖不到的方式表达主题,用 <ImageEditor theme="dark" /> 显式指定。