Skip to content

Commit

Permalink
Add PDF export to stream
Browse files Browse the repository at this point in the history
  • Loading branch information
cyanfish committed Dec 7, 2023
1 parent 54de82b commit e431157
Show file tree
Hide file tree
Showing 5 changed files with 83 additions and 6 deletions.
17 changes: 17 additions & 0 deletions NAPS2.Sdk.Tests/Pdf/PdfExportTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,23 @@ public async Task ExportJpegImage(StorageConfig storageConfig)
PdfAsserts.AssertImageFilter(filePath, 0, "DCTDecode");
}

[Theory]
[ClassData(typeof(StorageAwareTestData))]
public async Task ExportJpegImageToStream(StorageConfig storageConfig)
{
storageConfig.Apply(this);

var filePath = Path.Combine(FolderPath, "test.pdf");
var fileStream = File.OpenWrite(filePath);
using var image = ScanningContext.CreateProcessedImage(LoadImage(ImageResources.dog));

await _exporter.Export(fileStream, new[] { image });
fileStream.Close();

PdfAsserts.AssertImages(filePath, ImageResources.dog);
PdfAsserts.AssertImageFilter(filePath, 0, "DCTDecode");
}

[Theory]
[ClassData(typeof(StorageAwareTestData))]
public async Task ExportGrayJpegImage(StorageConfig storageConfig)
Expand Down
16 changes: 16 additions & 0 deletions NAPS2.Sdk.Tests/Pdf/PdfImportExportTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,22 @@ public async Task ImportExport(OcrTestConfig config)
PdfAsserts.AssertImages(_exportPath, PdfResources.word_p1, PdfResources.word_p2);
}

[Theory]
[ClassData(typeof(OcrTestData))]
public async Task ImportExportToStream(OcrTestConfig config)
{
config.StorageConfig.Apply(this);
SetUpFakeOcr();

var fileStream = File.OpenWrite(_exportPath);
var images = await _importer.Import(_importPath).ToListAsync();
Assert.Equal(2, images.Count);
await _exporter.Export(fileStream, images, ocrParams: config.OcrParams);
fileStream.Close();

PdfAsserts.AssertImages(_exportPath, PdfResources.word_p1, PdfResources.word_p2);
}

[Theory]
[ClassData(typeof(OcrTestData))]
public async Task ImportInsertExport(OcrTestConfig config)
Expand Down
3 changes: 3 additions & 0 deletions NAPS2.Sdk/Pdf/IPdfExporter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,7 @@ public interface IPdfExporter
{
Task<bool> Export(string path, ICollection<ProcessedImage> images, PdfExportParams? exportParams = null,
OcrParams? ocrParams = null, ProgressHandler progress = default);

Task<bool> Export(Stream stream, ICollection<ProcessedImage> images, PdfExportParams? exportParams = null,
OcrParams? ocrParams = null, ProgressHandler progress = default);
}
47 changes: 41 additions & 6 deletions NAPS2.Sdk/Pdf/PdfExporter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,15 @@ public PdfExporter(ScanningContext scanningContext)
_logger = scanningContext.Logger;
}

public async Task<bool> Export(string path, ICollection<ProcessedImage> images,
public Task<bool> Export(string path, ICollection<ProcessedImage> images,
PdfExportParams? exportParams = null, OcrParams? ocrParams = null, ProgressHandler progress = default)
=> Export(new OutputPathOrStream(path, null), images, exportParams, ocrParams, progress);

public Task<bool> Export(Stream stream, ICollection<ProcessedImage> images,
PdfExportParams? exportParams = null, OcrParams? ocrParams = null, ProgressHandler progress = default)
=> Export(new OutputPathOrStream(null, stream), images, exportParams, ocrParams, progress);

private async Task<bool> Export(OutputPathOrStream output, ICollection<ProcessedImage> images,
PdfExportParams? exportParams = null, OcrParams? ocrParams = null, ProgressHandler progress = default)
{
return await Task.Run(async () =>
Expand Down Expand Up @@ -123,7 +131,7 @@ void IncrementProgress()
var stream = FinalizeAndSaveDocument(document, exportParams);
if (progress.IsCancellationRequested) return false;

return MergePassthroughPages(stream, path, pdfPages, exportParams, progress);
return MergePassthroughPages(stream, output, pdfPages, exportParams, progress);
}
finally
{
Expand All @@ -136,13 +144,12 @@ void IncrementProgress()
});
}

private bool MergePassthroughPages(MemoryStream stream, string path, List<PageExportState> passthroughPages,
private bool MergePassthroughPages(MemoryStream stream, OutputPathOrStream output, List<PageExportState> passthroughPages,
PdfExportParams exportParams, ProgressHandler progress)
{
if (!passthroughPages.Any())
{
using var fileStream = new FileStream(path, FileMode.Create);
stream.CopyTo(fileStream);
output.CopyFromStream(stream);
return true;
}
// TODO: Should we do this (or maybe the whole pdf export/import) in a worker to avoid contention?
Expand Down Expand Up @@ -186,7 +193,7 @@ private bool MergePassthroughPages(MemoryStream stream, string path, List<PageEx
}
if (progress.IsCancellationRequested) return false;
}
destDoc.Save(path);
output.SaveDoc(destDoc);
return true;
}
finally
Expand Down Expand Up @@ -746,4 +753,32 @@ public void Dispose()
{
}
}

private record OutputPathOrStream(string? Path, Stream? Stream)
{
public void CopyFromStream(MemoryStream inputStream)
{
if (Stream != null)
{
inputStream.CopyTo(Stream);
}
else
{
using var fileStream = new FileStream(Path!, FileMode.Create);
inputStream.CopyTo(fileStream);
}
}

public void SaveDoc(Pdfium.PdfDocument doc)
{
if (Stream != null)
{
doc.Save(Stream);
}
else
{
doc.Save(Path!);
}
}
}
}
6 changes: 6 additions & 0 deletions NAPS2.Sdk/Pdf/PdfiumPdfExporter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,12 @@ public PdfiumPdfExporter(ScanningContext scanningContext)
_logger = scanningContext.Logger;
}

public Task<bool> Export(Stream stream, ICollection<ProcessedImage> images, PdfExportParams? exportParams = null, OcrParams? ocrParams = null,
ProgressHandler progress = default)
{
throw new NotSupportedException();
}

public async Task<bool> Export(string path, ICollection<ProcessedImage> images,
PdfExportParams? exportParams = null, OcrParams? ocrParams = null, ProgressHandler progress = default)
{
Expand Down

0 comments on commit e431157

Please sign in to comment.