node-pdf2img-native 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/index.d.ts ADDED
@@ -0,0 +1,209 @@
1
+ /* tslint:disable */
2
+ /* eslint-disable */
3
+
4
+ /* auto-generated by NAPI-RS */
5
+
6
+ /** 单页渲染结果 */
7
+ export interface PageResult {
8
+ /** 页码(从 1 开始) */
9
+ pageNum: number
10
+ /** 图像宽度 */
11
+ width: number
12
+ /** 图像高度 */
13
+ height: number
14
+ /** 编码后的图像数据 */
15
+ buffer: Buffer
16
+ /** 是否成功 */
17
+ success: boolean
18
+ /** 错误信息(如果失败) */
19
+ error?: string
20
+ /** 渲染耗时(毫秒) */
21
+ renderTime: number
22
+ /** 编码耗时(毫秒) */
23
+ encodeTime: number
24
+ }
25
+ /** 原始位图结果(不编码) */
26
+ export interface RawBitmapResult {
27
+ /** 是否成功 */
28
+ success: boolean
29
+ /** 错误信息(如果失败) */
30
+ error?: string
31
+ /** 图像宽度 */
32
+ width: number
33
+ /** 图像高度 */
34
+ height: number
35
+ /** 通道数(固定为 4,RGBA) */
36
+ channels: number
37
+ /** 原始 RGBA 像素数据 */
38
+ buffer: Buffer
39
+ /** 渲染耗时(毫秒) */
40
+ renderTime: number
41
+ }
42
+ /** 批量渲染结果 */
43
+ export interface RenderResult {
44
+ /** 是否成功 */
45
+ success: boolean
46
+ /** 错误信息(如果整体失败) */
47
+ error?: string
48
+ /** PDF 总页数 */
49
+ numPages: number
50
+ /** 每页的渲染结果 */
51
+ pages: Array<PageResult>
52
+ /** 总耗时(毫秒) */
53
+ totalTime: number
54
+ }
55
+ /** 渲染配置选项 */
56
+ export interface RenderOptions {
57
+ /** 目标渲染宽度(默认 1280) */
58
+ targetWidth?: number
59
+ /** 扫描件/图片页面的降级宽度(默认 1024) */
60
+ imageHeavyWidth?: number
61
+ /** 最大缩放比例(默认 4.0) */
62
+ maxScale?: number
63
+ /** 图片质量(1-100,用于 webp/jpg,已废弃,请使用 webp_quality/jpeg_quality) */
64
+ quality?: number
65
+ /** 是否启用扫描件检测(默认 true) */
66
+ detectScan?: boolean
67
+ /** 输出格式:webp, png, jpg(默认 webp) */
68
+ format?: string
69
+ /** WebP 编码质量(0-100,默认 80) */
70
+ webpQuality?: number
71
+ /** WebP 编码方法/速度(0-6,0最快,6最慢,默认 4) */
72
+ webpMethod?: number
73
+ /** JPEG 编码质量(0-100,默认 85) */
74
+ jpegQuality?: number
75
+ /** PNG 压缩级别(0-9,默认 6) */
76
+ pngCompression?: number
77
+ }
78
+ /**
79
+ * 从 PDF Buffer 渲染指定页面
80
+ *
81
+ * # Arguments
82
+ * * `pdf_buffer` - PDF 文件的二进制数据
83
+ * * `page_nums` - 要渲染的页码数组(从 1 开始)
84
+ * * `options` - 渲染配置选项
85
+ *
86
+ * # Returns
87
+ * 包含所有页面渲染结果的对象
88
+ */
89
+ export declare function renderPages(pdfBuffer: Buffer, pageNums: Array<number>, options?: RenderOptions | undefined | null): RenderResult
90
+ /**
91
+ * 从文件路径渲染 PDF 页面
92
+ *
93
+ * 直接从文件系统读取 PDF,避免在 Node.js 堆中创建大 Buffer。
94
+ * 这是处理本地大文件的最高效方式。
95
+ *
96
+ * # Arguments
97
+ * * `file_path` - PDF 文件的路径
98
+ * * `page_nums` - 要渲染的页码数组(从 1 开始)
99
+ * * `options` - 渲染配置选项
100
+ *
101
+ * # Returns
102
+ * 包含所有页面渲染结果的对象
103
+ */
104
+ export declare function renderPagesFromFile(filePath: string, pageNums: Array<number>, options?: RenderOptions | undefined | null): RenderResult
105
+ /**
106
+ * 从文件路径获取 PDF 页数(不渲染)
107
+ *
108
+ * # Arguments
109
+ * * `file_path` - PDF 文件的路径
110
+ *
111
+ * # Returns
112
+ * PDF 的总页数
113
+ */
114
+ export declare function getPageCountFromFile(filePath: string): number
115
+ /**
116
+ * 获取 PDF 页数(不渲染)
117
+ *
118
+ * # Arguments
119
+ * * `pdf_buffer` - PDF 文件的二进制数据
120
+ *
121
+ * # Returns
122
+ * PDF 的总页数
123
+ */
124
+ export declare function getPageCount(pdfBuffer: Buffer): number
125
+ /**
126
+ * 渲染单页到原始位图(不编码)
127
+ *
128
+ * 这个函数只进行 PDFium 渲染,跳过图像编码步骤,
129
+ * 返回原始 RGBA 像素数据。编码工作可以交给 Sharp 等更高效的库。
130
+ *
131
+ * # Arguments
132
+ * * `file_path` - PDF 文件路径
133
+ * * `page_num` - 页码(从 1 开始)
134
+ * * `options` - 渲染选项
135
+ *
136
+ * # Returns
137
+ * 包含原始位图数据和元信息的结果
138
+ */
139
+ export declare function renderPageToRawBitmap(filePath: string, pageNum: number, options?: RenderOptions | undefined | null): RawBitmapResult
140
+ /** 从 Buffer 渲染单页到原始位图(不编码) */
141
+ export declare function renderPageToRawBitmapFromBuffer(pdfBuffer: Buffer, pageNum: number, options?: RenderOptions | undefined | null): RawBitmapResult
142
+ /** 检查 PDFium 库是否可用 */
143
+ export declare function isPdfiumAvailable(): boolean
144
+ /**
145
+ * 预热 PDFium 库
146
+ *
147
+ * 在服务启动时调用,提前加载 PDFium 动态库并初始化,
148
+ * 避免首次请求时的冷启动延迟(约 1-2 秒)
149
+ *
150
+ * # Returns
151
+ * 预热耗时(毫秒)
152
+ */
153
+ export declare function warmup(): number
154
+ /** 获取版本信息 */
155
+ export declare function getVersion(): string
156
+ /** 流式渲染结果(包含额外的统计信息) */
157
+ export interface StreamRenderResult {
158
+ /** 是否成功 */
159
+ success: boolean
160
+ /** 错误信息(如果整体失败) */
161
+ error?: string
162
+ /** PDF 总页数 */
163
+ numPages: number
164
+ /** 每页的渲染结果 */
165
+ pages: Array<PageResult>
166
+ /** 总耗时(毫秒) */
167
+ totalTime: number
168
+ /** 流式加载统计 */
169
+ streamStats?: StreamStats
170
+ }
171
+ /** 流式加载统计信息 */
172
+ export interface StreamStats {
173
+ /** 总请求次数 */
174
+ totalRequests: number
175
+ /** 缓存命中次数 */
176
+ cacheHits: number
177
+ /** 缓存未命中次数 */
178
+ cacheMisses: number
179
+ /** 总下载字节数 */
180
+ totalBytesFetched: number
181
+ }
182
+ /**
183
+ * 从流式数据源渲染 PDF 页面(异步版本)
184
+ *
185
+ * 这个函数在独立线程中运行 PDFium 渲染,返回 Promise。
186
+ * 主线程保持事件循环运行,可以处理 JS 回调。
187
+ *
188
+ * # Arguments
189
+ * * `env` - NAPI 环境
190
+ * * `pdf_size` - PDF 文件的总大小(字节)
191
+ * * `page_nums` - 要渲染的页码数组(从 1 开始)
192
+ * * `options` - 渲染配置选项
193
+ * * `fetcher` - JavaScript 回调函数,用于获取指定范围的数据
194
+ *
195
+ * # Returns
196
+ * Promise<StreamRenderResult>
197
+ */
198
+ export declare function renderPagesFromStream(pdfSize: number, pageNums: number[], options: RenderOptions | null | undefined, fetcher: (offset: number, size: number, requestId: number) => void): object
199
+ /**
200
+ * 完成流式请求
201
+ *
202
+ * 当 JS 端获取到数据后,调用这个函数将数据发送给 Rust 端。
203
+ *
204
+ * # Arguments
205
+ * * `request_id` - 请求 ID
206
+ * * `data` - 获取到的数据
207
+ * * `error` - 错误信息(如果获取失败)
208
+ */
209
+ export declare function completeStreamRequest(requestId: number, data?: Buffer | undefined | null, error?: string | undefined | null): void
package/index.js ADDED
@@ -0,0 +1,325 @@
1
+ /* tslint:disable */
2
+ /* eslint-disable */
3
+ /* prettier-ignore */
4
+
5
+ /* auto-generated by NAPI-RS */
6
+
7
+ const { existsSync, readFileSync } = require('fs')
8
+ const { join } = require('path')
9
+
10
+ const { platform, arch } = process
11
+
12
+ let nativeBinding = null
13
+ let localFileExisted = false
14
+ let loadError = null
15
+
16
+ function isMusl() {
17
+ // For Node 10
18
+ if (!process.report || typeof process.report.getReport !== 'function') {
19
+ try {
20
+ const lddPath = require('child_process').execSync('which ldd').toString().trim()
21
+ return readFileSync(lddPath, 'utf8').includes('musl')
22
+ } catch (e) {
23
+ return true
24
+ }
25
+ } else {
26
+ const { glibcVersionRuntime } = process.report.getReport().header
27
+ return !glibcVersionRuntime
28
+ }
29
+ }
30
+
31
+ switch (platform) {
32
+ case 'android':
33
+ switch (arch) {
34
+ case 'arm64':
35
+ localFileExisted = existsSync(join(__dirname, 'pdf-renderer.android-arm64.node'))
36
+ try {
37
+ if (localFileExisted) {
38
+ nativeBinding = require('./pdf-renderer.android-arm64.node')
39
+ } else {
40
+ nativeBinding = require('node-pdf2img-native-android-arm64')
41
+ }
42
+ } catch (e) {
43
+ loadError = e
44
+ }
45
+ break
46
+ case 'arm':
47
+ localFileExisted = existsSync(join(__dirname, 'pdf-renderer.android-arm-eabi.node'))
48
+ try {
49
+ if (localFileExisted) {
50
+ nativeBinding = require('./pdf-renderer.android-arm-eabi.node')
51
+ } else {
52
+ nativeBinding = require('node-pdf2img-native-android-arm-eabi')
53
+ }
54
+ } catch (e) {
55
+ loadError = e
56
+ }
57
+ break
58
+ default:
59
+ throw new Error(`Unsupported architecture on Android ${arch}`)
60
+ }
61
+ break
62
+ case 'win32':
63
+ switch (arch) {
64
+ case 'x64':
65
+ localFileExisted = existsSync(
66
+ join(__dirname, 'pdf-renderer.win32-x64-msvc.node')
67
+ )
68
+ try {
69
+ if (localFileExisted) {
70
+ nativeBinding = require('./pdf-renderer.win32-x64-msvc.node')
71
+ } else {
72
+ nativeBinding = require('node-pdf2img-native-win32-x64-msvc')
73
+ }
74
+ } catch (e) {
75
+ loadError = e
76
+ }
77
+ break
78
+ case 'ia32':
79
+ localFileExisted = existsSync(
80
+ join(__dirname, 'pdf-renderer.win32-ia32-msvc.node')
81
+ )
82
+ try {
83
+ if (localFileExisted) {
84
+ nativeBinding = require('./pdf-renderer.win32-ia32-msvc.node')
85
+ } else {
86
+ nativeBinding = require('node-pdf2img-native-win32-ia32-msvc')
87
+ }
88
+ } catch (e) {
89
+ loadError = e
90
+ }
91
+ break
92
+ case 'arm64':
93
+ localFileExisted = existsSync(
94
+ join(__dirname, 'pdf-renderer.win32-arm64-msvc.node')
95
+ )
96
+ try {
97
+ if (localFileExisted) {
98
+ nativeBinding = require('./pdf-renderer.win32-arm64-msvc.node')
99
+ } else {
100
+ nativeBinding = require('node-pdf2img-native-win32-arm64-msvc')
101
+ }
102
+ } catch (e) {
103
+ loadError = e
104
+ }
105
+ break
106
+ default:
107
+ throw new Error(`Unsupported architecture on Windows: ${arch}`)
108
+ }
109
+ break
110
+ case 'darwin':
111
+ localFileExisted = existsSync(join(__dirname, 'pdf-renderer.darwin-universal.node'))
112
+ try {
113
+ if (localFileExisted) {
114
+ nativeBinding = require('./pdf-renderer.darwin-universal.node')
115
+ } else {
116
+ nativeBinding = require('node-pdf2img-native-darwin-universal')
117
+ }
118
+ break
119
+ } catch {}
120
+ switch (arch) {
121
+ case 'x64':
122
+ localFileExisted = existsSync(join(__dirname, 'pdf-renderer.darwin-x64.node'))
123
+ try {
124
+ if (localFileExisted) {
125
+ nativeBinding = require('./pdf-renderer.darwin-x64.node')
126
+ } else {
127
+ nativeBinding = require('node-pdf2img-native-darwin-x64')
128
+ }
129
+ } catch (e) {
130
+ loadError = e
131
+ }
132
+ break
133
+ case 'arm64':
134
+ localFileExisted = existsSync(
135
+ join(__dirname, 'pdf-renderer.darwin-arm64.node')
136
+ )
137
+ try {
138
+ if (localFileExisted) {
139
+ nativeBinding = require('./pdf-renderer.darwin-arm64.node')
140
+ } else {
141
+ nativeBinding = require('node-pdf2img-native-darwin-arm64')
142
+ }
143
+ } catch (e) {
144
+ loadError = e
145
+ }
146
+ break
147
+ default:
148
+ throw new Error(`Unsupported architecture on macOS: ${arch}`)
149
+ }
150
+ break
151
+ case 'freebsd':
152
+ if (arch !== 'x64') {
153
+ throw new Error(`Unsupported architecture on FreeBSD: ${arch}`)
154
+ }
155
+ localFileExisted = existsSync(join(__dirname, 'pdf-renderer.freebsd-x64.node'))
156
+ try {
157
+ if (localFileExisted) {
158
+ nativeBinding = require('./pdf-renderer.freebsd-x64.node')
159
+ } else {
160
+ nativeBinding = require('node-pdf2img-native-freebsd-x64')
161
+ }
162
+ } catch (e) {
163
+ loadError = e
164
+ }
165
+ break
166
+ case 'linux':
167
+ switch (arch) {
168
+ case 'x64':
169
+ if (isMusl()) {
170
+ localFileExisted = existsSync(
171
+ join(__dirname, 'pdf-renderer.linux-x64-musl.node')
172
+ )
173
+ try {
174
+ if (localFileExisted) {
175
+ nativeBinding = require('./pdf-renderer.linux-x64-musl.node')
176
+ } else {
177
+ nativeBinding = require('node-pdf2img-native-linux-x64-musl')
178
+ }
179
+ } catch (e) {
180
+ loadError = e
181
+ }
182
+ } else {
183
+ localFileExisted = existsSync(
184
+ join(__dirname, 'pdf-renderer.linux-x64-gnu.node')
185
+ )
186
+ try {
187
+ if (localFileExisted) {
188
+ nativeBinding = require('./pdf-renderer.linux-x64-gnu.node')
189
+ } else {
190
+ nativeBinding = require('node-pdf2img-native-linux-x64-gnu')
191
+ }
192
+ } catch (e) {
193
+ loadError = e
194
+ }
195
+ }
196
+ break
197
+ case 'arm64':
198
+ if (isMusl()) {
199
+ localFileExisted = existsSync(
200
+ join(__dirname, 'pdf-renderer.linux-arm64-musl.node')
201
+ )
202
+ try {
203
+ if (localFileExisted) {
204
+ nativeBinding = require('./pdf-renderer.linux-arm64-musl.node')
205
+ } else {
206
+ nativeBinding = require('node-pdf2img-native-linux-arm64-musl')
207
+ }
208
+ } catch (e) {
209
+ loadError = e
210
+ }
211
+ } else {
212
+ localFileExisted = existsSync(
213
+ join(__dirname, 'pdf-renderer.linux-arm64-gnu.node')
214
+ )
215
+ try {
216
+ if (localFileExisted) {
217
+ nativeBinding = require('./pdf-renderer.linux-arm64-gnu.node')
218
+ } else {
219
+ nativeBinding = require('node-pdf2img-native-linux-arm64-gnu')
220
+ }
221
+ } catch (e) {
222
+ loadError = e
223
+ }
224
+ }
225
+ break
226
+ case 'arm':
227
+ if (isMusl()) {
228
+ localFileExisted = existsSync(
229
+ join(__dirname, 'pdf-renderer.linux-arm-musleabihf.node')
230
+ )
231
+ try {
232
+ if (localFileExisted) {
233
+ nativeBinding = require('./pdf-renderer.linux-arm-musleabihf.node')
234
+ } else {
235
+ nativeBinding = require('node-pdf2img-native-linux-arm-musleabihf')
236
+ }
237
+ } catch (e) {
238
+ loadError = e
239
+ }
240
+ } else {
241
+ localFileExisted = existsSync(
242
+ join(__dirname, 'pdf-renderer.linux-arm-gnueabihf.node')
243
+ )
244
+ try {
245
+ if (localFileExisted) {
246
+ nativeBinding = require('./pdf-renderer.linux-arm-gnueabihf.node')
247
+ } else {
248
+ nativeBinding = require('node-pdf2img-native-linux-arm-gnueabihf')
249
+ }
250
+ } catch (e) {
251
+ loadError = e
252
+ }
253
+ }
254
+ break
255
+ case 'riscv64':
256
+ if (isMusl()) {
257
+ localFileExisted = existsSync(
258
+ join(__dirname, 'pdf-renderer.linux-riscv64-musl.node')
259
+ )
260
+ try {
261
+ if (localFileExisted) {
262
+ nativeBinding = require('./pdf-renderer.linux-riscv64-musl.node')
263
+ } else {
264
+ nativeBinding = require('node-pdf2img-native-linux-riscv64-musl')
265
+ }
266
+ } catch (e) {
267
+ loadError = e
268
+ }
269
+ } else {
270
+ localFileExisted = existsSync(
271
+ join(__dirname, 'pdf-renderer.linux-riscv64-gnu.node')
272
+ )
273
+ try {
274
+ if (localFileExisted) {
275
+ nativeBinding = require('./pdf-renderer.linux-riscv64-gnu.node')
276
+ } else {
277
+ nativeBinding = require('node-pdf2img-native-linux-riscv64-gnu')
278
+ }
279
+ } catch (e) {
280
+ loadError = e
281
+ }
282
+ }
283
+ break
284
+ case 's390x':
285
+ localFileExisted = existsSync(
286
+ join(__dirname, 'pdf-renderer.linux-s390x-gnu.node')
287
+ )
288
+ try {
289
+ if (localFileExisted) {
290
+ nativeBinding = require('./pdf-renderer.linux-s390x-gnu.node')
291
+ } else {
292
+ nativeBinding = require('node-pdf2img-native-linux-s390x-gnu')
293
+ }
294
+ } catch (e) {
295
+ loadError = e
296
+ }
297
+ break
298
+ default:
299
+ throw new Error(`Unsupported architecture on Linux: ${arch}`)
300
+ }
301
+ break
302
+ default:
303
+ throw new Error(`Unsupported OS: ${platform}, architecture: ${arch}`)
304
+ }
305
+
306
+ if (!nativeBinding) {
307
+ if (loadError) {
308
+ throw loadError
309
+ }
310
+ throw new Error(`Failed to load native binding`)
311
+ }
312
+
313
+ const { renderPages, renderPagesFromFile, getPageCountFromFile, getPageCount, renderPageToRawBitmap, renderPageToRawBitmapFromBuffer, isPdfiumAvailable, warmup, getVersion, renderPagesFromStream, completeStreamRequest } = nativeBinding
314
+
315
+ module.exports.renderPages = renderPages
316
+ module.exports.renderPagesFromFile = renderPagesFromFile
317
+ module.exports.getPageCountFromFile = getPageCountFromFile
318
+ module.exports.getPageCount = getPageCount
319
+ module.exports.renderPageToRawBitmap = renderPageToRawBitmap
320
+ module.exports.renderPageToRawBitmapFromBuffer = renderPageToRawBitmapFromBuffer
321
+ module.exports.isPdfiumAvailable = isPdfiumAvailable
322
+ module.exports.warmup = warmup
323
+ module.exports.getVersion = getVersion
324
+ module.exports.renderPagesFromStream = renderPagesFromStream
325
+ module.exports.completeStreamRequest = completeStreamRequest
Binary file
package/libpdfium.so ADDED
Binary file
package/package.json ADDED
@@ -0,0 +1,60 @@
1
+ {
2
+ "name": "node-pdf2img-native",
3
+ "version": "1.0.0",
4
+ "description": "High-performance PDF to image native renderer using PDFium and NAPI-RS",
5
+ "main": "index.js",
6
+ "types": "index.d.ts",
7
+ "napi": {
8
+ "name": "pdf-renderer",
9
+ "triples": {
10
+ "defaults": false,
11
+ "additional": [
12
+ "x86_64-unknown-linux-gnu",
13
+ "aarch64-unknown-linux-gnu",
14
+ "x86_64-apple-darwin",
15
+ "aarch64-apple-darwin",
16
+ "x86_64-pc-windows-msvc"
17
+ ]
18
+ },
19
+ "binaryName": "pdf-renderer"
20
+ },
21
+ "files": [
22
+ "index.js",
23
+ "index.d.ts",
24
+ "pdf-renderer.*.node",
25
+ "libpdfium.so",
26
+ "libpdfium.dylib",
27
+ "pdfium.dll"
28
+ ],
29
+ "scripts": {
30
+ "artifacts": "napi artifacts",
31
+ "build": "napi build --platform --release && node scripts/copy-pdfium.js",
32
+ "build:debug": "napi build --platform",
33
+ "install": "napi build --platform --release || echo 'Build skipped, using prebuilt binary'",
34
+ "prebuildify": "napi prebuildify",
35
+ "test": "LD_LIBRARY_PATH=. node test.mjs",
36
+ "universal": "napi universal",
37
+ "version": "napi version"
38
+ },
39
+ "os": [
40
+ "linux",
41
+ "darwin",
42
+ "win32"
43
+ ],
44
+ "cpu": [
45
+ "x64",
46
+ "arm64"
47
+ ],
48
+ "devDependencies": {
49
+ "@napi-rs/cli": "^2.18.0"
50
+ },
51
+ "engines": {
52
+ "node": ">= 18"
53
+ },
54
+ "repository": {
55
+ "type": "git",
56
+ "url": "git+https://github.com/sigma-2026/node-pdf2img.git",
57
+ "directory": "packages/native-renderer"
58
+ },
59
+ "license": "MIT"
60
+ }
Binary file
Binary file
Binary file