Skip to content

Commit

Permalink
improve ShowImagePreview performance using cancel token
Browse files Browse the repository at this point in the history
  • Loading branch information
d2phap committed Sep 27, 2022
1 parent 604b3e6 commit a68d5c9
Show file tree
Hide file tree
Showing 2 changed files with 85 additions and 61 deletions.
60 changes: 37 additions & 23 deletions v9/Components/ImageGlass.Base/Photoing/Codecs/PhotoCodec.cs
Original file line number Diff line number Diff line change
Expand Up @@ -224,11 +224,15 @@ public static async Task<IgImgData> LoadAsync(string filePath,
/// <summary>
/// Gets embedded thumbnail.
/// </summary>
/// <param name="filePath">Full path of image file</param>
public static WicBitmapSource? GetEmbeddedThumbnail(string filePath)
public static WicBitmapSource? GetEmbeddedThumbnail(string filePath, bool rawThumbnail = true, bool exifThumbnail = true, CancellationToken token = default)
{
if (string.IsNullOrEmpty(filePath)) return null;


try
{
token.ThrowIfCancellationRequested();
}
catch (OperationCanceledException) { return null; }

var settings = ParseSettings(new() { FirstFrameOnly = true }, filePath);
WicBitmapSource? result = null;
Expand All @@ -238,38 +242,48 @@ public static async Task<IgImgData> LoadAsync(string filePath,


// get RAW embedded thumbnail
try
if (rawThumbnail)
{
var profile = imgM.GetProfile("dng:thumbnail");

// try to get thumbnail
var thumbnailData = profile?.GetData();
if (thumbnailData != null)
try
{
imgM.Read(thumbnailData, settings);
result = BHelper.ToWicBitmapSource(imgM.ToBitmapSource());
token.ThrowIfCancellationRequested();
var profile = imgM.GetProfile("dng:thumbnail");

// try to get thumbnail
var thumbnailData = profile?.GetData();
if (thumbnailData != null)
{
imgM.Read(thumbnailData, settings);
result = BHelper.ToWicBitmapSource(imgM.ToBitmapSource());
}
}
catch (OperationCanceledException) { return null; }
catch { }
}
catch { }



// Use JPEG embedded thumbnail
try
if (exifThumbnail)
{
var exifProfile = imgM.GetExifProfile();

// Fetch the embedded thumbnail
using var thumbM = exifProfile?.CreateThumbnail();
if (thumbM != null)
try
{
var ext = Path.GetExtension(filePath).ToLower();
ApplyRotation(thumbM, exifProfile, ext);
token.ThrowIfCancellationRequested();
var exifProfile = imgM.GetExifProfile();

// Fetch the embedded thumbnail
using var thumbM = exifProfile?.CreateThumbnail();
if (thumbM != null)
{
var ext = Path.GetExtension(filePath).ToLower();
ApplyRotation(thumbM, exifProfile, ext);

result = BHelper.ToWicBitmapSource(thumbM.ToBitmapSource());
result = BHelper.ToWicBitmapSource(thumbM.ToBitmapSource());
}
}
catch (OperationCanceledException) { return null; }
catch { }
}
catch { }


return result;
}
Expand Down
86 changes: 48 additions & 38 deletions v9/ImageGlass/FrmMain.cs
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@ public partial class FrmMain : Form
{
// cancellation tokens of synchronious task
private CancellationTokenSource _loadCancelToken = new();

private readonly MovableForm _movableForm;


Expand Down Expand Up @@ -914,6 +913,9 @@ private async Task ViewNextAsync(int step,

try
{
// check if loading is cancelled
token?.Token.ThrowIfCancellationRequested();

// apply image list settings
Local.Images.SinglePageFormats = Config.SinglePageFormats;
Local.Images.ReadOptions = readSettings;
Expand All @@ -925,9 +927,6 @@ private async Task ViewNextAsync(int step,
}
else
{
// check if loading is cancelled
token?.Token.ThrowIfCancellationRequested();

// directly load the image file, skip image list
if (photo != null)
{
Expand Down Expand Up @@ -1020,7 +1019,7 @@ private void Local_OnImageLoading(ImageLoadingEventArgs e)
// Select thumbnail item
_ = BHelper.RunAsThread(SelectCurrentThumbnail);

ShowImagePreview(e.FilePath);
ShowImagePreview(e.FilePath, _loadCancelToken.Token);

_ = Task.Run(() => UpdateImageInfo(ImageInfoUpdateTypes.All, e.FilePath));
}
Expand Down Expand Up @@ -1130,11 +1129,11 @@ private void Local_OnLastImageReached()
/// <summary>
/// Show image preview using the thumbnail
/// </summary>
private void ShowImagePreview(string filePath)
private void ShowImagePreview(string filePath, CancellationToken token = default)
{
if (InvokeRequired)
{
Invoke(ShowImagePreview, filePath);
Invoke(ShowImagePreview, filePath, token);
return;
}

Expand All @@ -1144,14 +1143,19 @@ private void ShowImagePreview(string filePath)

try
{
token.ThrowIfCancellationRequested();
var isImageBig = Local.Metadata.Width >= 4000 || Local.Metadata.Height >= 4000;

// get embedded thumbnail for preview
wicSrc = PhotoCodec.GetEmbeddedThumbnail(filePath);
wicSrc = PhotoCodec.GetEmbeddedThumbnail(filePath,
rawThumbnail: true, exifThumbnail: isImageBig, token: token);

// use thumbnail image for preview
if (wicSrc == null)
if (wicSrc == null && isImageBig)
{
if (Local.CurrentIndex >= 0 && Local.CurrentIndex < Gallery.Items.Count)
{
token.ThrowIfCancellationRequested();
var thumbnailPath = Gallery.Items[Local.CurrentIndex].FileName;
var thumb = Gallery.Items[Local.CurrentIndex].ThumbnailImage;

Expand All @@ -1163,48 +1167,54 @@ private void ShowImagePreview(string filePath)
}
}
}
catch (OperationCanceledException) { return; }
catch { }


if (wicSrc != null)
{
Size previewSize;

// get preview size
if (Config.ZoomMode == ZoomMode.LockZoom)
{
previewSize = new(Local.Metadata.Width, Local.Metadata.Height);
}
else
try
{
var zoomFactor = PicMain.CalculateZoomFactor(Config.ZoomMode, Local.Metadata.Width, Local.Metadata.Height);
Size previewSize;
token.ThrowIfCancellationRequested();

previewSize = new((int)(Local.Metadata.Width * zoomFactor), (int)(Local.Metadata.Height * zoomFactor));
}


// scale the preview image
if (wicSrc.Width < previewSize.Width || wicSrc.Height < previewSize.Height)
{
// sync interpolation mode for the preview
var interpolation = DirectN.WICBitmapInterpolationMode.WICBitmapInterpolationModeLinear;
if (PicMain.ZoomFactor > 1 &&
(PicMain.CurrentInterpolation == ImageInterpolation.HighQualityBicubic))
// get preview size
if (Config.ZoomMode == ZoomMode.LockZoom)
{
interpolation = DirectN.WICBitmapInterpolationMode.WICBitmapInterpolationModeNearestNeighbor;
previewSize = new(Local.Metadata.Width, Local.Metadata.Height);
}
else
{
var zoomFactor = PicMain.CalculateZoomFactor(Config.ZoomMode, Local.Metadata.Width, Local.Metadata.Height);

previewSize = new((int)(Local.Metadata.Width * zoomFactor), (int)(Local.Metadata.Height * zoomFactor));
}

wicSrc.Scale(previewSize.Width, previewSize.Height, interpolation);
}

// scale the preview image
if (wicSrc.Width < previewSize.Width || wicSrc.Height < previewSize.Height)
{
// sync interpolation mode for the preview
var interpolation = DirectN.WICBitmapInterpolationMode.WICBitmapInterpolationModeLinear;
if (PicMain.ZoomFactor > 1 &&
(PicMain.CurrentInterpolation == ImageInterpolation.HighQualityBicubic))
{
interpolation = DirectN.WICBitmapInterpolationMode.WICBitmapInterpolationModeNearestNeighbor;
}

token.ThrowIfCancellationRequested();
wicSrc.Scale(previewSize.Width, previewSize.Height, interpolation);
}

PicMain.SetImage(new()
{
Image = wicSrc,
CanAnimate = false,
FrameCount = 1,
});
token.ThrowIfCancellationRequested();
PicMain.SetImage(new()
{
Image = wicSrc,
CanAnimate = false,
FrameCount = 1,
});
}
catch (OperationCanceledException) { }
}
}

Expand Down

0 comments on commit a68d5c9

Please sign in to comment.