@gutenye/ocr-node
Version:
Guten OCR is a high accurate text detection (OCR) Javascript/Typescript library that runs on Node.js, Browser, React Native and C++. Based on PaddleOCR and ONNX runtime
75 lines (65 loc) • 2 kB
text/typescript
import filePath from 'node:path'
import { ImageRawBase } from '@gutenye/ocr-common'
import type { ImageRawData, LineImage, SizeOption } from '@gutenye/ocr-common'
import sharp from 'sharp'
export class ImageRaw extends ImageRawBase {
#sharp: sharp.Sharp
static async open(path: string): Promise<ImageRaw> {
return new ImageRaw(await toImageRaw(sharp(path).ensureAlpha(1)))
}
constructor(imageRawData: ImageRawData) {
super(imageRawData)
this.#sharp = toSharp(imageRawData)
}
async write(path: string) {
const ext = filePath.extname(path).slice(1)
return this.#sharp.toFormat(ext as keyof sharp.FormatEnum).toFile(path)
}
async resize(size: SizeOption) {
return this.#apply(
this.#sharp.resize({
width: size.width,
height: size.height,
fit: 'contain',
}),
)
}
async drawBox(lineImages: LineImage[]) {
const svg = `
<svg width="${this.width}" height="${this.height}">
${lineImages
.map((lineImage) => {
const [p1, p2, p3, p4] = lineImage.box
return `<polygon points="${p1[0]},${p1[1]} ${p2[0]},${p2[1]} ${p3[0]},${p3[1]} ${p4[0]},${p4[1]}" fill="none" stroke="red" />`
})
.join('\n')}
</svg>
`
return this.#apply(this.#sharp.composite([{ input: Buffer.from(svg), left: 0, top: 0 }]))
}
async #apply(sharp: sharp.Sharp) {
this.#sharp = sharp
const result = await toImageRaw(sharp)
this.data = result.data
this.width = result.width
this.height = result.height
return this
}
}
async function toImageRaw(sharp: sharp.Sharp) {
const result = await sharp.raw().toBuffer({ resolveWithObject: true })
return {
data: result.data,
width: result.info.width,
height: result.info.height,
}
}
function toSharp(imageRawData: ImageRawData) {
return sharp(imageRawData.data, {
raw: {
width: imageRawData.width,
height: imageRawData.height,
channels: 4,
},
})
}