mirror of
https://github.com/MrUnknownDE/VRCX.git
synced 2026-04-19 06:43:51 +02:00
Delete screenshot metadata
This commit is contained in:
@@ -11,118 +11,155 @@ namespace VRCX;
|
||||
|
||||
public partial class AppApi
|
||||
{
|
||||
public string GetExtraScreenshotData(string path, bool carouselCache)
|
||||
public string GetExtraScreenshotData(string path, bool carouselCache)
|
||||
{
|
||||
var fileName = Path.GetFileNameWithoutExtension(path);
|
||||
var metadata = new JObject();
|
||||
|
||||
if (!File.Exists(path) || !path.EndsWith(".png"))
|
||||
return null;
|
||||
|
||||
var files = Directory.GetFiles(Path.GetDirectoryName(path), "*.png");
|
||||
|
||||
// Add previous/next file paths to metadata so the screenshot viewer carousel can request metadata for next/previous images in directory
|
||||
if (carouselCache)
|
||||
{
|
||||
var fileName = Path.GetFileNameWithoutExtension(path);
|
||||
var metadata = new JObject();
|
||||
|
||||
if (!File.Exists(path) || !path.EndsWith(".png"))
|
||||
return null;
|
||||
|
||||
var files = Directory.GetFiles(Path.GetDirectoryName(path), "*.png");
|
||||
|
||||
// Add previous/next file paths to metadata so the screenshot viewer carousel can request metadata for next/previous images in directory
|
||||
if (carouselCache)
|
||||
var index = Array.IndexOf(files, path);
|
||||
if (index > 0)
|
||||
{
|
||||
var index = Array.IndexOf(files, path);
|
||||
if (index > 0)
|
||||
{
|
||||
metadata.Add("previousFilePath", files[index - 1]);
|
||||
}
|
||||
if (index < files.Length - 1)
|
||||
{
|
||||
metadata.Add("nextFilePath", files[index + 1]);
|
||||
}
|
||||
metadata.Add("previousFilePath", files[index - 1]);
|
||||
}
|
||||
if (index < files.Length - 1)
|
||||
{
|
||||
metadata.Add("nextFilePath", files[index + 1]);
|
||||
}
|
||||
|
||||
using var png = new PNGFile(path);
|
||||
metadata.Add("fileResolution", PNGHelper.ReadResolution(png));
|
||||
|
||||
var creationDate = File.GetCreationTime(path);
|
||||
metadata.Add("creationDate", creationDate.ToString("yyyy-MM-dd HH:mm:ss"));
|
||||
|
||||
var fileSizeBytes = new FileInfo(path).Length;
|
||||
metadata.Add("fileSizeBytes", fileSizeBytes.ToString());
|
||||
metadata.Add("fileName", fileName);
|
||||
metadata.Add("filePath", path);
|
||||
metadata.Add("fileSize", $"{(fileSizeBytes / 1024f / 1024f).ToString("0.00")} MB");
|
||||
|
||||
return metadata.ToString(Formatting.Indented);
|
||||
}
|
||||
|
||||
public string GetScreenshotMetadata(string path)
|
||||
using var png = new PNGFile(path);
|
||||
metadata.Add("fileResolution", PNGHelper.ReadResolution(png));
|
||||
|
||||
var creationDate = File.GetCreationTime(path);
|
||||
metadata.Add("creationDate", creationDate.ToString("yyyy-MM-dd HH:mm:ss"));
|
||||
|
||||
var fileSizeBytes = new FileInfo(path).Length;
|
||||
metadata.Add("fileSizeBytes", fileSizeBytes.ToString());
|
||||
metadata.Add("fileName", fileName);
|
||||
metadata.Add("filePath", path);
|
||||
metadata.Add("fileSize", $"{(fileSizeBytes / 1024f / 1024f).ToString("0.00")} MB");
|
||||
|
||||
return metadata.ToString(Formatting.Indented);
|
||||
}
|
||||
|
||||
public string GetScreenshotMetadata(string path)
|
||||
{
|
||||
if (string.IsNullOrEmpty(path))
|
||||
return null;
|
||||
|
||||
|
||||
var metadata = ScreenshotHelper.GetScreenshotMetadata(path);
|
||||
|
||||
if (metadata == null)
|
||||
{
|
||||
if (string.IsNullOrEmpty(path))
|
||||
return null;
|
||||
|
||||
|
||||
var metadata = ScreenshotHelper.GetScreenshotMetadata(path);
|
||||
|
||||
if (metadata == null)
|
||||
var obj = new JObject
|
||||
{
|
||||
var obj = new JObject
|
||||
{
|
||||
{ "sourceFile", path },
|
||||
{ "error", "Screenshot contains no metadata." }
|
||||
};
|
||||
|
||||
return obj.ToString(Formatting.Indented);
|
||||
{ "sourceFile", path },
|
||||
{ "error", "Screenshot contains no metadata." }
|
||||
};
|
||||
|
||||
if (metadata.Error != null)
|
||||
{
|
||||
var obj = new JObject
|
||||
{
|
||||
{ "sourceFile", path },
|
||||
{ "error", metadata.Error }
|
||||
};
|
||||
return obj.ToString(Formatting.Indented);
|
||||
};
|
||||
|
||||
return obj.ToString(Formatting.Indented);
|
||||
}
|
||||
|
||||
return JsonConvert.SerializeObject(metadata, Formatting.Indented, new JsonSerializerSettings
|
||||
{
|
||||
ContractResolver = new DefaultContractResolver
|
||||
{
|
||||
NamingStrategy = new CamelCaseNamingStrategy() // This'll serialize our .net property names to their camelCase equivalents. Ex; "FileName" -> "fileName"
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public string FindScreenshotsBySearch(string searchQuery, int searchType = 0)
|
||||
if (metadata.Error != null)
|
||||
{
|
||||
var stopwatch = new Stopwatch();
|
||||
stopwatch.Start();
|
||||
|
||||
var searchPath = GetVRChatPhotosLocation();
|
||||
var screenshots = ScreenshotHelper.FindScreenshots(searchQuery, searchPath, (ScreenshotHelper.ScreenshotSearchType)searchType);
|
||||
|
||||
JArray json = new JArray();
|
||||
|
||||
foreach (var screenshot in screenshots)
|
||||
var obj = new JObject
|
||||
{
|
||||
json.Add(screenshot.SourceFile);
|
||||
}
|
||||
{ "sourceFile", path },
|
||||
{ "error", metadata.Error }
|
||||
};
|
||||
|
||||
stopwatch.Stop();
|
||||
|
||||
logger.Info($"FindScreenshotsBySearch took {stopwatch.ElapsedMilliseconds}ms to complete.");
|
||||
|
||||
return json.ToString();
|
||||
return obj.ToString(Formatting.Indented);
|
||||
}
|
||||
|
||||
public string GetLastScreenshot()
|
||||
return JsonConvert.SerializeObject(metadata, Formatting.Indented, new JsonSerializerSettings
|
||||
{
|
||||
// Get the last screenshot taken by VRChat
|
||||
var path = GetVRChatPhotosLocation();
|
||||
if (!Directory.Exists(path))
|
||||
return null;
|
||||
|
||||
// exclude folder names that contain "Prints" or "Stickers"
|
||||
var imageFiles = Directory.GetFiles(path, "*.png", SearchOption.AllDirectories)
|
||||
.Where(x => !Regex.IsMatch(x, @"\\Prints\\|\\Stickers\\", RegexOptions.IgnoreCase));
|
||||
var lastScreenshot = imageFiles.OrderByDescending(Directory.GetCreationTime).FirstOrDefault();
|
||||
ContractResolver = new DefaultContractResolver
|
||||
{
|
||||
NamingStrategy = new CamelCaseNamingStrategy() // This'll serialize our .net property names to their camelCase equivalents. Ex; "FileName" -> "fileName"
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return lastScreenshot;
|
||||
public string FindScreenshotsBySearch(string searchQuery, int searchType = 0)
|
||||
{
|
||||
var stopwatch = new Stopwatch();
|
||||
stopwatch.Start();
|
||||
|
||||
var searchPath = GetVRChatPhotosLocation();
|
||||
var screenshots = ScreenshotHelper.FindScreenshots(searchQuery, searchPath, (ScreenshotHelper.ScreenshotSearchType)searchType);
|
||||
|
||||
JArray json = new JArray();
|
||||
|
||||
foreach (var screenshot in screenshots)
|
||||
{
|
||||
json.Add(screenshot.SourceFile);
|
||||
}
|
||||
|
||||
stopwatch.Stop();
|
||||
|
||||
logger.Info($"FindScreenshotsBySearch took {stopwatch.ElapsedMilliseconds}ms to complete.");
|
||||
|
||||
return json.ToString();
|
||||
}
|
||||
|
||||
public string GetLastScreenshot()
|
||||
{
|
||||
// Get the last screenshot taken by VRChat
|
||||
var path = GetVRChatPhotosLocation();
|
||||
if (!Directory.Exists(path))
|
||||
return null;
|
||||
|
||||
// exclude folder names that contain "Prints" or "Stickers"
|
||||
var imageFiles = Directory.GetFiles(path, "*.png", SearchOption.AllDirectories)
|
||||
.Where(x => !Regex.IsMatch(x, @"\\Prints\\|\\Stickers\\", RegexOptions.IgnoreCase));
|
||||
var lastScreenshot = imageFiles.OrderByDescending(Directory.GetCreationTime).FirstOrDefault();
|
||||
|
||||
return lastScreenshot;
|
||||
}
|
||||
|
||||
public bool DeleteScreenshotMetadata(string path)
|
||||
{
|
||||
if (string.IsNullOrEmpty(path) || !File.Exists(path) || !path.EndsWith(".png"))
|
||||
return false;
|
||||
|
||||
try
|
||||
{
|
||||
ScreenshotHelper.DeleteTextMetadata(path, true);
|
||||
return true;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
logger.Error(ex, "Failed to delete screenshot metadata for {0}", path);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public void DeleteAllScreenshotMetadata()
|
||||
{
|
||||
var path = GetVRChatPhotosLocation();
|
||||
if (!Directory.Exists(path))
|
||||
return;
|
||||
|
||||
var imageFiles = Directory.GetFiles(path, "*.png", SearchOption.AllDirectories);
|
||||
foreach (var file in imageFiles)
|
||||
{
|
||||
try
|
||||
{
|
||||
ScreenshotHelper.DeleteTextMetadata(file, true);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
logger.Error(ex, "Failed to delete screenshot metadata for {0}", file);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
@@ -43,7 +43,7 @@ public class PNGFile : IDisposable
|
||||
ReadAndCacheMetadata();
|
||||
|
||||
var chunk = metadataChunkCache.FirstOrDefault((chunk) => chunkTypeFilter.HasFlag(chunk.ChunkTypeEnum));
|
||||
if (chunk.IsZero())
|
||||
if (chunk == null || chunk.IsZero())
|
||||
return null;
|
||||
|
||||
return chunk;
|
||||
@@ -60,7 +60,7 @@ public class PNGFile : IDisposable
|
||||
public PNGChunk? GetChunkReverse(PNGChunkTypeFilter chunkTypeFilter)
|
||||
{
|
||||
var chunk = ReadChunkReverse(chunkTypeFilter);
|
||||
if (chunk != null && chunk.IsZero())
|
||||
if (chunk == null || chunk.IsZero())
|
||||
return null;
|
||||
|
||||
return chunk;
|
||||
|
||||
@@ -36,7 +36,7 @@ namespace VRCX
|
||||
/// If true, the function searches from the end of the file using a reverse search bruteforce method.
|
||||
/// </param>
|
||||
/// <returns>The text associated with the specified keyword, or null if not found.</returns>
|
||||
public static string ReadTextChunk(string keyword, PNGFile pngFile, bool legacySearch = false)
|
||||
public static string? ReadTextChunk(string keyword, PNGFile pngFile, bool legacySearch = false)
|
||||
{
|
||||
// Search for legacy text chunks created by old vrchat mods
|
||||
if (legacySearch)
|
||||
|
||||
Reference in New Issue
Block a user