Feature/performance pdf (#426)

#  Added
- Added: Added series format information to the search typeahead to help identify duplicate series in libraries

# Fixed
- Fixed: Fixed accent color not looking well on light theme
- Fixed: Attempted to fix the memory issues with PDF reading on Docker. Uses a Memory Pool for streams and removes a bitmap operation for fixing books with transparent backgrounds (#424)

# Changed
- Changed: Refactored download logs to use the same download code as rest of Kavita 

# Dev stuff
- Added timeout for Regex's to make sure during matching, malicious filenames doesn't crash user system
- Refactored a missing GetCoverImage to use Series Format rather than old Library Type

==================================================
* Added Timeout for Regex matching to ensure malicious filenames don't crash system

* Refactored GetCoverImage to use series format rather than library type

* Refactored download logs to use the download service

* Fixed accent color not looking well on light theme

* Refactored series format into dedicated component and added to search results

* Switch to using MemoryManager for Streams to attempt to minimize GC pressure and reduced bitmap manipulation for transparency hack.
This commit is contained in:
Joseph Milazzo 2021-07-24 16:17:13 -05:00 committed by GitHub
parent 78ad01f5ae
commit 81dfd63250
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
21 changed files with 267 additions and 136 deletions

View file

@ -13,11 +13,13 @@ using API.Entities.Enums;
using API.Interfaces.Services;
using API.Parser;
using Docnet.Core;
using Docnet.Core.Converters;
using Docnet.Core.Models;
using Docnet.Core.Readers;
using ExCSS;
using HtmlAgilityPack;
using Microsoft.Extensions.Logging;
using Microsoft.IO;
using VersOne.Epub;
using Image = NetVips.Image;
using Point = System.Drawing.Point;
@ -28,6 +30,7 @@ namespace API.Services
{
private readonly ILogger<BookService> _logger;
private readonly StylesheetParser _cssParser = new ();
private static readonly RecyclableMemoryStreamManager StreamManager = new ();
public BookService(ILogger<BookService> logger)
{
@ -375,7 +378,6 @@ namespace API.Services
var pages = docReader.GetPageCount();
for (var pageNumber = 0; pageNumber < pages; pageNumber++)
{
using var pageReader = docReader.GetPageReader(pageNumber);
using var stream = GetPdfPage(docReader, pageNumber);
File.WriteAllBytes(Path.Combine(targetDirectory, "Page-" + pageNumber + ".png"), stream.ToArray());
}
@ -405,7 +407,7 @@ namespace API.Services
if (!createThumbnail) return coverImageContent.ReadContent();
using var stream = new MemoryStream(coverImageContent.ReadContent());
using var stream = StreamManager.GetStream("BookService.GetCoverImage", coverImageContent.ReadContent());
using var thumbnail = Image.ThumbnailStream(stream, MetadataService.ThumbnailWidth);
return thumbnail.WriteToBuffer(".jpg");
@ -447,23 +449,19 @@ namespace API.Services
private static MemoryStream GetPdfPage(IDocReader docReader, int pageNumber)
{
using var pageReader = docReader.GetPageReader(pageNumber);
var rawBytes = pageReader.GetImage();
var rawBytes = pageReader.GetImage(new NaiveTransparencyRemover());
var width = pageReader.GetPageWidth();
var height = pageReader.GetPageHeight();
using var doc = new Bitmap(width, height, PixelFormat.Format32bppArgb);
using var bmp = new Bitmap(width, height, PixelFormat.Format32bppArgb);
AddBytesToBitmap(bmp, rawBytes);
for (int y = 0; y < bmp.Height; y++)
// Removes 1px margin on left/right side after bitmap is copied out
for (var y = 0; y < bmp.Height; y++)
{
bmp.SetPixel(bmp.Width - 1, y, bmp.GetPixel(bmp.Width - 2, y));
}
using var g = Graphics.FromImage(doc);
g.FillRegion(Brushes.White, new Region(new Rectangle(0, 0, width, height)));
g.DrawImage(bmp, new Point(0, 0));
g.Save();
var stream = new MemoryStream();
doc.Save(stream, ImageFormat.Jpeg);
var stream = StreamManager.GetStream("BookService.GetPdfPage");
bmp.Save(stream, ImageFormat.Jpeg);
return stream;
}