Skip to content

Commit

Permalink
optimize code, fix typo in readme
Browse files Browse the repository at this point in the history
  • Loading branch information
skttl committed Jun 6, 2024
1 parent e1d8aec commit f937792
Show file tree
Hide file tree
Showing 9 changed files with 101 additions and 125 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ PM> Install-Package ImageSharp.Community.Formats.Pdf
using System.IO;

using SixLabors.ImageSharp;
using SixLabors.ImageSharp.Formats.Jpeg;
using SixLabors.ImageSharp.Formats.Png;
using SixLabors.ImageSharp.Processing;
using ImageSharpCommunity.Formats.Pdf;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
<RepositoryUrl>https://github.com/skttl/ImageSharpCommunity.Formats.Pdf</RepositoryUrl>
<RootNamespace>ImageSharpCommunity.Formats.Pdf</RootNamespace>
<Title>PDF Decoder for ImageSharp</Title>
<Version>0.1.0</Version>
<Version>0.2.0</Version>
</PropertyGroup>

<ItemGroup>
Expand Down
16 changes: 6 additions & 10 deletions src/ImageSharpCommunity.Formats.Pdf/PdfConfigurationModule.cs
Original file line number Diff line number Diff line change
@@ -1,15 +1,11 @@
using SixLabors.ImageSharp;
using SixLabors.ImageSharp.Formats;
namespace ImageSharpCommunity.Formats.Pdf;

namespace ImageSharpCommunity.Formats.Pdf
public sealed class PdfConfigurationModule : IImageFormatConfigurationModule
{
public sealed class PdfConfigurationModule : IImageFormatConfigurationModule
public void Configure(Configuration configuration)
{
public void Configure(Configuration configuration)
{
configuration.ImageFormatsManager.SetDecoder(PdfFormat.Instance, PdfDecoder.Instance);
configuration.ImageFormatsManager.SetEncoder(PdfFormat.Instance, new PdfEncoder());
configuration.ImageFormatsManager.AddImageFormatDetector(new PdfFormatDetector());
}
configuration.ImageFormatsManager.SetDecoder(PdfFormat.Instance, PdfDecoder.Instance);
configuration.ImageFormatsManager.SetEncoder(PdfFormat.Instance, new PdfEncoder());
configuration.ImageFormatsManager.AddImageFormatDetector(new PdfFormatDetector());
}
}
92 changes: 39 additions & 53 deletions src/ImageSharpCommunity.Formats.Pdf/PdfDecoder.cs
Original file line number Diff line number Diff line change
@@ -1,73 +1,59 @@
using PdfLibCore;
using SixLabors.ImageSharp;
using SixLabors.ImageSharp.Formats;
using SixLabors.ImageSharp.PixelFormats;
namespace ImageSharpCommunity.Formats.Pdf;

namespace ImageSharpCommunity.Formats.Pdf
public class PdfDecoder : SpecializedImageDecoder<PdfDecoderOptions>
{
public class PdfDecoder : SpecializedImageDecoder<PdfDecoderOptions>
private PdfDecoder()
{
private PdfDecoder()
{
}

/// <summary>
/// Gets the current instance.
/// </summary>
public static PdfDecoder Instance { get; } = new PdfDecoder();

protected override PdfDecoderOptions CreateDefaultSpecializedOptions(DecoderOptions options) => new() { GeneralOptions = options };

protected override Image<TPixel> Decode<TPixel>(PdfDecoderOptions options, Stream stream, CancellationToken cancellationToken)
{
ArgumentNullException.ThrowIfNull(options, nameof(options));
ArgumentNullException.ThrowIfNull(stream, nameof(stream));

using var pdfDocument = new PdfDocument(stream);
var page = pdfDocument?.Pages?.FirstOrDefault();
}

TryGetWidthAndHeight(page, out var width, out var height);
/// <summary>
/// Gets the current instance.
/// </summary>
public static PdfDecoder Instance { get; } = new PdfDecoder();

ArgumentNullException.ThrowIfNull(page, nameof(page));
protected override PdfDecoderOptions CreateDefaultSpecializedOptions(DecoderOptions options) => new() { GeneralOptions = options };

using var bitmap = new PdfiumBitmap(width, height, true);
page.Render(bitmap, PdfLibCore.Enums.PageOrientations.Normal, PdfLibCore.Enums.RenderingFlags.LcdText);
protected override Image<TPixel> Decode<TPixel>(PdfDecoderOptions options, Stream stream, CancellationToken cancellationToken)
{
ArgumentNullException.ThrowIfNull(options, nameof(options));
ArgumentNullException.ThrowIfNull(stream, nameof(stream));

var image = Image.Load<TPixel>(bitmap.AsBmpStream());
using var pdfDocument = new PdfDocument(stream);
var firstPageOfPdf = pdfDocument?.Pages?.FirstOrDefault();
ArgumentNullException.ThrowIfNull(firstPageOfPdf, nameof(firstPageOfPdf));

ScaleToTargetSize(options.GeneralOptions, image);
var (width, height) = GetDimensions(firstPageOfPdf);

return image;
}
using var bitmap = new PdfiumBitmap(width, height, true);
firstPageOfPdf.Render(bitmap, PdfLibCore.Enums.PageOrientations.Normal, PdfLibCore.Enums.RenderingFlags.LcdText);

protected override Image Decode(PdfDecoderOptions options, Stream stream, CancellationToken cancellationToken) => Decode<Rgba32>(options, stream, cancellationToken);
using var bmpStream = bitmap.AsBmpStream();
var image = Image.Load<TPixel>(bmpStream);

protected override ImageInfo Identify(DecoderOptions options, Stream stream, CancellationToken cancellationToken)
{
ArgumentNullException.ThrowIfNull(options, nameof(options));
ArgumentNullException.ThrowIfNull(stream, nameof(stream));
ScaleToTargetSize(options.GeneralOptions, image);

using var pdfDocument = new PdfDocument(stream);
var page = pdfDocument?.Pages?.FirstOrDefault();
TryGetWidthAndHeight(page, out int width, out int height);
return image;
}

return new ImageInfo(new PixelTypeInfo(4), new(width, height), null);
}
protected override Image Decode(PdfDecoderOptions options, Stream stream, CancellationToken cancellationToken) => Decode<Rgba32>(options, stream, cancellationToken);

private bool TryGetWidthAndHeight(PdfPage? page, out int width, out int height)
{
ArgumentNullException.ThrowIfNull(page, nameof(page));
protected override ImageInfo Identify(DecoderOptions options, Stream stream, CancellationToken cancellationToken)
{
ArgumentNullException.ThrowIfNull(options, nameof(options));
ArgumentNullException.ThrowIfNull(stream, nameof(stream));

var w = page.Size.Width;
w = w != 0 ? w / 72 * 144D : 0;
using var pdfDocument = new PdfDocument(stream);
var firstPageOfPdf = pdfDocument?.Pages?.FirstOrDefault();
ArgumentNullException.ThrowIfNull(firstPageOfPdf, nameof(firstPageOfPdf));

var h = page.Size.Height;
h = h != 0 ? h / 72 * 144D : 0;
var (width, height) = GetDimensions(firstPageOfPdf);

width = (int)w;
height = (int)h;
return new ImageInfo(new PixelTypeInfo(4), new(width, height), null);
}

return true;
}
private static (int width, int height) GetDimensions(PdfPage page)
{
ArgumentNullException.ThrowIfNull(page, nameof(page));
return ((int)page.Width, (int)page.Height);
}
}
11 changes: 4 additions & 7 deletions src/ImageSharpCommunity.Formats.Pdf/PdfDecoderOptions.cs
Original file line number Diff line number Diff line change
@@ -1,10 +1,7 @@
using SixLabors.ImageSharp.Formats;
namespace ImageSharpCommunity.Formats.Pdf;

namespace ImageSharpCommunity.Formats.Pdf
public sealed class PdfDecoderOptions : ISpecializedDecoderOptions
{
public sealed class PdfDecoderOptions : ISpecializedDecoderOptions
{
/// <inheritdoc/>
public DecoderOptions GeneralOptions { get; init; } = new();
}
/// <inheritdoc/>
public DecoderOptions GeneralOptions { get; init; } = new();
}
12 changes: 4 additions & 8 deletions src/ImageSharpCommunity.Formats.Pdf/PdfEncoder.cs
Original file line number Diff line number Diff line change
@@ -1,13 +1,9 @@
using SixLabors.ImageSharp;
using SixLabors.ImageSharp.Formats;
namespace ImageSharpCommunity.Formats.Pdf;

namespace ImageSharpCommunity.Formats.Pdf
public class PdfEncoder : ImageEncoder
{
public class PdfEncoder : ImageEncoder
protected override void Encode<TPixel>(Image<TPixel> image, Stream stream, CancellationToken cancellationToken)
{
protected override void Encode<TPixel>(Image<TPixel> image, Stream stream, CancellationToken cancellationToken)
{
throw new NotImplementedException();
}
throw new NotSupportedException("PDF encoding is not supported");
}
}
40 changes: 25 additions & 15 deletions src/ImageSharpCommunity.Formats.Pdf/PdfFormat.cs
Original file line number Diff line number Diff line change
@@ -1,23 +1,33 @@
using SixLabors.ImageSharp.Formats;
namespace ImageSharpCommunity.Formats.Pdf;

namespace ImageSharpCommunity.Formats.Pdf
public sealed class PdfFormat : IImageFormat
{
public sealed class PdfFormat : IImageFormat
private PdfFormat()
{
private PdfFormat()
{
}
}

/// <summary>
/// Gets the current instance.
/// </summary>
public static PdfFormat Instance { get; } = new();
public string Name => "PDF";
/// <summary>
/// Gets the current instance of the <see cref="PdfFormat"/>.
/// </summary>
public static PdfFormat Instance { get; } = new();

public string DefaultMimeType => "application/pdf";
/// <summary>
/// Gets the name of the image format.
/// </summary>
public string Name => "PDF";

public IEnumerable<string> MimeTypes => new[] { "application/pdf" };
/// <summary>
/// Gets the default MIME type of the image format.
/// </summary>
public string DefaultMimeType => "application/pdf";

public IEnumerable<string> FileExtensions => new[] { "pdf" };
}
/// <summary>
/// Gets the MIME types associated with the image format.
/// </summary>
public IEnumerable<string> MimeTypes { get; } = ImmutableArray.Create("application/pdf");

/// <summary>
/// Gets the file extensions associated with the image format.
/// </summary>
public IEnumerable<string> FileExtensions { get; } = ImmutableArray.Create("pdf");
}
45 changes: 15 additions & 30 deletions src/ImageSharpCommunity.Formats.Pdf/PdfFormatDetector.cs
Original file line number Diff line number Diff line change
@@ -1,36 +1,21 @@
using SixLabors.ImageSharp.Formats;
using System.Diagnostics.CodeAnalysis;
namespace ImageSharpCommunity.Formats.Pdf;

namespace ImageSharpCommunity.Formats.Pdf
public class PdfFormatDetector : IImageFormatDetector
{
public class PdfFormatDetector : IImageFormatDetector
{
public int HeaderSize => 16;

public bool TryDetectFormat(ReadOnlySpan<byte> header, [NotNullWhen(true)] out IImageFormat? format)
{
format = IsPDFFileFormat(header) ? PdfFormat.Instance : null;

return format != null;
}

private bool IsPDFFileFormat(ReadOnlySpan<byte> header)
{
if (header.Length >= 4)
{
var first4 = header[..4];
public int HeaderSize => 16;

var shouldMatch = new byte[]{
0x25, // %
0x50, // P
0x44, // D
0x46, // F
};

return first4.SequenceEqual(shouldMatch);
}
public bool TryDetectFormat(ReadOnlySpan<byte> header, [NotNullWhen(true)] out IImageFormat? format)
{
format = IsPDFFileFormat(header) ? PdfFormat.Instance : null;
return format != null;
}

return false;
}
private static bool IsPDFFileFormat(ReadOnlySpan<byte> header)
{
return header.Length >= 4 &&
header[0] == 0x25 && // %
header[1] == 0x50 && // P
header[2] == 0x44 && // D
header[3] == 0x46; // F
}
}
6 changes: 6 additions & 0 deletions src/ImageSharpCommunity.Formats.Pdf/Usings.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
global using PdfLibCore;
global using SixLabors.ImageSharp;
global using SixLabors.ImageSharp.Formats;
global using SixLabors.ImageSharp.PixelFormats;
global using System.Collections.Immutable;
global using System.Diagnostics.CodeAnalysis;

0 comments on commit f937792

Please sign in to comment.