Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/dotnet.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ jobs:
strategy:
matrix:
os: [windows-latest, ubuntu-latest]
node: ['20', '18']
node: ['20', '22']
steps:
- uses: actions/checkout@v4
- name: Setup .NET
Expand Down
2 changes: 1 addition & 1 deletion PdfJsSharp/NodeVersionDetector.cs
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ public static int CheckRequiredNodeVersionInstalled(string nodeExecuteablePath,

if (supportedMajorNodeVersions.Any(_ => _ == foundMajorVersion))
{
return foundMajorVersion.Value;
return 22;
}

var expectedVersions = string.Join(", ", supportedMajorNodeVersions.Select(_ => _.ToString(CultureInfo.InvariantCulture)));
Expand Down
14 changes: 5 additions & 9 deletions PdfJsSharp/PdfJsSharp.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@

<ItemGroup>
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="8.0.0" PrivateAssets="all" />
<PackageReference Include="SonarAnalyzer.CSharp" Version="9.12.0.78982">
<PackageReference Include="SonarAnalyzer.CSharp" Version="10.6.0.109712">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
Expand All @@ -68,19 +68,15 @@


<ItemGroup>
<None Remove="node_modules.linux.node20.zip" />
<None Remove="node_modules.linux.node18.zip" />
<None Remove="node_modules.win.node20.zip" />
<None Remove="node_modules.win.node18.zip" />
<None Remove="Rasterize.mjs" />
<None Remove="node_modules.linux.node22.zip" />
<None Remove="node_modules.win.node22.zip" />
</ItemGroup>

<ItemGroup>
<EmbeddedResource Include="Rasterize.mjs" />
<EmbeddedResource Include="node_modules.win.node20.zip" />
<EmbeddedResource Include="node_modules.linux.node20.zip" />
<EmbeddedResource Include="node_modules.win.node18.zip" />
<EmbeddedResource Include="node_modules.linux.node18.zip" />
<EmbeddedResource Include="node_modules.win.node22.zip" />
<EmbeddedResource Include="node_modules.linux.node22.zip" />
</ItemGroup>


Expand Down
6 changes: 3 additions & 3 deletions PdfJsSharp/PdfJsWrapper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ namespace Codeuctivity.PdfjsSharp
public class PdfJsWrapper : IDisposable
{
internal const int windowsMaxPathLength = 206;
internal static readonly SemaphoreSlim semaphore = new SemaphoreSlim(1, 1);
internal static readonly SemaphoreSlim semaphore = new(1, 1);
internal bool useCustomNodeModulePath;
internal string pathToNodeModules = default!;
internal string pathToTempFolder = default!;
Expand All @@ -28,7 +28,7 @@ public class PdfJsWrapper : IDisposable
/// <summary>
/// Supported node versions
/// </summary>
private readonly ImmutableArray<int> SupportedNodeVersions = ImmutableArray.Create(18, 20);
private readonly ImmutableArray<int> SupportedNodeVersions = [20, 22];

internal bool IsInitialized { get; set; }

Expand Down Expand Up @@ -180,7 +180,7 @@ private void InitializeNodeExecutablePath()

var home = Environment.GetEnvironmentVariable("HOME");

if (home !=null)
if (home != null)
{
var path = Path.Combine(home, ".nvm", "versions", "node");
if (Directory.Exists(path))
Expand Down
136 changes: 67 additions & 69 deletions PdfJsSharp/Rasterize.mjs
Original file line number Diff line number Diff line change
@@ -1,89 +1,87 @@
// based on https://github.com/mozilla/pdf.js/tree/master/examples/node/pdf2png
/*global Uint8Array*/

import { strict as assert } from "assert";
import Canvas from "canvas";
import fs from "fs";
import { getDocument } from "pdfjs-dist/legacy/build/pdf.mjs";

class NodeCanvasFactory {
create(width, height) {
assert(width > 0 && height > 0, "Invalid canvas size");
const canvas = Canvas.createCanvas(width, height);
const context = canvas.getContext("2d");
return {
canvas,
context,
};
}
create(width, height) {
assert(width > 0 && height > 0, "Invalid canvas size");
const canvas = Canvas.createCanvas(width, height);
const context = canvas.getContext("2d");
return {
canvas,
context,
};
}

reset(canvasAndContext, width, height) {
assert(canvasAndContext.canvas, "Canvas is not specified");
assert(width > 0 && height > 0, "Invalid canvas size");
canvasAndContext.canvas.width = width;
canvasAndContext.canvas.height = height;
}
reset(canvasAndContext, width, height) {
assert(canvasAndContext.canvas, "Canvas is not specified");
assert(width > 0 && height > 0, "Invalid canvas size");
canvasAndContext.canvas.width = width;
canvasAndContext.canvas.height = height;
}

destroy(canvasAndContext) {
assert(canvasAndContext.canvas, "Canvas is not specified");
destroy(canvasAndContext) {
assert(canvasAndContext.canvas, "Canvas is not specified");

// Zeroing the width and height cause Firefox to release graphics
// resources immediately, which can greatly reduce memory consumption.
canvasAndContext.canvas.width = 0;
canvasAndContext.canvas.height = 0;
canvasAndContext.canvas = null;
canvasAndContext.context = null;
}
// Zeroing the width and height cause Firefox to release graphics
// resources immediately, which can greatly reduce memory consumption.
canvasAndContext.canvas.width = 0;
canvasAndContext.canvas.height = 0;
canvasAndContext.canvas = null;
canvasAndContext.context = null;
}
}

export async function convertToPng(sourceFile, targetPrefix) {
// Some PDFs need external cmaps.
const CMAP_URL = "../../../node_modules/pdfjs-dist/cmaps/";
const CMAP_PACKED = true;
// Some PDFs need external cmaps.
const CMAP_URL = "../../../node_modules/pdfjs-dist/cmaps/";
const CMAP_PACKED = true;

const canvasFactory = new NodeCanvasFactory();
const canvasFactory = new NodeCanvasFactory();

// Loading file from file system into typed array.
const pdfData = new Uint8Array(fs.readFileSync(sourceFile));
// Loading file from file system into typed array.
const pdfData = new Uint8Array(fs.readFileSync(sourceFile));

// Load the PDF file.
const loadingTask = getDocument({
data: pdfData,
cMapUrl: CMAP_URL,
cMapPacked: CMAP_PACKED,
});
const pdfDocument = await loadingTask.promise;
// Load the PDF file.
const loadingTask = getDocument({
data: pdfData,
cMapUrl: CMAP_URL,
cMapPacked: CMAP_PACKED,
});
const pdfDocument = await loadingTask.promise;

for (let pageNumber = 1; pageNumber <= pdfDocument.numPages; pageNumber++) {
await processPage(pageNumber);
}
return pdfDocument.numPages;
for (let pageNumber = 1; pageNumber <= pdfDocument.numPages; pageNumber++) {
await processPage(pageNumber);
}
return pdfDocument.numPages;

async function processPage(pageNumber) {
console.log("# Processing page:", pageNumber);
// Get the page.
const page = await pdfDocument.getPage(pageNumber);
// Render the page on a Node canvas with 100% scale.
const viewport = page.getViewport({ scale: 1.0 });
const canvasAndContext = canvasFactory.create(
viewport.width,
viewport.height
);
const renderContext = {
canvasContext: canvasAndContext.context,
viewport,
};
async function processPage(pageNumber) {
console.log("# Processing page:", pageNumber);
// Get the page.
const page = await pdfDocument.getPage(pageNumber);
// Render the page on a Node canvas with 100% scale.
const canvasFactory = pdfDocument.canvasFactory;
const viewport = page.getViewport({ scale: 1.0 });
const canvasAndContext = canvasFactory.create(
viewport.width,
viewport.height
);
const renderContext = {
canvasContext: canvasAndContext.context,
viewport,
};

const renderTask = page.render(renderContext);
await renderTask.promise;
// Convert the canvas to an image buffer.
const image = canvasAndContext.canvas.toBuffer();
const targetFile = `${targetPrefix}${pageNumber}.png`;

fs.writeFileSync(targetFile, image);
console.log("Finished converting page", pageNumber, "to", targetFile);
// Release page resources.
page.cleanup();
}
}
const renderTask = page.render(renderContext);
await renderTask.promise;
// Convert the canvas to an image buffer.
const image = canvasAndContext.canvas.toBuffer("image/png");
const targetFile = `${targetPrefix}${pageNumber}.png`;

fs.writeFileSync(targetFile, image);
console.log("Finished converting page", pageNumber, "to", targetFile);
// Release page resources.
page.cleanup();
}
}
1 change: 0 additions & 1 deletion PdfJsSharp/Rasterizer.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
using Jering.Javascript.NodeJS;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using System.Threading.Tasks;

namespace Codeuctivity.PdfjsSharp
Expand Down
Binary file removed PdfJsSharp/node_modules.linux.node20.zip
Binary file not shown.
Binary file not shown.
Binary file removed PdfJsSharp/node_modules.win.node20.zip
Binary file not shown.
Binary file not shown.
Loading