42 lines
1.6 KiB
TypeScript
42 lines
1.6 KiB
TypeScript
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) }
|
||
}
|