| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081 |
- using System.Collections.Concurrent;
- using System.IO;
- using System.Linq;
- using QuestPDF.Drawing.Exceptions;
- using QuestPDF.Skia;
- namespace QuestPDF.Infrastructure;
- static class StaticImageCache
- {
- private static bool CacheIsEnabled { get; set; } = true;
- private static ConcurrentDictionary<string, Image> Items { get; set; } = new();
- private const int MaxCacheSize = 25_000_000;
- private const int MaxItemSize = 1_000_000;
-
- public static Image Load(string filePath)
- {
- var isPathRooted = Path.IsPathRooted(filePath);
-
- // check fallback path
- if (!File.Exists(filePath))
- {
- var fallbackPath = Path.Combine(Helpers.Helpers.ApplicationFilesPath, filePath);
- if (!File.Exists(fallbackPath))
- throw new DocumentComposeException($"Cannot load provided image, file not found: {filePath}");
- filePath = fallbackPath;
- }
-
- if (isPathRooted)
- return LoadImage(filePath, false);
-
- // check file size
- var fileInfo = new FileInfo(filePath);
-
- if (fileInfo.Length > MaxItemSize)
- return LoadImage(filePath, false);
-
- // check if the image is already in cache
- if (Items.TryGetValue(filePath, out var cacheItem))
- return cacheItem;
-
- // if cache is larger than expected, the usage might be different from loading static images
- if (!CacheIsEnabled)
- return LoadImage(filePath, false);
-
- // create new cache item and add it to the cache
- var image = LoadImage(filePath, true);
- Items.TryAdd(filePath, image);
-
- // check cache size
- CacheIsEnabled = Items.Values.Sum(x => x.SkImage.EncodedDataSize) < MaxCacheSize;
-
- // return cached value
- return image;
- }
-
- private static Image LoadImage(string filePath, bool isShared)
- {
- using var imageData = SkData.FromFile(filePath);
- return DecodeImage(imageData, isShared);
- }
-
- public static Image DecodeImage(SkData imageData, bool isShared)
- {
- try
- {
- var skImage = SkImage.FromData(imageData);
- var image = new Image(skImage);
- image.IsShared = isShared;
-
- return image;
- }
- catch
- {
- throw new DocumentComposeException("Cannot decode the provided image.");
- }
- }
- }
|