JD2022-TU1/main/tools/modules/Orbit.Module/ViewModel/ImageManager.cs

168 lines
4.2 KiB
C#

// Copyright 2014-2018 Dirk Lemstra (https://github.com/dlemstra/MagickViewer)
//
// Licensed under the ImageMagick License (the "License"); you may not use this file except in
// compliance with the License. You may obtain a copy of the License at
//
// https://www.imagemagick.org/script/license.php
//
// Unless required by applicable law or agreed to in writing, software distributed under the
// License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
// express or implied. See the License for the specific language governing permissions and
// limitations under the License.
using System;
using System.IO;
using System.Threading;
using System.Threading.Tasks;
using ImageMagick;
namespace Orbit.Module.ViewModel
{
class ImageManager : IDisposable
{
private static readonly object Semaphore = new object();
private readonly ImageIterator _imageIterator;
private int _index;
private MagickImageCollection _images;
public event EventHandler<Exception> Loaded;
public event EventHandler Loading;
public ImageManager()
{
_imageIterator = new ImageIterator();
}
public string FileInfo
{
get
{
if (_imageIterator.Current == null)
return null;
string fileInfo = _imageIterator.Current.FullName;
if (_images != null)
{
if (_images.Count > 1)
fileInfo += " (" + (_index + 1) + " of " + _images.Count + ")";
if (Image != null)
fileInfo += "\n" + Image.Format.ToString().ToUpperInvariant() + "\n" + Image.Width + "x" + Image.Height;
}
return fileInfo;
}
}
public IMagickImage Image
{
get
{
if (_images.Count == 0)
return null;
return _images[_index];
}
}
public void Dispose()
{
DisposeImages();
}
public async Task Load(string fileName)
{
await Load(new FileInfo(fileName));
}
public async Task Next()
{
FileInfo file = _imageIterator.Next();
if (file != null)
await Load(file);
}
public void NextFrame()
{
if (_images.Count < 2)
return;
if (++_index == _images.Count)
_index = 0;
Loaded?.Invoke(this, null);
}
public async Task Previous()
{
FileInfo file = _imageIterator.Previous();
if (file != null)
await Load(file);
}
public void PreviousFrame()
{
if (_images.Count < 2)
return;
if (--_index == -1)
_index = _images.Count - 1;
Loaded?.Invoke(this, null);
}
private void ConstructImages()
{
DisposeImages();
_images = new MagickImageCollection();
_index = 0;
}
private void DisposeImages()
{
if (_images == null)
return;
_images.Dispose();
_images = null;
}
private async Task Load(FileInfo file)
{
Monitor.Enter(Semaphore);
Loading?.Invoke(this, null);
_imageIterator.Current = file;
var ex = await Task.Run(() => ReadImage(file));
Loaded?.Invoke(this, ex);
Monitor.Exit(Semaphore);
}
private Exception ReadImage(FileInfo file)
{
ConstructImages();
MagickErrorException exception = null;
try
{
MagickReadSettings settings = new MagickReadSettings();
_images.Read(file, settings);
foreach (var img in _images)
{
img.AutoOrient();
}
}
catch (MagickErrorException ex)
{
exception = ex;
}
return exception;
}
}
}