2022-08-08 04:31:38 +00:00
|
|
|
|
using System;
|
2016-04-21 22:37:40 +00:00
|
|
|
|
using System.Collections.Concurrent;
|
2020-03-30 10:49:23 +00:00
|
|
|
|
using System.Collections.Generic;
|
2014-07-14 11:03:52 +00:00
|
|
|
|
using System.IO;
|
2016-04-26 00:20:10 +00:00
|
|
|
|
using System.Linq;
|
2023-11-12 00:00:03 +00:00
|
|
|
|
using System.Threading;
|
2016-05-03 20:18:26 +00:00
|
|
|
|
using System.Threading.Tasks;
|
2014-07-14 11:03:52 +00:00
|
|
|
|
using System.Windows.Media;
|
|
|
|
|
|
using System.Windows.Media.Imaging;
|
2020-04-21 09:12:17 +00:00
|
|
|
|
using Flow.Launcher.Infrastructure.Logger;
|
|
|
|
|
|
using Flow.Launcher.Infrastructure.Storage;
|
2022-10-30 19:23:04 +00:00
|
|
|
|
using static Flow.Launcher.Infrastructure.Http.Http;
|
2014-07-14 11:03:52 +00:00
|
|
|
|
|
2020-08-05 09:57:23 +00:00
|
|
|
|
namespace Flow.Launcher.Infrastructure.Image
|
2014-07-14 11:03:52 +00:00
|
|
|
|
{
|
2016-04-26 01:40:23 +00:00
|
|
|
|
public static class ImageLoader
|
2014-07-14 11:03:52 +00:00
|
|
|
|
{
|
2022-08-09 00:35:38 +00:00
|
|
|
|
private static readonly ImageCache ImageCache = new();
|
2023-11-12 00:00:03 +00:00
|
|
|
|
private static SemaphoreSlim storageLock { get; } = new SemaphoreSlim(1, 1);
|
2022-10-30 19:39:57 +00:00
|
|
|
|
private static BinaryStorage<Dictionary<(string, bool), int>> _storage;
|
2022-08-09 00:35:38 +00:00
|
|
|
|
private static readonly ConcurrentDictionary<string, string> GuidToKey = new();
|
2020-01-03 19:16:17 +00:00
|
|
|
|
private static IImageHashGenerator _hashGenerator;
|
2022-08-09 00:35:38 +00:00
|
|
|
|
private static readonly bool EnableImageHash = true;
|
2022-11-26 16:16:04 +00:00
|
|
|
|
public static ImageSource MissingImage { get; } = new BitmapImage(new Uri(Constant.MissingImgIcon));
|
|
|
|
|
|
public static ImageSource LoadingImage { get; } = new BitmapImage(new Uri(Constant.LoadingImgIcon));
|
2022-11-26 17:17:13 +00:00
|
|
|
|
public const int SmallIconSize = 64;
|
2022-11-25 19:51:07 +00:00
|
|
|
|
public const int FullIconSize = 256;
|
2020-11-16 04:46:39 +00:00
|
|
|
|
|
2016-08-20 00:02:47 +00:00
|
|
|
|
|
2023-11-12 00:00:03 +00:00
|
|
|
|
private static readonly string[] ImageExtensions = { ".png", ".jpg", ".jpeg", ".gif", ".bmp", ".tiff", ".ico" };
|
2014-07-14 11:03:52 +00:00
|
|
|
|
|
2023-11-12 00:00:03 +00:00
|
|
|
|
public static async Task InitializeAsync()
|
2016-03-28 02:09:57 +00:00
|
|
|
|
{
|
2022-10-30 19:39:57 +00:00
|
|
|
|
_storage = new BinaryStorage<Dictionary<(string, bool), int>>("Image");
|
2020-01-03 19:16:17 +00:00
|
|
|
|
_hashGenerator = new ImageHashGenerator();
|
2020-03-30 10:49:23 +00:00
|
|
|
|
|
2023-11-12 00:00:03 +00:00
|
|
|
|
var usage = await LoadStorageToConcurrentDictionaryAsync();
|
2017-02-12 16:57:24 +00:00
|
|
|
|
|
2023-04-24 14:58:32 +00:00
|
|
|
|
ImageCache.Initialize(usage.ToDictionary(x => x.Key, x => x.Value));
|
|
|
|
|
|
|
2023-11-12 00:00:03 +00:00
|
|
|
|
foreach (var icon in new[] { Constant.DefaultIcon, Constant.MissingImgIcon })
|
2017-02-12 16:57:24 +00:00
|
|
|
|
{
|
|
|
|
|
|
ImageSource img = new BitmapImage(new Uri(icon));
|
|
|
|
|
|
img.Freeze();
|
2022-10-30 19:39:57 +00:00
|
|
|
|
ImageCache[icon, false] = img;
|
2017-02-12 16:57:24 +00:00
|
|
|
|
}
|
2020-05-01 09:58:48 +00:00
|
|
|
|
|
2022-10-30 19:23:04 +00:00
|
|
|
|
_ = Task.Run(async () =>
|
2017-02-12 16:57:24 +00:00
|
|
|
|
{
|
2022-10-30 19:23:04 +00:00
|
|
|
|
await Stopwatch.NormalAsync("|ImageLoader.Initialize|Preload images cost", async () =>
|
2017-02-12 16:57:24 +00:00
|
|
|
|
{
|
2024-01-22 18:06:14 +00:00
|
|
|
|
foreach (var ((path, isFullImage), _) in usage)
|
2017-02-12 16:57:24 +00:00
|
|
|
|
{
|
2022-10-30 19:39:57 +00:00
|
|
|
|
await LoadAsync(path, isFullImage);
|
2022-10-30 19:23:04 +00:00
|
|
|
|
}
|
2017-02-12 16:57:24 +00:00
|
|
|
|
});
|
2023-11-12 00:00:03 +00:00
|
|
|
|
Log.Info(
|
|
|
|
|
|
$"|ImageLoader.Initialize|Number of preload images is <{ImageCache.CacheSize()}>, Images Number: {ImageCache.CacheSize()}, Unique Items {ImageCache.UniqueImagesInCache()}");
|
2017-02-12 16:57:24 +00:00
|
|
|
|
});
|
2016-04-21 00:53:21 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
2023-11-12 00:00:03 +00:00
|
|
|
|
public static async Task Save()
|
2016-04-21 00:53:21 +00:00
|
|
|
|
{
|
2023-11-12 00:00:03 +00:00
|
|
|
|
await storageLock.WaitAsync();
|
|
|
|
|
|
|
|
|
|
|
|
try
|
2020-03-30 10:49:23 +00:00
|
|
|
|
{
|
2024-01-22 18:06:14 +00:00
|
|
|
|
await _storage.SaveAsync(ImageCache.EnumerateEntries()
|
2022-10-30 19:39:57 +00:00
|
|
|
|
.ToDictionary(
|
|
|
|
|
|
x => x.Key,
|
|
|
|
|
|
x => x.Value.usage));
|
2020-03-30 10:49:23 +00:00
|
|
|
|
}
|
2023-11-12 00:00:03 +00:00
|
|
|
|
finally
|
|
|
|
|
|
{
|
|
|
|
|
|
storageLock.Release();
|
|
|
|
|
|
}
|
2020-03-30 10:49:23 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
2023-11-12 00:00:03 +00:00
|
|
|
|
private static async Task<ConcurrentDictionary<(string, bool), int>> LoadStorageToConcurrentDictionaryAsync()
|
2020-03-30 10:49:23 +00:00
|
|
|
|
{
|
2023-11-12 00:00:03 +00:00
|
|
|
|
await storageLock.WaitAsync();
|
|
|
|
|
|
try
|
2020-03-30 10:49:23 +00:00
|
|
|
|
{
|
2023-11-12 00:00:03 +00:00
|
|
|
|
var loaded = await _storage.TryLoadAsync(new Dictionary<(string, bool), int>());
|
2020-03-30 10:49:23 +00:00
|
|
|
|
|
2022-10-30 19:39:57 +00:00
|
|
|
|
return new ConcurrentDictionary<(string, bool), int>(loaded);
|
2020-03-30 10:49:23 +00:00
|
|
|
|
}
|
2023-11-12 00:00:03 +00:00
|
|
|
|
finally
|
|
|
|
|
|
{
|
|
|
|
|
|
storageLock.Release();
|
|
|
|
|
|
}
|
2016-03-28 02:09:57 +00:00
|
|
|
|
}
|
2020-01-03 19:16:17 +00:00
|
|
|
|
|
|
|
|
|
|
private class ImageResult
|
|
|
|
|
|
{
|
|
|
|
|
|
public ImageResult(ImageSource imageSource, ImageType imageType)
|
|
|
|
|
|
{
|
|
|
|
|
|
ImageSource = imageSource;
|
|
|
|
|
|
ImageType = imageType;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public ImageType ImageType { get; }
|
|
|
|
|
|
public ImageSource ImageSource { get; }
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private enum ImageType
|
|
|
|
|
|
{
|
|
|
|
|
|
File,
|
|
|
|
|
|
Folder,
|
|
|
|
|
|
Data,
|
|
|
|
|
|
ImageFile,
|
2022-09-02 11:36:57 +00:00
|
|
|
|
FullImageFile,
|
2020-01-03 19:16:17 +00:00
|
|
|
|
Error,
|
|
|
|
|
|
Cache
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2022-10-30 19:23:04 +00:00
|
|
|
|
private static async ValueTask<ImageResult> LoadInternalAsync(string path, bool loadFullImage = false)
|
2014-07-14 11:03:52 +00:00
|
|
|
|
{
|
2020-05-02 11:12:34 +00:00
|
|
|
|
ImageResult imageResult;
|
|
|
|
|
|
|
2015-01-15 12:47:48 +00:00
|
|
|
|
try
|
2014-07-14 11:03:52 +00:00
|
|
|
|
{
|
2018-03-31 07:19:55 +00:00
|
|
|
|
if (string.IsNullOrEmpty(path))
|
2015-01-15 12:47:48 +00:00
|
|
|
|
{
|
2022-11-26 16:16:04 +00:00
|
|
|
|
return new ImageResult(MissingImage, ImageType.Error);
|
2016-05-03 22:21:03 +00:00
|
|
|
|
}
|
2022-11-24 06:31:00 +00:00
|
|
|
|
|
2024-01-22 18:06:14 +00:00
|
|
|
|
// extra scope for use of same variable name
|
2022-09-02 11:38:49 +00:00
|
|
|
|
{
|
2024-01-22 18:06:14 +00:00
|
|
|
|
if (ImageCache.TryGetValue(path, loadFullImage, out var imageSource))
|
|
|
|
|
|
{
|
|
|
|
|
|
return new ImageResult(imageSource, ImageType.Cache);
|
|
|
|
|
|
}
|
2022-09-02 11:38:49 +00:00
|
|
|
|
}
|
2022-11-24 06:31:00 +00:00
|
|
|
|
|
2022-10-30 19:23:04 +00:00
|
|
|
|
if (Uri.TryCreate(path, UriKind.RelativeOrAbsolute, out var uriResult)
|
|
|
|
|
|
&& (uriResult.Scheme == Uri.UriSchemeHttp || uriResult.Scheme == Uri.UriSchemeHttps))
|
2022-09-02 11:39:32 +00:00
|
|
|
|
{
|
2022-10-30 19:24:38 +00:00
|
|
|
|
var image = await LoadRemoteImageAsync(loadFullImage, uriResult);
|
2022-10-30 19:39:57 +00:00
|
|
|
|
ImageCache[path, loadFullImage] = image;
|
2022-09-21 16:02:39 +00:00
|
|
|
|
return new ImageResult(image, ImageType.ImageFile);
|
2022-09-02 11:39:32 +00:00
|
|
|
|
}
|
2023-11-12 00:00:03 +00:00
|
|
|
|
|
2016-05-03 20:18:26 +00:00
|
|
|
|
if (path.StartsWith("data:", StringComparison.OrdinalIgnoreCase))
|
2015-02-04 15:16:41 +00:00
|
|
|
|
{
|
2020-01-03 20:33:00 +00:00
|
|
|
|
var imageSource = new BitmapImage(new Uri(path));
|
|
|
|
|
|
imageSource.Freeze();
|
|
|
|
|
|
return new ImageResult(imageSource, ImageType.Data);
|
2015-02-04 15:16:41 +00:00
|
|
|
|
}
|
2018-03-31 07:19:55 +00:00
|
|
|
|
|
2022-11-23 07:03:15 +00:00
|
|
|
|
imageResult = await Task.Run(() => GetThumbnailResult(ref path, loadFullImage));
|
2020-05-02 11:12:34 +00:00
|
|
|
|
}
|
|
|
|
|
|
catch (System.Exception e)
|
|
|
|
|
|
{
|
|
|
|
|
|
try
|
|
|
|
|
|
{
|
2020-05-03 04:32:52 +00:00
|
|
|
|
// Get thumbnail may fail for certain images on the first try, retry again has proven to work
|
2020-05-02 11:12:34 +00:00
|
|
|
|
imageResult = GetThumbnailResult(ref path, loadFullImage);
|
|
|
|
|
|
}
|
|
|
|
|
|
catch (System.Exception e2)
|
2018-03-31 07:19:55 +00:00
|
|
|
|
{
|
2020-05-02 11:12:34 +00:00
|
|
|
|
Log.Exception($"|ImageLoader.Load|Failed to get thumbnail for {path} on first try", e);
|
|
|
|
|
|
Log.Exception($"|ImageLoader.Load|Failed to get thumbnail for {path} on second try", e2);
|
2020-01-03 19:16:17 +00:00
|
|
|
|
|
2022-10-30 19:39:57 +00:00
|
|
|
|
ImageSource image = ImageCache[Constant.MissingImgIcon, false];
|
|
|
|
|
|
ImageCache[path, false] = image;
|
2020-05-02 11:12:34 +00:00
|
|
|
|
imageResult = new ImageResult(image, ImageType.Error);
|
2018-03-31 07:19:55 +00:00
|
|
|
|
}
|
2020-05-02 11:12:34 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return imageResult;
|
|
|
|
|
|
}
|
2023-11-12 00:00:03 +00:00
|
|
|
|
|
2022-10-30 19:24:38 +00:00
|
|
|
|
private static async Task<BitmapImage> LoadRemoteImageAsync(bool loadFullImage, Uri uriResult)
|
|
|
|
|
|
{
|
|
|
|
|
|
// Download image from url
|
|
|
|
|
|
await using var resp = await GetStreamAsync(uriResult);
|
|
|
|
|
|
await using var buffer = new MemoryStream();
|
|
|
|
|
|
await resp.CopyToAsync(buffer);
|
|
|
|
|
|
buffer.Seek(0, SeekOrigin.Begin);
|
|
|
|
|
|
var image = new BitmapImage();
|
|
|
|
|
|
image.BeginInit();
|
|
|
|
|
|
image.CacheOption = BitmapCacheOption.OnLoad;
|
|
|
|
|
|
if (!loadFullImage)
|
|
|
|
|
|
{
|
|
|
|
|
|
image.DecodePixelHeight = SmallIconSize;
|
|
|
|
|
|
image.DecodePixelWidth = SmallIconSize;
|
|
|
|
|
|
}
|
2023-11-12 00:00:03 +00:00
|
|
|
|
|
2022-10-30 19:24:38 +00:00
|
|
|
|
image.StreamSource = buffer;
|
|
|
|
|
|
image.EndInit();
|
|
|
|
|
|
image.StreamSource = null;
|
|
|
|
|
|
image.Freeze();
|
|
|
|
|
|
return image;
|
|
|
|
|
|
}
|
2020-05-02 11:12:34 +00:00
|
|
|
|
|
|
|
|
|
|
private static ImageResult GetThumbnailResult(ref string path, bool loadFullImage = false)
|
|
|
|
|
|
{
|
|
|
|
|
|
ImageSource image;
|
|
|
|
|
|
ImageType type = ImageType.Error;
|
|
|
|
|
|
|
|
|
|
|
|
if (Directory.Exists(path))
|
|
|
|
|
|
{
|
|
|
|
|
|
/* Directories can also have thumbnails instead of shell icons.
|
2023-11-12 00:00:03 +00:00
|
|
|
|
* Generating thumbnails for a bunch of folder results while scrolling
|
|
|
|
|
|
* could have a big impact on performance and Flow.Launcher responsibility.
|
2020-05-02 11:12:34 +00:00
|
|
|
|
* - Solution: just load the icon
|
|
|
|
|
|
*/
|
|
|
|
|
|
type = ImageType.Folder;
|
|
|
|
|
|
image = GetThumbnail(path, ThumbnailOptions.IconOnly);
|
|
|
|
|
|
}
|
|
|
|
|
|
else if (File.Exists(path))
|
|
|
|
|
|
{
|
|
|
|
|
|
var extension = Path.GetExtension(path).ToLower();
|
|
|
|
|
|
if (ImageExtensions.Contains(extension))
|
2018-03-31 07:19:55 +00:00
|
|
|
|
{
|
2020-05-02 11:12:34 +00:00
|
|
|
|
type = ImageType.ImageFile;
|
|
|
|
|
|
if (loadFullImage)
|
2015-11-02 00:04:05 +00:00
|
|
|
|
{
|
2020-05-02 11:12:34 +00:00
|
|
|
|
image = LoadFullImage(path);
|
2022-09-02 11:37:25 +00:00
|
|
|
|
type = ImageType.FullImageFile;
|
2015-11-02 00:04:05 +00:00
|
|
|
|
}
|
2016-05-03 20:18:26 +00:00
|
|
|
|
else
|
2015-11-02 00:04:05 +00:00
|
|
|
|
{
|
2023-11-12 00:00:03 +00:00
|
|
|
|
/* Although the documentation for GetImage on MSDN indicates that
|
2020-05-02 11:12:34 +00:00
|
|
|
|
* if a thumbnail is available it will return one, this has proved to not
|
2023-11-12 00:00:03 +00:00
|
|
|
|
* be the case in many situations while testing.
|
2020-05-02 11:12:34 +00:00
|
|
|
|
* - Solution: explicitly pass the ThumbnailOnly flag
|
|
|
|
|
|
*/
|
|
|
|
|
|
image = GetThumbnail(path, ThumbnailOptions.ThumbnailOnly);
|
2015-11-02 00:04:05 +00:00
|
|
|
|
}
|
2016-05-03 20:18:26 +00:00
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
2020-05-02 11:12:34 +00:00
|
|
|
|
type = ImageType.File;
|
2022-11-25 19:51:07 +00:00
|
|
|
|
image = GetThumbnail(path, ThumbnailOptions.None, loadFullImage ? FullIconSize : SmallIconSize);
|
2020-01-03 19:16:17 +00:00
|
|
|
|
}
|
2016-05-03 20:18:26 +00:00
|
|
|
|
}
|
2020-05-02 11:12:34 +00:00
|
|
|
|
else
|
2018-03-31 07:19:55 +00:00
|
|
|
|
{
|
2022-10-30 19:39:57 +00:00
|
|
|
|
image = ImageCache[Constant.MissingImgIcon, false];
|
2020-09-06 20:55:12 +00:00
|
|
|
|
path = Constant.MissingImgIcon;
|
2020-05-02 11:12:34 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (type != ImageType.Error)
|
|
|
|
|
|
{
|
|
|
|
|
|
image.Freeze();
|
2018-03-31 07:19:55 +00:00
|
|
|
|
}
|
2020-05-01 09:58:48 +00:00
|
|
|
|
|
2020-01-03 19:16:17 +00:00
|
|
|
|
return new ImageResult(image, type);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2023-11-12 00:00:03 +00:00
|
|
|
|
private static BitmapSource GetThumbnail(string path, ThumbnailOptions option = ThumbnailOptions.ThumbnailOnly,
|
|
|
|
|
|
int size = SmallIconSize)
|
2020-05-02 11:12:34 +00:00
|
|
|
|
{
|
|
|
|
|
|
return WindowsThumbnailProvider.GetThumbnail(
|
|
|
|
|
|
path,
|
2022-11-25 19:51:07 +00:00
|
|
|
|
size,
|
|
|
|
|
|
size,
|
2020-05-02 11:12:34 +00:00
|
|
|
|
option);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2022-10-31 03:07:04 +00:00
|
|
|
|
public static bool CacheContainImage(string path, bool loadFullImage = false)
|
2020-11-15 12:45:00 +00:00
|
|
|
|
{
|
2022-12-29 03:17:29 +00:00
|
|
|
|
return ImageCache.ContainsKey(path, loadFullImage);
|
2020-11-15 12:45:00 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
2022-12-29 03:43:40 +00:00
|
|
|
|
public static bool TryGetValue(string path, bool loadFullImage, out ImageSource image)
|
|
|
|
|
|
{
|
|
|
|
|
|
return ImageCache.TryGetValue(path, loadFullImage, out image);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2022-10-30 19:23:04 +00:00
|
|
|
|
public static async ValueTask<ImageSource> LoadAsync(string path, bool loadFullImage = false)
|
2020-01-03 19:16:17 +00:00
|
|
|
|
{
|
2022-10-30 19:23:04 +00:00
|
|
|
|
var imageResult = await LoadInternalAsync(path, loadFullImage);
|
2020-01-03 19:16:17 +00:00
|
|
|
|
|
|
|
|
|
|
var img = imageResult.ImageSource;
|
|
|
|
|
|
if (imageResult.ImageType != ImageType.Error && imageResult.ImageType != ImageType.Cache)
|
2023-11-12 00:00:03 +00:00
|
|
|
|
{
|
|
|
|
|
|
// we need to get image hash
|
2020-08-05 09:30:45 +00:00
|
|
|
|
string hash = EnableImageHash ? _hashGenerator.GetHashFromImage(img) : null;
|
2020-01-03 19:16:17 +00:00
|
|
|
|
if (hash != null)
|
2020-01-03 20:33:00 +00:00
|
|
|
|
{
|
2020-08-05 09:30:45 +00:00
|
|
|
|
if (GuidToKey.TryGetValue(hash, out string key))
|
2023-11-12 00:00:03 +00:00
|
|
|
|
{
|
|
|
|
|
|
// image already exists
|
2023-04-07 03:00:44 +00:00
|
|
|
|
img = ImageCache[key, loadFullImage] ?? img;
|
2020-01-03 19:16:17 +00:00
|
|
|
|
}
|
|
|
|
|
|
else
|
2023-11-12 00:00:03 +00:00
|
|
|
|
{
|
|
|
|
|
|
// new guid
|
2022-09-02 12:36:07 +00:00
|
|
|
|
|
2020-08-05 09:30:45 +00:00
|
|
|
|
GuidToKey[hash] = path;
|
2020-01-03 19:16:17 +00:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// update cache
|
2022-12-28 07:07:26 +00:00
|
|
|
|
ImageCache[path, loadFullImage] = img;
|
2020-01-03 19:16:17 +00:00
|
|
|
|
}
|
2020-01-03 20:33:00 +00:00
|
|
|
|
|
2020-01-03 19:16:17 +00:00
|
|
|
|
return img;
|
2014-07-14 11:03:52 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
2018-03-31 07:19:55 +00:00
|
|
|
|
private static BitmapImage LoadFullImage(string path)
|
2016-08-20 12:10:33 +00:00
|
|
|
|
{
|
2018-03-31 07:19:55 +00:00
|
|
|
|
BitmapImage image = new BitmapImage();
|
|
|
|
|
|
image.BeginInit();
|
|
|
|
|
|
image.CacheOption = BitmapCacheOption.OnLoad;
|
2023-11-12 00:00:03 +00:00
|
|
|
|
image.UriSource = new Uri(path);
|
2022-10-19 05:39:27 +00:00
|
|
|
|
image.CreateOptions = BitmapCreateOptions.IgnoreColorProfile;
|
2018-03-31 07:19:55 +00:00
|
|
|
|
image.EndInit();
|
2022-12-06 14:04:18 +00:00
|
|
|
|
|
|
|
|
|
|
if (image.PixelWidth > 320)
|
|
|
|
|
|
{
|
|
|
|
|
|
BitmapImage resizedWidth = new BitmapImage();
|
|
|
|
|
|
resizedWidth.BeginInit();
|
|
|
|
|
|
resizedWidth.CacheOption = BitmapCacheOption.OnLoad;
|
|
|
|
|
|
resizedWidth.UriSource = new Uri(path);
|
|
|
|
|
|
resizedWidth.CreateOptions = BitmapCreateOptions.IgnoreColorProfile;
|
|
|
|
|
|
resizedWidth.DecodePixelWidth = 320;
|
|
|
|
|
|
resizedWidth.EndInit();
|
|
|
|
|
|
|
|
|
|
|
|
if (resizedWidth.PixelHeight > 320)
|
|
|
|
|
|
{
|
|
|
|
|
|
BitmapImage resizedHeight = new BitmapImage();
|
|
|
|
|
|
resizedHeight.BeginInit();
|
|
|
|
|
|
resizedHeight.CacheOption = BitmapCacheOption.OnLoad;
|
|
|
|
|
|
resizedHeight.UriSource = new Uri(path);
|
|
|
|
|
|
resizedHeight.CreateOptions = BitmapCreateOptions.IgnoreColorProfile;
|
|
|
|
|
|
resizedHeight.DecodePixelHeight = 320;
|
|
|
|
|
|
resizedHeight.EndInit();
|
|
|
|
|
|
return resizedHeight;
|
|
|
|
|
|
}
|
2023-11-12 00:00:03 +00:00
|
|
|
|
|
2022-12-06 14:04:18 +00:00
|
|
|
|
return resizedWidth;
|
|
|
|
|
|
}
|
2023-11-12 00:00:03 +00:00
|
|
|
|
|
2018-03-31 07:19:55 +00:00
|
|
|
|
return image;
|
2016-08-20 12:10:33 +00:00
|
|
|
|
}
|
|
|
|
|
|
}
|
2014-07-14 11:03:52 +00:00
|
|
|
|
}
|