import type { CropRect, TransformOptions } from './types' /** * 裁剪 / 旋转 / 翻转:canvas 变换矩阵一次性重绘,全部基于源位图(非截屏,保画质) */ import { beginDraw, exportFile, loadImage, typeByExt } from './core' import { resultName } from './task' /** 裁剪:rect 为源图像素坐标 */ export async function cropImage( src: string, rect: CropRect, ): Promise<{ path: string, name: string }> { const { img } = await loadImage(src) const type = typeByExt(src) const { ctx } = beginDraw(rect.width, rect.height, type === 'jpg') ctx.drawImage(img as CanvasImageSource, rect.x, rect.y, rect.width, rect.height, 0, 0, rect.width, rect.height) const path = await exportFile(type, 0.92) return { path, name: resultName(src, 'crop', type) } } /** 旋转(90° 步进顺时针)+ 镜像 */ export async function transformImage( src: string, opts: TransformOptions, ): Promise<{ path: string, name: string }> { const { img, width, height } = await loadImage(src) const rotate = opts.rotate ?? 0 const swap = rotate === 90 || rotate === 270 const outW = swap ? height : width const outH = swap ? width : height const type = typeByExt(src) const { ctx } = beginDraw(outW, outH, type === 'jpg') ctx.save() ctx.translate(outW / 2, outH / 2) ctx.rotate((rotate * Math.PI) / 180) ctx.scale(opts.flipH ? -1 : 1, opts.flipV ? -1 : 1) ctx.drawImage(img as CanvasImageSource, -width / 2, -height / 2) ctx.restore() const path = await exportFile(type, 0.92) return { path, name: resultName(src, 'transform', type) } }