Changed GetDimensions to handle a stream at the end and one exit Switched to using Action? over IDlibDotNet for Tick method Switched to using AsReadOnly over new() Moved Meta Base to Shared
542 lines
27 KiB
C#
542 lines
27 KiB
C#
using System.Collections.ObjectModel;
|
|
using System.Drawing;
|
|
using System.Drawing.Imaging;
|
|
using System.Reflection;
|
|
using System.Runtime.InteropServices;
|
|
using System.Text;
|
|
using System.Text.Json;
|
|
using View_by_Distance.Metadata.Models;
|
|
using View_by_Distance.Property.Models;
|
|
using View_by_Distance.Property.Models.Stateless;
|
|
using View_by_Distance.Shared.Models;
|
|
using View_by_Distance.Shared.Models.Properties;
|
|
|
|
namespace View_by_Distance.Resize.Models;
|
|
|
|
/// <summary>
|
|
// Dictionary<string, int[]>
|
|
/// </summary>
|
|
public class C_Resize
|
|
{
|
|
|
|
public List<string> AngleBracketCollection { get; }
|
|
|
|
protected readonly string _FileNameExtension;
|
|
public string FileNameExtension => _FileNameExtension;
|
|
|
|
private readonly string _Original;
|
|
private readonly int _TempResolutionWidth;
|
|
private readonly int _TempResolutionHeight;
|
|
private readonly string[] _ValidResolutions;
|
|
private readonly ASCIIEncoding _ASCIIEncoding;
|
|
private readonly bool _OverrideForResizeImages;
|
|
private readonly ImageCodecInfo _ImageCodecInfo;
|
|
private readonly int _OutputResolutionWidthIndex;
|
|
private readonly bool _PropertiesChangedForResize;
|
|
private readonly ConstructorInfo _ConstructorInfo;
|
|
private readonly int _OutputResolutionHeightIndex;
|
|
private readonly EncoderParameters _EncoderParameters;
|
|
private readonly int _OutputResolutionOrientationIndex;
|
|
private readonly bool _ForceResizeLastWriteTimeToCreationTime;
|
|
private readonly IPropertyConfiguration _PropertyConfiguration;
|
|
private readonly JsonSerializerOptions _WriteIndentedJsonSerializerOptions;
|
|
private readonly ReadOnlyDictionary<byte, ReadOnlyCollection<string>>[] _ResultSingletonFileGroups;
|
|
|
|
public C_Resize(IPropertyConfiguration propertyConfiguration, bool forceResizeLastWriteTimeToCreationTime, bool overrideForResizeImages, bool propertiesChangedForResize, string[] validResolutions, ImageCodecInfo imageCodecInfo, EncoderParameters encoderParameters, string filenameExtension)
|
|
{
|
|
_Original = "Original";
|
|
_TempResolutionWidth = 3;
|
|
_TempResolutionHeight = 4;
|
|
_OutputResolutionWidthIndex = 0;
|
|
_ImageCodecInfo = imageCodecInfo;
|
|
_OutputResolutionHeightIndex = 1;
|
|
_ASCIIEncoding = new ASCIIEncoding();
|
|
_ValidResolutions = validResolutions;
|
|
_OutputResolutionOrientationIndex = 2;
|
|
_EncoderParameters = encoderParameters;
|
|
_FileNameExtension = filenameExtension;
|
|
AngleBracketCollection = [];
|
|
_PropertyConfiguration = propertyConfiguration;
|
|
_OverrideForResizeImages = overrideForResizeImages;
|
|
_PropertiesChangedForResize = propertiesChangedForResize;
|
|
_ForceResizeLastWriteTimeToCreationTime = forceResizeLastWriteTimeToCreationTime;
|
|
_ResultSingletonFileGroups = [new(new Dictionary<byte, ReadOnlyCollection<string>>())];
|
|
_WriteIndentedJsonSerializerOptions = new JsonSerializerOptions { WriteIndented = true };
|
|
ConstructorInfo? constructorInfo = typeof(PropertyItem).GetConstructor(BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Public, null, [], null) ?? throw new Exception();
|
|
_ConstructorInfo = constructorInfo;
|
|
}
|
|
|
|
public static byte[] GetBitmapData(Bitmap bitmap)
|
|
{
|
|
byte[] results;
|
|
#pragma warning disable CA1416
|
|
Rectangle rectangle = new(0, 0, bitmap.Width, bitmap.Height);
|
|
BitmapData bitmapData = bitmap.LockBits(rectangle, ImageLockMode.ReadOnly, bitmap.PixelFormat);
|
|
IntPtr intPtr = bitmapData.Scan0;
|
|
int length = bitmapData.Stride * bitmap.Height;
|
|
results = new byte[length];
|
|
Marshal.Copy(intPtr, results, 0, length);
|
|
bitmap.UnlockBits(bitmapData);
|
|
#pragma warning restore CA1416
|
|
return results;
|
|
}
|
|
|
|
public static (ImageCodecInfo imageCodecInfo, EncoderParameters encoderParameters, string filenameExtension) GetPngLowQuality()
|
|
{
|
|
(ImageCodecInfo, EncoderParameters, string) result;
|
|
#pragma warning disable CA1416
|
|
ImageFormat imageFormat = ImageFormat.Png;
|
|
ImageCodecInfo[] imageCodecInfoCollection = ImageCodecInfo.GetImageEncoders();
|
|
ImageCodecInfo imageCodecInfo = (from l in imageCodecInfoCollection where l.FormatID == imageFormat.Guid select l).First();
|
|
EncoderParameters encoderParameters = new(1);
|
|
encoderParameters.Param[0] = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, 75L);
|
|
if (string.IsNullOrEmpty(imageCodecInfo.FilenameExtension))
|
|
throw new NullReferenceException(nameof(imageCodecInfo.FilenameExtension));
|
|
result = new(imageCodecInfo, encoderParameters, imageCodecInfo.FilenameExtension.Split(';')[0].ToLower()[1..]);
|
|
#pragma warning restore CA1416
|
|
return result;
|
|
}
|
|
|
|
public static (ImageCodecInfo imageCodecInfo, EncoderParameters encoderParameters, string filenameExtension) GetJpegLowQuality()
|
|
{
|
|
(ImageCodecInfo, EncoderParameters, string) result;
|
|
#pragma warning disable CA1416
|
|
ImageFormat imageFormat = ImageFormat.Jpeg;
|
|
ImageCodecInfo[] imageCodecInfoCollection = ImageCodecInfo.GetImageEncoders();
|
|
ImageCodecInfo imageCodecInfo = (from l in imageCodecInfoCollection where l.FormatID == imageFormat.Guid select l).First();
|
|
EncoderParameters encoderParameters = new(1);
|
|
encoderParameters.Param[0] = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, 75L);
|
|
if (string.IsNullOrEmpty(imageCodecInfo.FilenameExtension))
|
|
throw new NullReferenceException(nameof(imageCodecInfo.FilenameExtension));
|
|
result = new(imageCodecInfo, encoderParameters, imageCodecInfo.FilenameExtension.Split(';')[0].ToLower()[1..]);
|
|
#pragma warning restore CA1416
|
|
return result;
|
|
}
|
|
|
|
public static (ImageCodecInfo imageCodecInfo, EncoderParameters encoderParameters, string filenameExtension) GetTuple(string outputExtension, int outputQuality)
|
|
{
|
|
(ImageCodecInfo, EncoderParameters, string) result;
|
|
#pragma warning disable CA1416
|
|
ImageFormat imageFormat = outputExtension switch
|
|
{
|
|
".gif" => ImageFormat.Gif,
|
|
".jfif" => ImageFormat.Jpeg,
|
|
".jpe" => ImageFormat.Jpeg,
|
|
".jpeg" => ImageFormat.Jpeg,
|
|
".jpg" => ImageFormat.Jpeg,
|
|
".png" => ImageFormat.Png,
|
|
".tif" => ImageFormat.Tiff,
|
|
".tiff" => ImageFormat.Tiff,
|
|
_ => throw new Exception(),
|
|
};
|
|
ImageCodecInfo[] imageCodecInfoCollection = ImageCodecInfo.GetImageEncoders();
|
|
ImageCodecInfo imageCodecInfo = (from l in imageCodecInfoCollection where l.FormatID == imageFormat.Guid select l).First();
|
|
EncoderParameters encoderParameters = new(1);
|
|
// encoderParameters.Param[0] = New EncoderParameter(Encoder.Quality, CType(75L, Int32)) 'Default
|
|
// encoderParameters.Param[0] = New EncoderParameter(Encoder.Quality, CType(95L, Int32)) 'Paint
|
|
encoderParameters.Param[0] = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, outputQuality);
|
|
if (string.IsNullOrEmpty(imageCodecInfo.FilenameExtension))
|
|
throw new NullReferenceException(nameof(imageCodecInfo.FilenameExtension));
|
|
result = new(imageCodecInfo, encoderParameters, imageCodecInfo.FilenameExtension.Split(';')[0].ToLower()[1..]);
|
|
#pragma warning restore CA1416
|
|
return result;
|
|
}
|
|
|
|
public FileHolder GetResizedFileHolder(string cResultsFullGroupDirectory, Item item, bool outputResolutionHasNumber, int id) =>
|
|
GetResizedFileHolder(cResultsFullGroupDirectory, item.FilePath, outputResolutionHasNumber, $"{id}{item.FilePath.ExtensionLowered}");
|
|
|
|
private FileHolder GetResizedFileHolder(string cResultsFullGroupDirectory, FilePath filePath, bool outputResolutionHasNumber, string fileName)
|
|
{
|
|
FileHolder result;
|
|
if (outputResolutionHasNumber)
|
|
result = Shared.Models.Stateless.Methods.IFileHolder.Get(Path.Combine(AngleBracketCollection[0].Replace("<>", _PropertyConfiguration.ResultContent), fileName));
|
|
else
|
|
{
|
|
CombinedEnumAndIndex cei = Shared.Models.Stateless.Methods.IPath.GetCombinedEnumAndIndex(_PropertyConfiguration, filePath);
|
|
result = Shared.Models.Stateless.Methods.IFileHolder.Get(Path.Combine(cResultsFullGroupDirectory, _PropertyConfiguration.ResultContent, cei.Combined, fileName));
|
|
}
|
|
return result;
|
|
}
|
|
|
|
public override string ToString()
|
|
{
|
|
string result = JsonSerializer.Serialize(this, new JsonSerializerOptions() { WriteIndented = true });
|
|
return result;
|
|
}
|
|
|
|
public void Update(string cResultsFullGroupDirectory)
|
|
{
|
|
ReadOnlyDictionary<string, ReadOnlyDictionary<byte, ReadOnlyCollection<string>>> keyValuePairs = Shared.Models.Stateless.Methods.IPath.GetKeyValuePairs(_PropertyConfiguration, cResultsFullGroupDirectory, [_PropertyConfiguration.ResultSingleton]);
|
|
foreach (KeyValuePair<string, ReadOnlyDictionary<byte, ReadOnlyCollection<string>>> keyValuePair in keyValuePairs)
|
|
{
|
|
if (keyValuePair.Key == _PropertyConfiguration.ResultSingleton)
|
|
_ResultSingletonFileGroups[0] = keyValuePair.Value;
|
|
else
|
|
throw new Exception();
|
|
}
|
|
}
|
|
|
|
public void SetAngleBracketCollection(string cResultsFullGroupDirectory, string sourceDirectory)
|
|
{
|
|
AngleBracketCollection.Clear();
|
|
AngleBracketCollection.AddRange(IResult.GetDirectoryInfoCollection(_PropertyConfiguration,
|
|
sourceDirectory,
|
|
cResultsFullGroupDirectory,
|
|
contentDescription: "Resized image",
|
|
singletonDescription: "Resize dimensions for each resolution",
|
|
collectionDescription: string.Empty,
|
|
converted: true));
|
|
}
|
|
|
|
public FileHolder GetResizedFileHolder(string cResultsFullGroupDirectory, Item item, bool outputResolutionHasNumber) =>
|
|
GetResizedFileHolder(cResultsFullGroupDirectory, item.FilePath, outputResolutionHasNumber, item.FilePath.Name);
|
|
|
|
public Dictionary<string, int[]> GetResizeKeyValuePairs(Configuration configuration, string cResultsFullGroupDirectory, FilePath filePath, List<Tuple<string, DateTime>> subFileTuples, List<string> parseExceptions, ExifDirectory exifDirectory, MappingFromItem mappingFromItem)
|
|
{
|
|
Dictionary<string, int[]>? results;
|
|
string json;
|
|
string[] changesFrom = [nameof(A_Property), nameof(B_Metadata)];
|
|
List<DateTime> dateTimes = (from l in subFileTuples where changesFrom.Contains(l.Item1) select l.Item2).ToList();
|
|
CombinedEnumAndIndex cei = Shared.Models.Stateless.Methods.IPath.GetCombinedEnumAndIndex(_PropertyConfiguration, filePath);
|
|
string fileName = $"{mappingFromItem.FilePath.NameWithoutExtension}{mappingFromItem.FilePath.ExtensionLowered}.json";
|
|
string directory = _ResultSingletonFileGroups[0][cei.Enum][cei.Index];
|
|
FileInfo fileInfo = new(Path.Combine(directory, fileName));
|
|
MoveIf(fileName, cei, directory, fileInfo);
|
|
if (_ForceResizeLastWriteTimeToCreationTime && !fileInfo.Exists && File.Exists(Path.ChangeExtension(fileInfo.FullName, ".delete")))
|
|
{
|
|
File.Move(Path.ChangeExtension(fileInfo.FullName, ".delete"), fileInfo.FullName);
|
|
fileInfo.Refresh();
|
|
}
|
|
if (_ForceResizeLastWriteTimeToCreationTime && fileInfo.Exists && fileInfo.LastWriteTime != fileInfo.CreationTime)
|
|
{
|
|
File.SetLastWriteTime(fileInfo.FullName, fileInfo.CreationTime);
|
|
fileInfo.Refresh();
|
|
}
|
|
if (_PropertiesChangedForResize)
|
|
results = null;
|
|
else if (!fileInfo.Exists)
|
|
results = null;
|
|
else if (!fileInfo.FullName.EndsWith(".json") && !fileInfo.FullName.EndsWith(".old"))
|
|
throw new ArgumentException("must be a *.json file");
|
|
else if (dateTimes.Count != 0 && dateTimes.Max() > fileInfo.LastWriteTime)
|
|
results = null;
|
|
else
|
|
{
|
|
json = File.ReadAllText(fileInfo.FullName);
|
|
try
|
|
{
|
|
results = JsonSerializer.Deserialize<Dictionary<string, int[]>>(json);
|
|
if (results is null)
|
|
throw new Exception();
|
|
subFileTuples.Add(new Tuple<string, DateTime>(nameof(C_Resize), fileInfo.LastWriteTime));
|
|
}
|
|
catch (Exception)
|
|
{
|
|
results = null;
|
|
parseExceptions.Add(nameof(C_Resize));
|
|
}
|
|
}
|
|
if (results is null)
|
|
{
|
|
results = GetImageResizes(exifDirectory);
|
|
json = JsonSerializer.Serialize(results, _WriteIndentedJsonSerializerOptions);
|
|
bool updateDateWhenMatches = dateTimes.Count != 0 && fileInfo.Exists && dateTimes.Max() > fileInfo.LastWriteTime;
|
|
DateTime? dateTime = !updateDateWhenMatches ? null : dateTimes.Max();
|
|
if (Shared.Models.Stateless.Methods.IPath.WriteAllText(fileInfo.FullName, json, updateDateWhenMatches, compareBeforeWrite: true, updateToWhenMatches: dateTime))
|
|
{
|
|
if (!_ForceResizeLastWriteTimeToCreationTime)
|
|
subFileTuples.Add(new Tuple<string, DateTime>(nameof(C_Resize), DateTime.Now));
|
|
else
|
|
{
|
|
File.SetLastWriteTime(fileInfo.FullName, fileInfo.CreationTime);
|
|
fileInfo.Refresh();
|
|
subFileTuples.Add(new Tuple<string, DateTime>(nameof(C_Resize), fileInfo.CreationTime));
|
|
}
|
|
}
|
|
}
|
|
return results;
|
|
}
|
|
|
|
private static void MoveIf(string fileName, CombinedEnumAndIndex cei, string directory, FileInfo fileInfo)
|
|
{
|
|
string[] segments = directory.Split(cei.Combined);
|
|
string? checkDirectory = segments.Length == 1 ?
|
|
Path.Combine(segments[0], $"{cei.Combined[2..]}") :
|
|
segments.Length == 2 ?
|
|
$"{segments[0]}{cei.Combined[2..]}{segments[1]}" :
|
|
null;
|
|
if (checkDirectory is not null && Directory.Exists(checkDirectory))
|
|
{
|
|
string checkFile = Path.Combine(checkDirectory, fileName);
|
|
if (File.Exists(checkFile))
|
|
{
|
|
File.Move(checkFile, fileInfo.FullName);
|
|
fileInfo.Refresh();
|
|
}
|
|
}
|
|
}
|
|
|
|
private Dictionary<string, int[]> GetImageResizes(ExifDirectory exifDirectory)
|
|
{
|
|
Dictionary<string, int[]> results = [];
|
|
int[] desired;
|
|
int checkWidth;
|
|
int checkHeight;
|
|
int desiredWidth;
|
|
int desiredHeight;
|
|
int? orientation = Shared.Models.Stateless.Methods.IMetaBase.GetOrientation(exifDirectory);
|
|
if (exifDirectory is null || orientation is null || exifDirectory.Width is null || exifDirectory.Height is null)
|
|
throw new NotSupportedException();
|
|
checkWidth = exifDirectory.Width.Value;
|
|
checkHeight = exifDirectory.Height.Value;
|
|
if (!_ValidResolutions.Contains(_Original))
|
|
results.Add(_Original, [checkWidth, checkHeight, orientation.Value]);
|
|
foreach (string validResolution in _ValidResolutions)
|
|
{
|
|
if (validResolution == _Original)
|
|
{
|
|
desiredWidth = checkWidth;
|
|
desiredHeight = checkHeight;
|
|
}
|
|
else
|
|
{
|
|
desired = GetCollection(validResolution);
|
|
desiredWidth = desired[0];
|
|
desiredHeight = desired[1];
|
|
}
|
|
if (checkWidth <= desiredWidth && checkHeight <= desiredHeight)
|
|
results.Add(validResolution, [checkWidth, checkHeight, orientation.Value]);
|
|
else
|
|
{
|
|
if (desiredWidth != desiredHeight)
|
|
{
|
|
if (checkWidth * desiredHeight > desiredWidth * checkHeight)
|
|
results.Add(validResolution, [desiredWidth, Convert.ToInt32(desiredWidth * checkHeight / (double)checkWidth), orientation.Value]);
|
|
else
|
|
results.Add(validResolution, [Convert.ToInt32(desiredHeight * checkWidth / (double)checkHeight), desiredHeight, orientation.Value]);
|
|
}
|
|
else
|
|
{
|
|
if (checkWidth * desiredHeight <= desiredWidth * checkHeight)
|
|
results.Add(validResolution, [desiredWidth, desiredHeight, orientation.Value, desiredWidth, Convert.ToInt32(desiredWidth * checkHeight / (double)checkWidth)]);
|
|
else
|
|
results.Add(validResolution, [desiredWidth, desiredHeight, orientation.Value, Convert.ToInt32(desiredHeight * checkWidth / (double)checkHeight), desiredHeight]);
|
|
}
|
|
}
|
|
}
|
|
return results;
|
|
}
|
|
|
|
private static int[] GetCollection(string outputResolution)
|
|
{
|
|
List<int> results = [];
|
|
string[] segments = outputResolution.Split('x');
|
|
results.Add(int.Parse(segments[0]));
|
|
results.Add(int.Parse(segments[1]));
|
|
return results.ToArray();
|
|
}
|
|
|
|
public void SaveResizedSubfile(Configuration configuration, string outputResolution, string cResultsFullGroupDirectory, List<Tuple<string, DateTime>> subFileTuples, Item item, ExifDirectory exifDirectory, MappingFromItem mappingFromItem, Dictionary<string, int[]> outputResolutionToResize)
|
|
{
|
|
if (mappingFromItem.ResizedFileHolder is null)
|
|
throw new NullReferenceException(nameof(mappingFromItem.ResizedFileHolder));
|
|
#pragma warning disable CA1854
|
|
if (!outputResolutionToResize.ContainsKey(_Original))
|
|
throw new Exception();
|
|
if (!outputResolutionToResize.ContainsKey(outputResolution))
|
|
throw new Exception();
|
|
#pragma warning restore CA1854
|
|
FileInfo fileInfo = new(mappingFromItem.ResizedFileHolder.FullName);
|
|
bool check = false;
|
|
int[] resize = outputResolutionToResize[outputResolution];
|
|
int outputResolutionWidth = resize[_OutputResolutionWidthIndex];
|
|
int outputResolutionHeight = resize[_OutputResolutionHeightIndex];
|
|
int outputResolutionOrientation = resize[_OutputResolutionOrientationIndex];
|
|
int[] originalCollection = outputResolutionToResize[_Original];
|
|
string[] changesFrom = [nameof(A_Property), nameof(B_Metadata), nameof(C_Resize)];
|
|
List<DateTime> dateTimes = (from l in subFileTuples where changesFrom.Contains(l.Item1) select l.Item2).ToList();
|
|
if (_OverrideForResizeImages)
|
|
check = true;
|
|
else if (!fileInfo.Exists)
|
|
check = true;
|
|
if (outputResolutionWidth == originalCollection[_OutputResolutionWidthIndex] && outputResolutionHeight == originalCollection[_OutputResolutionHeightIndex] && outputResolutionOrientation == originalCollection[_OutputResolutionOrientationIndex])
|
|
{
|
|
if (!check && dateTimes.Count != 0 && dateTimes.Max() > fileInfo.CreationTime.AddDays(1))
|
|
check = true;
|
|
if (check)
|
|
{
|
|
// if (fileInfo.Exists)
|
|
// File.Delete(fileInfo.FullName);
|
|
// File.Copy(mappingFromItem.FilePath.FullName, fileInfo.FullName);
|
|
// item.SetResizedFileHolder(_FileNameExtension, Shared.Models.Stateless.Methods.IFileHolder.Refresh(mappingFromItem.ResizedFileHolder));
|
|
// subFileTuples.Add(new Tuple<string, DateTime>(nameof(C_Resize), DateTime.Now));
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (!check && dateTimes.Count != 0 && dateTimes.Max() > fileInfo.LastWriteTime)
|
|
check = true;
|
|
if (check)
|
|
{
|
|
SaveResizedSubfile(exifDirectory, mappingFromItem, resize);
|
|
item.SetResizedFileHolder(_FileNameExtension, Shared.Models.Stateless.Methods.IFileHolder.Refresh(mappingFromItem.ResizedFileHolder));
|
|
subFileTuples.Add(new Tuple<string, DateTime>(nameof(C_Resize), DateTime.Now));
|
|
}
|
|
}
|
|
}
|
|
|
|
private void SaveResizedSubfile(ExifDirectory exifDirectory, MappingFromItem mappingFromItem, int[] resize)
|
|
{
|
|
string dateTimeFormat = IProperty.DateTimeFormat;
|
|
DateTime? dateTime = Shared.Models.Stateless.Methods.IDate.GetDateTimeOriginal(exifDirectory);
|
|
dateTime ??= Shared.Models.Stateless.Methods.IDate.GetMinimum(exifDirectory);
|
|
string dateTimeValue = dateTime.Value.ToString(dateTimeFormat);
|
|
byte[] bytes = _ASCIIEncoding.GetBytes(dateTimeValue);
|
|
if (_ASCIIEncoding.GetString(bytes, 0, bytes.Length) != dateTimeValue)
|
|
throw new Exception();
|
|
if (resize.Length == 3)
|
|
SaveResizedSubfile3(mappingFromItem, resize, bytes);
|
|
else if (resize.Length == 5)
|
|
SaveResizedSubfile5(mappingFromItem, resize, bytes);
|
|
else
|
|
throw new Exception();
|
|
}
|
|
|
|
private void SaveResizedSubfile3(MappingFromItem mappingFromItem, int[] resize, byte[] bytes)
|
|
{
|
|
Bitmap bitmap;
|
|
#pragma warning disable CA1416
|
|
int outputResolutionWidth = resize[_OutputResolutionWidthIndex];
|
|
using Bitmap temp = new(mappingFromItem.FilePath.FullName, useIcm: false);
|
|
int outputResolutionHeight = resize[_OutputResolutionHeightIndex];
|
|
PropertyItem[] propertyItems = temp.PropertyItems;
|
|
int outputResolutionOrientation = resize[_OutputResolutionOrientationIndex];
|
|
bitmap = new(temp, outputResolutionWidth, outputResolutionHeight);
|
|
switch (outputResolutionOrientation) // exif 274
|
|
{
|
|
case 0:
|
|
break;
|
|
case 1:
|
|
break; // 1 = Horizontal (normal)
|
|
case 2:
|
|
bitmap.RotateFlip(RotateFlipType.RotateNoneFlipX);
|
|
break; // 2 = Mirror horizontal
|
|
case 3:
|
|
bitmap.RotateFlip(RotateFlipType.Rotate180FlipNone);
|
|
break; // 3 = Rotate 180
|
|
case 4:
|
|
bitmap.RotateFlip(RotateFlipType.RotateNoneFlipY);
|
|
break; // 4 = Mirror vertical
|
|
case 5:
|
|
bitmap.RotateFlip(RotateFlipType.Rotate270FlipX);
|
|
break; // 5 = Mirror horizontal and rotate 270 CW
|
|
case 6:
|
|
bitmap.RotateFlip(RotateFlipType.Rotate90FlipNone);
|
|
break; // 6 = Rotate 90 CW
|
|
case 7:
|
|
bitmap.RotateFlip(RotateFlipType.Rotate90FlipX);
|
|
break; // 7 = Mirror horizontal and rotate 90 CW
|
|
case 8:
|
|
bitmap.RotateFlip(RotateFlipType.Rotate270FlipNone);
|
|
break; // 8 = Rotate 270 CW
|
|
default:
|
|
break;
|
|
}
|
|
CopyPropertyItems(bytes, propertyItems, bitmap);
|
|
bitmap.Save(mappingFromItem.ResizedFileHolder.FullName, _ImageCodecInfo, _EncoderParameters);
|
|
bitmap.Dispose();
|
|
#pragma warning restore CA1416
|
|
}
|
|
|
|
private void CopyPropertyItems(byte[] bytes, PropertyItem[] propertyItems, Bitmap bitmap)
|
|
{
|
|
bool hasId = false;
|
|
int id = MetadataExtractor.Formats.Exif.ExifDirectoryBase.TagDateTimeDigitized;
|
|
int imageWidth = MetadataExtractor.Formats.Exif.ExifDirectoryBase.TagImageWidth;
|
|
int imageHeight = MetadataExtractor.Formats.Exif.ExifDirectoryBase.TagImageHeight;
|
|
int orientation = MetadataExtractor.Formats.Exif.ExifDirectoryBase.TagOrientation;
|
|
#pragma warning disable CA1416
|
|
foreach (PropertyItem propertyItem in propertyItems)
|
|
{
|
|
if (propertyItem.Id == id)
|
|
hasId = true;
|
|
else if (propertyItem.Id == imageWidth)
|
|
continue;
|
|
else if (propertyItem.Id == imageHeight)
|
|
continue;
|
|
else if (propertyItem.Id == orientation)
|
|
continue;
|
|
bitmap.SetPropertyItem(propertyItem);
|
|
}
|
|
if (!hasId)
|
|
{
|
|
PropertyItem propertyItem = (PropertyItem)_ConstructorInfo.Invoke(null);
|
|
propertyItem.Id = id;
|
|
propertyItem.Len = bytes.Length;
|
|
propertyItem.Type = 2;
|
|
propertyItem.Value = bytes;
|
|
bitmap.SetPropertyItem(propertyItem);
|
|
}
|
|
#pragma warning restore CA1416
|
|
}
|
|
|
|
private void SaveResizedSubfile5(MappingFromItem mappingFromItem, int[] resize, byte[] bytes)
|
|
{
|
|
Bitmap bitmap;
|
|
#pragma warning disable CA1416
|
|
using Bitmap temp = new(mappingFromItem.FilePath.FullName, useIcm: false);
|
|
PropertyItem[] propertyItems = temp.PropertyItems;
|
|
int tempResolutionWidth = resize[_TempResolutionWidth];
|
|
int tempResolutionHeight = resize[_TempResolutionHeight];
|
|
int outputResolutionWidth = resize[_OutputResolutionWidthIndex];
|
|
int outputResolutionHeight = resize[_OutputResolutionHeightIndex];
|
|
int outputResolutionOrientation = resize[_OutputResolutionOrientationIndex];
|
|
bitmap = new(temp, tempResolutionWidth, tempResolutionHeight);
|
|
switch (outputResolutionOrientation) // exif 274
|
|
{
|
|
case 0:
|
|
break;
|
|
case 1:
|
|
break; // 1 = Horizontal (normal)
|
|
case 2:
|
|
bitmap.RotateFlip(RotateFlipType.RotateNoneFlipX);
|
|
break; // 2 = Mirror horizontal
|
|
case 3:
|
|
bitmap.RotateFlip(RotateFlipType.Rotate180FlipNone);
|
|
break; // 3 = Rotate 180
|
|
case 4:
|
|
bitmap.RotateFlip(RotateFlipType.RotateNoneFlipY);
|
|
break; // 4 = Mirror vertical
|
|
case 5:
|
|
bitmap.RotateFlip(RotateFlipType.Rotate270FlipX);
|
|
break; // 5 = Mirror horizontal and rotate 270 CW
|
|
case 6:
|
|
bitmap.RotateFlip(RotateFlipType.Rotate90FlipNone);
|
|
break; // 6 = Rotate 90 CW
|
|
case 7:
|
|
bitmap.RotateFlip(RotateFlipType.Rotate90FlipX);
|
|
break; // 7 = Mirror horizontal and rotate 90 CW
|
|
case 8:
|
|
bitmap.RotateFlip(RotateFlipType.Rotate270FlipNone);
|
|
break; // 8 = Rotate 270 CW
|
|
default:
|
|
break;
|
|
}
|
|
Bitmap preRotated;
|
|
Rectangle rectangle;
|
|
if (tempResolutionHeight < tempResolutionWidth)
|
|
rectangle = new Rectangle((int)((tempResolutionWidth - outputResolutionWidth) * .5), 0, outputResolutionWidth, outputResolutionHeight);
|
|
else
|
|
rectangle = new Rectangle(0, (int)((tempResolutionHeight - outputResolutionHeight) * .5), outputResolutionWidth, outputResolutionHeight);
|
|
using (preRotated = new Bitmap(outputResolutionWidth, outputResolutionHeight))
|
|
{
|
|
using (Graphics graphics = Graphics.FromImage(preRotated))
|
|
graphics.DrawImage(bitmap, new Rectangle(0, 0, outputResolutionWidth, outputResolutionHeight), rectangle, GraphicsUnit.Pixel);
|
|
CopyPropertyItems(bytes, propertyItems, bitmap);
|
|
bitmap.Save(mappingFromItem.ResizedFileHolder.FullName, _ImageCodecInfo, _EncoderParameters);
|
|
}
|
|
bitmap.Dispose();
|
|
#pragma warning restore CA1416
|
|
}
|
|
|
|
} |