168 lines
4.2 KiB
C#
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;
|
|
}
|
|
}
|
|
}
|