mirror of
https://github.com/cyanfish/naps2.git
synced 2024-08-17 19:20:29 +03:00
Provide IPdfRenderer from ProcessedImage
This commit is contained in:
parent
80dc5c0635
commit
8906f5b76e
@ -11,11 +11,7 @@ public class GdiImageContext : ImageContext
|
||||
{
|
||||
private readonly GdiImageTransformer _imageTransformer;
|
||||
|
||||
public GdiImageContext() : this(null)
|
||||
{
|
||||
}
|
||||
|
||||
public GdiImageContext(IPdfRenderer? pdfRenderer) : base(typeof(GdiImage), pdfRenderer)
|
||||
public GdiImageContext() : base(typeof(GdiImage))
|
||||
{
|
||||
_imageTransformer = new GdiImageTransformer(this);
|
||||
}
|
||||
|
@ -9,7 +9,7 @@ public class GtkImageContext : ImageContext
|
||||
private readonly GtkImageTransformer _imageTransformer;
|
||||
private readonly LibTiffIo _tiffIo;
|
||||
|
||||
public GtkImageContext(IPdfRenderer? pdfRenderer = null) : base(typeof(GtkImage), pdfRenderer)
|
||||
public GtkImageContext() : base(typeof(GtkImage))
|
||||
{
|
||||
_imageTransformer = new GtkImageTransformer(this);
|
||||
_tiffIo = new LibTiffIo(this);
|
||||
|
@ -21,7 +21,7 @@ public class ImageSharpImageContext : ImageContext
|
||||
Configuration = GetConfiguration()
|
||||
};
|
||||
|
||||
public ImageSharpImageContext(IPdfRenderer? pdfRenderer = null) : base(typeof(ImageSharpImage), pdfRenderer)
|
||||
public ImageSharpImageContext() : base(typeof(ImageSharpImage))
|
||||
{
|
||||
_imageTransformer = new ImageSharpImageTransformer(this);
|
||||
}
|
||||
|
@ -9,7 +9,7 @@ public class MacImageContext : ImageContext
|
||||
|
||||
private readonly MacImageTransformer _imageTransformer;
|
||||
|
||||
public MacImageContext(IPdfRenderer? pdfRenderer = null) : base(typeof(MacImage), pdfRenderer)
|
||||
public MacImageContext() : base(typeof(MacImage))
|
||||
{
|
||||
NSApplication.CheckForIllegalCrossThreadCalls = false;
|
||||
_imageTransformer = new MacImageTransformer(this);
|
||||
|
@ -9,7 +9,7 @@ public class WpfImageContext : ImageContext
|
||||
{
|
||||
private readonly WpfImageTransformer _imageTransformer;
|
||||
|
||||
public WpfImageContext(IPdfRenderer? pdfRenderer = null) : base(typeof(WpfImage), pdfRenderer)
|
||||
public WpfImageContext() : base(typeof(WpfImage))
|
||||
{
|
||||
_imageTransformer = new WpfImageTransformer(this);
|
||||
}
|
||||
|
@ -8,6 +8,8 @@ namespace NAPS2.Images;
|
||||
/// </summary>
|
||||
public interface IMemoryImage : IImageStorage
|
||||
{
|
||||
// TODO: Now that ImageContext objects are fully stateless, we can maybe eliminate ImageContext as a parameter
|
||||
// in IMemoryImage constructors and just create the appropriate ImageContext objects automatically.
|
||||
/// <summary>
|
||||
/// Gets the image context used to create this image.
|
||||
/// </summary>
|
||||
|
6
NAPS2.Images/IPdfRendererProvider.cs
Normal file
6
NAPS2.Images/IPdfRendererProvider.cs
Normal file
@ -0,0 +1,6 @@
|
||||
namespace NAPS2.Images;
|
||||
|
||||
public interface IPdfRendererProvider
|
||||
{
|
||||
IPdfRenderer PdfRenderer { get; }
|
||||
}
|
@ -5,8 +5,6 @@ namespace NAPS2.Images;
|
||||
|
||||
public abstract class ImageContext
|
||||
{
|
||||
private readonly IPdfRenderer? _pdfRenderer;
|
||||
|
||||
public static ImageFileFormat GetFileFormatFromExtension(string path)
|
||||
{
|
||||
return Path.GetExtension(path).ToLowerInvariant() switch
|
||||
@ -43,40 +41,39 @@ public abstract class ImageContext
|
||||
};
|
||||
}
|
||||
|
||||
protected ImageContext(Type imageType, IPdfRenderer? pdfRenderer = null)
|
||||
protected ImageContext(Type imageType)
|
||||
{
|
||||
ImageType = imageType;
|
||||
_pdfRenderer = pdfRenderer;
|
||||
}
|
||||
|
||||
// TODO: Add NotNullWhen attribute?
|
||||
private bool MaybeRenderPdf(ImageFileStorage fileStorage, out IMemoryImage? renderedPdf)
|
||||
private bool MaybeRenderPdf(ImageFileStorage fileStorage, IPdfRenderer? pdfRenderer, out IMemoryImage? renderedPdf)
|
||||
{
|
||||
if (Path.GetExtension(fileStorage.FullPath).ToLowerInvariant() == ".pdf")
|
||||
{
|
||||
if (_pdfRenderer == null)
|
||||
if (pdfRenderer == null)
|
||||
{
|
||||
throw new InvalidOperationException(
|
||||
"Unable to render pdf page as the ImageContext wasn't created with an IPdfRenderer.");
|
||||
"Unable to render pdf page as the IRenderableImage didn't implement IPdfRendererProvider.");
|
||||
}
|
||||
renderedPdf = _pdfRenderer.Render(this, fileStorage.FullPath, PdfRenderSize.Default).Single();
|
||||
renderedPdf = pdfRenderer.Render(this, fileStorage.FullPath, PdfRenderSize.Default).Single();
|
||||
return true;
|
||||
}
|
||||
renderedPdf = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
private bool MaybeRenderPdf(ImageMemoryStorage memoryStorage, out IMemoryImage? renderedPdf)
|
||||
private bool MaybeRenderPdf(ImageMemoryStorage memoryStorage, IPdfRenderer? pdfRenderer, out IMemoryImage? renderedPdf)
|
||||
{
|
||||
if (memoryStorage.TypeHint == ".pdf")
|
||||
{
|
||||
if (_pdfRenderer == null)
|
||||
if (pdfRenderer == null)
|
||||
{
|
||||
throw new InvalidOperationException(
|
||||
"Unable to render pdf page as the ImageContext wasn't created with an IPdfRenderer.");
|
||||
"Unable to render pdf page as the IRenderableImage didn't implement IPdfRendererProvider.");
|
||||
}
|
||||
var stream = memoryStorage.Stream;
|
||||
renderedPdf = _pdfRenderer.Render(this, stream.GetBuffer(), (int) stream.Length, PdfRenderSize.Default)
|
||||
renderedPdf = pdfRenderer.Render(this, stream.GetBuffer(), (int) stream.Length, PdfRenderSize.Default)
|
||||
.Single();
|
||||
return true;
|
||||
}
|
||||
@ -239,22 +236,27 @@ public abstract class ImageContext
|
||||
|
||||
public IMemoryImage Render(IRenderableImage image)
|
||||
{
|
||||
var bitmap = RenderFromStorage(image.Storage);
|
||||
var bitmap = RenderWithoutTransforms(image);
|
||||
return PerformAllTransforms(bitmap, image.TransformState.Transforms);
|
||||
}
|
||||
|
||||
public IMemoryImage RenderFromStorage(IImageStorage storage)
|
||||
public IMemoryImage RenderWithoutTransforms(IRenderableImage image)
|
||||
{
|
||||
return RenderFromStorage(image.Storage, (image as IPdfRendererProvider)?.PdfRenderer);
|
||||
}
|
||||
|
||||
private IMemoryImage RenderFromStorage(IImageStorage storage, IPdfRenderer pdfRenderer)
|
||||
{
|
||||
switch (storage)
|
||||
{
|
||||
case ImageFileStorage fileStorage:
|
||||
if (MaybeRenderPdf(fileStorage, out var renderedPdf))
|
||||
if (MaybeRenderPdf(fileStorage, pdfRenderer, out var renderedPdf))
|
||||
{
|
||||
return renderedPdf!;
|
||||
}
|
||||
return Load(fileStorage.FullPath);
|
||||
case ImageMemoryStorage memoryStorage:
|
||||
if (MaybeRenderPdf(memoryStorage, out var renderedMemoryPdf))
|
||||
if (MaybeRenderPdf(memoryStorage, pdfRenderer, out var renderedMemoryPdf))
|
||||
{
|
||||
return renderedMemoryPdf!;
|
||||
}
|
||||
|
@ -18,7 +18,7 @@ public class ContextualTests : IDisposable
|
||||
FolderPath = Path.GetFullPath(Path.Combine("naps2_test_temp", Path.GetRandomFileName()));
|
||||
Folder = Directory.CreateDirectory(FolderPath);
|
||||
|
||||
ImageContext = TestImageContextFactory.Get(new PdfiumPdfRenderer());
|
||||
ImageContext = TestImageContextFactory.Get();
|
||||
ScanningContext = new ScanningContext(ImageContext);
|
||||
ScanningContext.TempFolderPath = Path.Combine(FolderPath, "temp");
|
||||
Directory.CreateDirectory(ScanningContext.TempFolderPath);
|
||||
|
@ -278,7 +278,7 @@ public class ImageSerializerTests : ContextualTests
|
||||
public async Task PdfDeserializeToMemoryStorage(StorageConfig config)
|
||||
{
|
||||
config.Apply(this);
|
||||
using var destContext = new ScanningContext(TestImageContextFactory.Get(new PdfiumPdfRenderer()));
|
||||
using var destContext = new ScanningContext(TestImageContextFactory.Get());
|
||||
|
||||
var importPath = Path.Combine(FolderPath, "import.pdf");
|
||||
File.WriteAllBytes(importPath, PdfResources.word_generated_pdf);
|
||||
@ -340,7 +340,7 @@ public class ImageSerializerTests : ContextualTests
|
||||
|
||||
private ScanningContext CreateDestContextWithFileStorage()
|
||||
{
|
||||
return new ScanningContext(TestImageContextFactory.Get(new PdfiumPdfRenderer()))
|
||||
return new ScanningContext(TestImageContextFactory.Get())
|
||||
{
|
||||
FileStorageManager = FileStorageManager.CreateFolder(Path.Combine(FolderPath, "dest"))
|
||||
};
|
||||
|
@ -2,18 +2,18 @@ namespace NAPS2.Sdk.Tests;
|
||||
|
||||
public static class TestImageContextFactory
|
||||
{
|
||||
public static ImageContext Get(IPdfRenderer pdfRenderer = null)
|
||||
public static ImageContext Get()
|
||||
{
|
||||
// TODO: For now we use ImageSharp on net6-windows for coverage. But eventually we'll need to do something
|
||||
// more comprehensive, i.e. set up some IMAGESHARP/SKIA compiler variables and have special test commands.
|
||||
#if MAC
|
||||
return new NAPS2.Images.Mac.MacImageContext(pdfRenderer);
|
||||
return new NAPS2.Images.Mac.MacImageContext();
|
||||
#elif LINUX
|
||||
return new NAPS2.Images.Gtk.GtkImageContext(pdfRenderer);
|
||||
return new NAPS2.Images.Gtk.GtkImageContext();
|
||||
#elif NET6_0_OR_GREATER
|
||||
return new NAPS2.Images.ImageSharp.ImageSharpImageContext(pdfRenderer);
|
||||
return new NAPS2.Images.ImageSharp.ImageSharpImageContext();
|
||||
#else
|
||||
return new NAPS2.Images.Gdi.GdiImageContext(pdfRenderer);
|
||||
return new NAPS2.Images.Gdi.GdiImageContext();
|
||||
#endif
|
||||
}
|
||||
}
|
@ -1,3 +1,5 @@
|
||||
using NAPS2.Pdf;
|
||||
|
||||
namespace NAPS2.Images;
|
||||
|
||||
/// <summary>
|
||||
@ -9,7 +11,7 @@ namespace NAPS2.Images;
|
||||
/// reference with Clone() that will need to be disposed, and the underlying image storage will only be disposed once
|
||||
/// all related instances are disposed (or the parent ScanningContext is disposed).
|
||||
/// </summary>
|
||||
public class ProcessedImage : IRenderableImage, IDisposable, IEquatable<ProcessedImage>
|
||||
public class ProcessedImage : IRenderableImage, IPdfRendererProvider, IDisposable, IEquatable<ProcessedImage>
|
||||
{
|
||||
private readonly RefCount.Token _token;
|
||||
private bool _disposed;
|
||||
@ -189,4 +191,6 @@ public class ProcessedImage : IRenderableImage, IDisposable, IEquatable<Processe
|
||||
/// at any moment.
|
||||
/// </param>
|
||||
public record WeakReference(ProcessedImage ProcessedImage);
|
||||
|
||||
IPdfRenderer IPdfRendererProvider.PdfRenderer => new PdfiumPdfRenderer();
|
||||
}
|
@ -17,7 +17,7 @@ public class ThumbnailRenderer
|
||||
|
||||
public IMemoryImage Render(ProcessedImage processedImage, int outputSize)
|
||||
{
|
||||
var image = _imageContext.RenderFromStorage(processedImage.Storage);
|
||||
var image = _imageContext.RenderWithoutTransforms(processedImage);
|
||||
var transformList = processedImage.TransformState.Transforms;
|
||||
if (!processedImage.TransformState.IsEmpty)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user