Moved functionality into the application root
Added a CachedByteArray class that will store compressed (disk-ready) images on the appropriate media
This commit is contained in:
@@ -1,10 +1,15 @@
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.Configuration;
|
||||
using System.Data;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Media.Imaging;
|
||||
|
||||
namespace RBG_Server
|
||||
{
|
||||
@@ -13,5 +18,194 @@ namespace RBG_Server
|
||||
/// </summary>
|
||||
public partial class App : Application
|
||||
{
|
||||
public GameServer BoardGameServer {get;}
|
||||
public CommunicationHandler communicationHandler { get; private set;}
|
||||
protected static readonly SolidColorBrush RED_BRUSH = new(Color.FromRgb(255, 0, 0));
|
||||
protected static readonly SolidColorBrush BLUE_BRUSH = new(Color.FromRgb(0, 0, 255));
|
||||
protected static readonly SolidColorBrush GREEN_BRUSH = new(Color.FromRgb(0, 255, 0));
|
||||
|
||||
/// <summary>
|
||||
/// Loads the specified files from disk, creating mip maps as appropriate
|
||||
/// </summary>
|
||||
/// <param name="selectedFiles"></param>
|
||||
/// <param name="isSprite"></param>
|
||||
/// <param name="spriteLimit"></param>
|
||||
void LoadFiles(string[] selectedFiles, bool isSprite=false, int spriteLimit=128)
|
||||
{
|
||||
// Continue in parallel
|
||||
_ = Parallel.ForEach(selectedFiles, (file) =>
|
||||
{
|
||||
LoadFile(file);
|
||||
});
|
||||
}
|
||||
/// <summary>
|
||||
/// Loads a singular file from disk, generating Mip maps as required
|
||||
/// </summary>
|
||||
/// <param name="path"></param>
|
||||
void LoadFile(string path, bool isSprite=true)
|
||||
{
|
||||
// Check if the file is a .gif, first.
|
||||
using FileStream fs = File.OpenRead(path);
|
||||
LoadStream(fs, path, isSprite);
|
||||
|
||||
}
|
||||
|
||||
void LoadStream(Stream source, string path, bool isSprite)
|
||||
{
|
||||
long srcStart = source.Position;
|
||||
byte[] vs = new byte[6]; // First 6 bytes is the gif specifier
|
||||
source.Read(vs, 0, 6);
|
||||
source.Position = srcStart;
|
||||
string magicNumber = Encoding.ASCII.GetString(vs);
|
||||
if (magicNumber == "GIF87a" || magicNumber == "GIF89a")
|
||||
{
|
||||
// Gif file, replace with a layered .png
|
||||
GifBitmapDecoder decoder = new(source, BitmapCreateOptions.None, BitmapCacheOption.Default);
|
||||
// Obtain each .gif frame
|
||||
BitmapFrame[] frames = new BitmapFrame[decoder.Frames.Count];
|
||||
decoder.Frames.CopyTo(frames, 0);
|
||||
// Get frame sizes
|
||||
int height = frames[0].PixelHeight;
|
||||
int width = frames[0].PixelWidth;
|
||||
// The lowest mip is static, using either the thumb or first frame
|
||||
if (decoder.Thumbnail != null)
|
||||
{
|
||||
double scaleRate = 32 / (double)Math.Max(height, width);
|
||||
MemoryStream ms = ScaleImage(decoder.Thumbnail, scaleRate);
|
||||
_ = communicationHandler.ImageCollection.TryAdd(Path.GetFileNameWithoutExtension(path) + "_mip_low" + Path.GetExtension(path), new CachedByteArray(ms.ToArray()));
|
||||
}
|
||||
else
|
||||
{
|
||||
double scaleRate = 32 / (double)Math.Max(height, width);
|
||||
MemoryStream ms = ScaleImage(frames[0], scaleRate);
|
||||
_ = communicationHandler.ImageCollection.TryAdd(Path.GetFileNameWithoutExtension(path) + "_mip_low" + Path.GetExtension(path), new CachedByteArray(ms.ToArray()));
|
||||
}
|
||||
// The remaining mips are animated
|
||||
if (width >= 128 || height >= 128)
|
||||
{
|
||||
double scaleRate = 128 / (double)Math.Max(height, width);
|
||||
MemoryStream ms = ScaleAnimatedImage(frames, scaleRate);
|
||||
_ = communicationHandler.ImageCollection.TryAdd(Path.GetFileNameWithoutExtension(path) + "_mip_med" + Path.GetExtension(path), new CachedByteArray(ms.ToArray()));
|
||||
}
|
||||
if (width >= 512 || height >= 512)
|
||||
{
|
||||
double scaleRate = 512 / (double)Math.Max(height, width);
|
||||
MemoryStream ms = ScaleAnimatedImage(frames, scaleRate);
|
||||
_ = communicationHandler.ImageCollection.TryAdd(Path.GetFileNameWithoutExtension(path) + "_mip_high" + Path.GetExtension(path), new CachedByteArray(ms.ToArray()));
|
||||
}
|
||||
if (width >= 512 || height >= 512)
|
||||
{
|
||||
// Just re-encode the gif to .png
|
||||
PngBitmapEncoder encoder = new();
|
||||
foreach (BitmapFrame frame in frames)
|
||||
{
|
||||
encoder.Frames.Add(frame);
|
||||
}
|
||||
MemoryStream ms = new();
|
||||
encoder.Save(ms);
|
||||
_ = communicationHandler.ImageCollection.TryAdd(Path.GetFileNameWithoutExtension(path) + "_mip_raw" + Path.GetExtension(path), new CachedByteArray(ms.ToArray()));
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
// Regular image file
|
||||
// Create the bitmap to get the current intrinsics
|
||||
BitmapImage bitmapImage = new();
|
||||
bitmapImage.BeginInit();
|
||||
bitmapImage.StreamSource = source;
|
||||
bitmapImage.CacheOption = BitmapCacheOption.None;
|
||||
bitmapImage.EndInit();
|
||||
int height = bitmapImage.PixelHeight;
|
||||
int width = bitmapImage.PixelWidth;
|
||||
|
||||
// Behaviour depends on the required image
|
||||
if (isSprite)
|
||||
{
|
||||
// Sprites should have a low mip-map, and the medium
|
||||
// Low = 32*32
|
||||
// Medium = 128*128
|
||||
// High = 512*512 or image size if less than 1024
|
||||
if (width >= 32 || height >= 32)
|
||||
{
|
||||
double scaleRate = 32 / (double)Math.Max(height, width);
|
||||
MemoryStream ms = ScaleImage(bitmapImage, scaleRate);
|
||||
_ = communicationHandler.ImageCollection.TryAdd(Path.GetFileNameWithoutExtension(path) + "_mip_low" + Path.GetExtension(path), new CachedByteArray(ms.ToArray()));
|
||||
}
|
||||
if (width >= 128 || height >= 128)
|
||||
{
|
||||
double scaleRate = 128 / (double)Math.Max(height, width);
|
||||
MemoryStream ms = ScaleImage(bitmapImage, scaleRate);
|
||||
_ = communicationHandler.ImageCollection.TryAdd(Path.GetFileNameWithoutExtension(path) + "_mip_med" + Path.GetExtension(path), new CachedByteArray(ms.ToArray()));
|
||||
}
|
||||
if (width >= 512 || height >= 512)
|
||||
{
|
||||
double scaleRate = 512 / (double)Math.Max(height, width);
|
||||
MemoryStream ms = ScaleImage(bitmapImage, scaleRate);
|
||||
_ = communicationHandler.ImageCollection.TryAdd(Path.GetFileNameWithoutExtension(path) + "_mip_high" + Path.GetExtension(path), new CachedByteArray(ms.ToArray()));
|
||||
}
|
||||
if (width >= 512 || height >= 512)
|
||||
{
|
||||
MemoryStream ms = new();
|
||||
source.CopyTo(ms);
|
||||
_ = communicationHandler.ImageCollection.TryAdd(Path.GetFileNameWithoutExtension(path) + "_mip_raw" + Path.GetExtension(path), new CachedByteArray(ms.ToArray()));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Non-sprites should have a low mip-map, and the medium, but at a larger size than the sprites
|
||||
// Low = 128*128
|
||||
// Medium = 512*512
|
||||
// High = 2048*2048
|
||||
if (width >= 128 || height >= 128)
|
||||
{
|
||||
double scaleRate = 128 / (double)Math.Max(height, width);
|
||||
MemoryStream ms = ScaleImage(bitmapImage, scaleRate);
|
||||
_ = communicationHandler.ImageCollection.TryAdd(Path.GetFileNameWithoutExtension(path) + "_mip_low" + Path.GetExtension(path), new CachedByteArray(ms.ToArray()));
|
||||
}
|
||||
if (width >= 512 || height >= 512)
|
||||
{
|
||||
double scaleRate = 512 / (double)Math.Max(height, width);
|
||||
MemoryStream ms = ScaleImage(bitmapImage, scaleRate);
|
||||
_ = communicationHandler.ImageCollection.TryAdd(Path.GetFileNameWithoutExtension(path) + "_mip_med" + Path.GetExtension(path), new CachedByteArray(ms.ToArray()));
|
||||
}
|
||||
if (width >= 2048 || height >= 2048)
|
||||
{
|
||||
double scaleRate = 2048 / (double)Math.Max(height, width);
|
||||
MemoryStream ms = ScaleImage(bitmapImage, scaleRate);
|
||||
_ = communicationHandler.ImageCollection.TryAdd(Path.GetFileNameWithoutExtension(path) + "_mip_high" + Path.GetExtension(path), new CachedByteArray(ms.ToArray()));
|
||||
}
|
||||
if (width >= 2048 || height >= 2048)
|
||||
{
|
||||
MemoryStream ms = new();
|
||||
source.CopyTo(ms);
|
||||
_ = communicationHandler.ImageCollection.TryAdd(Path.GetFileNameWithoutExtension(path) + "_mip_raw" + Path.GetExtension(path), new CachedByteArray(ms.ToArray()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
MemoryStream ScaleImage(BitmapSource source, double scaleRate)
|
||||
{
|
||||
TransformedBitmap modified = new(source, new ScaleTransform(source.PixelWidth * scaleRate, source.PixelHeight * scaleRate));
|
||||
PngBitmapEncoder encoder = new();
|
||||
encoder.Frames.Add(BitmapFrame.Create(modified));
|
||||
MemoryStream ms = new();
|
||||
encoder.Save(ms);
|
||||
return ms;
|
||||
}
|
||||
|
||||
MemoryStream ScaleAnimatedImage(BitmapFrame[] frames, double scaleRate)
|
||||
{
|
||||
PngBitmapEncoder encoder = new();
|
||||
foreach (BitmapFrame frame in frames)
|
||||
{
|
||||
TransformedBitmap modified = new(frame, new ScaleTransform(frame.PixelWidth * scaleRate, frame.PixelHeight * scaleRate));
|
||||
encoder.Frames.Add(BitmapFrame.Create(modified));
|
||||
}
|
||||
MemoryStream ms = new();
|
||||
encoder.Save(ms);
|
||||
return ms;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user