This commit is contained in:
John Andrews
2024-05-06 21:52:14 +12:00
parent c25e454d20
commit d6c2034d8e
4 changed files with 132 additions and 52 deletions
+101 -18
View File
@@ -1,4 +1,5 @@
using System.ComponentModel;
using System.Diagnostics;
using FileFlows.Plugin.Helpers;
namespace FileFlows.ComicNodes.Comics;
@@ -154,7 +155,7 @@ public class ComicConverter: Node
if (Codec.ToLowerInvariant() is "webp" or "jpeg")
{
args.Logger?.ILog("Converting images to: " + Codec);
var rgxImages = new Regex(@"\.(jpeg|jpg|jpe|png|bmp|tiff|webp|gif)$", RegexOptions.IgnoreCase);
var rgxImages = new Regex(@"\.(jpeg|jpg|jp2|jpe|png|bmp|tiff|webp|gif)$", RegexOptions.IgnoreCase);
var files = Directory.GetFiles(destinationPath, "*.*", SearchOption.AllDirectories);
ImageOptions imageOptions = new()
{
@@ -165,10 +166,13 @@ public class ComicConverter: Node
args.Logger?.ILog("Quality: " + Quality);
args.Logger?.ILog("MaxWidth: " + MaxWidth);
args.Logger?.ILog("MaxHeight: " + MaxHeight);
args.Logger?.ILog("Total Files: " + files.Length);
args.PartPercentageUpdate?.Invoke(0);
int count = 0;
foreach (string file in files)
for (int i = 0; i < files.Length; i++)
{
var file = files[i];
if (cancellation.IsCancellationRequested)
break;
try
@@ -183,23 +187,47 @@ public class ComicConverter: Node
continue;
}
if (rgxImages.IsMatch(file))
{
args.Logger?.ILog("Converting image: " + file);
string dest;
if (Codec.ToLowerInvariant() == "webp")
{
dest = Path.ChangeExtension(file, "webp");
args.ImageHelper.ConvertToWebp(file, dest, imageOptions);
}
else
{
dest = Path.ChangeExtension(file, "jpg");
args.ImageHelper.ConvertToJpeg(file, dest, imageOptions);
}
// if (file.ToLowerInvariant().EndsWith(".jp2"))
// {
// // special case
// if (ConvertJp2ToJpeg(args.Logger, ref file) == false)
// {
// args.FailureReason =
// "JPEG 2000 File detected which is only supported if ImageMagick is installed.";
// args.Logger?.ELog(args.FailureReason);
// break;
// }
// }
if (File.Exists(dest) && File.Exists(file) && file != dest)
File.Delete(file);
if (rgxImages.IsMatch(file) == false)
continue;
DateTime dt = DateTime.UtcNow;
string dest;
if (Codec.ToLowerInvariant() == "webp")
{
dest = Path.ChangeExtension(file, "webp");
args.ImageHelper.ConvertToWebp(file, dest, imageOptions);
}
else
{
dest = Path.ChangeExtension(file, "jpg");
args.ImageHelper.ConvertToJpeg(file, dest, imageOptions);
}
if (File.Exists(dest) == false)
{
args.FailureReason = "Failed to convert image: " + dest;
args.Logger?.ELog(args.FailureReason);
break;
}
args.Logger?.ILog($"Converted image [{DateTime.UtcNow.Subtract(dt)}]: {dest}");
if (File.Exists(file) && file != dest)
{
args.Logger?.ILog("Deleting file: " + file);
File.Delete(file);
}
}
finally
@@ -207,6 +235,7 @@ public class ComicConverter: Node
float total = files.Length;
args.PartPercentageUpdate?.Invoke((count++ / total) * 100);
}
}
}
@@ -219,6 +248,60 @@ public class ComicConverter: Node
return 1;
}
/// <summary>
/// Tries to use imagemagick to convert an image to JPEG
/// </summary>
/// <param name="logger">The logger</param>
/// <param name="file">the file to convert</param>
/// <returns>true if converted</returns>
private bool ConvertJp2ToJpeg(ILogger logger, ref string file)
{
try
{
string outFile = Path.ChangeExtension(file, "jpg");
// Start the ImageMagick convert process
ProcessStartInfo startInfo = new ProcessStartInfo
{
FileName = "convert", // ImageMagick's convert command
ArgumentList = { file, outFile },
RedirectStandardOutput = true,
RedirectStandardError = true,
UseShellExecute = false,
CreateNoWindow = true
};
using Process process = Process.Start(startInfo);
// Capture output
string output = process.StandardOutput.ReadToEnd();
string error = process.StandardError.ReadToEnd();
process.WaitForExit();
// Check for errors
if (string.IsNullOrEmpty(error) == false)
{
logger?.ELog($"Error occurred: {error}");
return false;
}
logger?.ILog("Converted JPEG 2000 File: " + file);
File.Delete(file);
file = outFile;
// Conversion successful
return true;
}
catch (Exception ex)
{
logger.ELog($"An error occurred converted the JPEG 2000 image: {ex.Message}");
return false;
}
}
/// <summary>
/// Cancels the conversion
+31 -34
View File
@@ -1,8 +1,6 @@
using System.Xml;
using FileFlows.ComicNodes.Helpers;
using Microsoft.VisualStudio.TestPlatform.Utilities.Helpers;
using FileHelper = FileFlows.Plugin.Helpers.FileHelper;
using Path = SixLabors.ImageSharp.Drawing.Path;
namespace FileFlows.ComicNodes.Comics;
@@ -68,6 +66,34 @@ public class CreateComicInfo : Node
}
args.Logger?.ILog("Got ComicInfo from filename");
var newMetadata = new Dictionary<string, object>
{
{ nameof(info.Value.Title), info.Value.Title },
{ nameof(info.Value.Series), info.Value.Series },
{ nameof(info.Value.Publisher), info.Value.Publisher },
{ nameof(info.Value.Number), info.Value.Number },
{ nameof(info.Value.Count), info.Value.Count },
{ nameof(info.Value.Volume), info.Value.Volume },
{ nameof(info.Value.AlternateSeries), info.Value.AlternateSeries },
{ nameof(info.Value.AlternateNumber), info.Value.AlternateNumber },
{ nameof(info.Value.AlternateCount), info.Value.AlternateCount },
{ nameof(info.Value.Summary), info.Value.Summary },
{ nameof(info.Value.Notes), info.Value.Notes },
{ nameof(info.Value.ReleaseDate), info.Value.ReleaseDate },
{ nameof(info.Value.Tags), info.Value.Tags?.Any() == true ? string.Join(", ", info.Value.Tags) : null }
}.Where(x => x.Value != null)
.ToDictionary(x => x.Key, x => x.Value);
if (args.Metadata != null)
{
foreach (var key in args.Metadata.Keys)
{
if (newMetadata.ContainsKey(key))
continue;
newMetadata[key] = args.Metadata[key];
}
}
string xml = SerializeToXml(info.Value);
if (string.IsNullOrWhiteSpace(xml))
{
@@ -199,19 +225,7 @@ public class CreateComicInfo : Node
Encoding = Encoding.UTF8
});
writer.WriteStartDocument();
writer.WriteStartElement("xs", "schema", "http://www.w3.org/2001/XMLSchema");
writer.WriteAttributeString("elementFormDefault", "qualified");
writer.WriteStartElement("xs", "element", null);
writer.WriteAttributeString("name", "ComicInfo");
writer.WriteAttributeString("nillable", "true");
writer.WriteAttributeString("type", "ComicInfo");
writer.WriteEndElement();
writer.WriteStartElement("xs", "complexType", null);
writer.WriteAttributeString("name", "ComicInfo");
writer.WriteStartElement("xs", "sequence", null);
writer.WriteStartElement("ComicInfo", "http://www.w3.org/2001/XMLSchema");
WriteXmlElement(writer, "Title", comicInfo.Title);
WriteXmlElement(writer, "Series", comicInfo.Series);
@@ -233,9 +247,7 @@ public class CreateComicInfo : Node
WriteXmlElement(writer, "Day", comicInfo.ReleaseDate.Value.Day.ToString());
}
writer.WriteEndElement(); // Close sequence
writer.WriteEndElement(); // Close complexType
writer.WriteEndElement(); // Close schema
writer.WriteEndElement(); // Close ComicInfo
writer.WriteEndDocument();
writer.Flush();
@@ -253,23 +265,8 @@ public class CreateComicInfo : Node
if (value == null)
return;
writer.WriteStartElement("xs", "element", null);
writer.WriteAttributeString("minOccurs", "0");
writer.WriteAttributeString("maxOccurs", "1");
writer.WriteAttributeString("name", name);
if (value is string)
{
writer.WriteAttributeString("default", "");
writer.WriteAttributeString("type", "xs:string");
}
else if (value is int || value is int?)
{
writer.WriteAttributeString("default", "-1");
writer.WriteAttributeString("type", "xs:int");
}
writer.WriteStartElement(name);
writer.WriteValue(value);
writer.WriteEndElement();
}
}
Binary file not shown.
Binary file not shown.