Fix scaling when uploading images

This commit is contained in:
Natsumi
2025-02-10 09:11:24 +13:00
parent d73bcd04c1
commit 0c213f915f
2 changed files with 35 additions and 46 deletions
+34 -46
View File
@@ -42,8 +42,6 @@ namespace VRCX
return imageData; return imageData;
} }
// FIXME: I think these are aspect ratio preserving calcs, but we can ask ImageSharp nicely to do this by
// passing 0, see docs for Resize()
if (image.Width > maxWidth) if (image.Width > maxWidth)
{ {
var sizingFactor = image.Width / (double)maxWidth; var sizingFactor = image.Width / (double)maxWidth;
@@ -58,18 +56,13 @@ namespace VRCX
} }
if (matchingDimensions && image.Width != image.Height) if (matchingDimensions && image.Width != image.Height)
{ {
var newSize = Math.Max(image.Width, image.Height); var targetSize = Math.Max(image.Width, image.Height);
using Image<Rgba32> resizedImage = new(newSize, newSize); var squareCanvas = new Image<Rgba32>(targetSize, targetSize);
// regalialong: i think the access should be safe var xOffset = (targetSize - image.Width) / 2;
// ReSharper disable AccessToModifiedClosure var yOffset = (targetSize - image.Height) / 2;
// ReSharper disable AccessToDisposedClosure squareCanvas.Mutate(x =>
resizedImage.Mutate(x => x.DrawImage(image, x.DrawImage(image, new Point(xOffset, yOffset), 1f));
new Rectangle((newSize - image.Width) / 2, (newSize - image.Height) / 2, image.Width, image.Height), image = squareCanvas;
0));
// ReSharper restore AccessToDisposedClosure
// ReSharper restore AccessToModifiedClosure
image.Dispose();
image = resizedImage;
} }
SaveToFileToUpload(); SaveToFileToUpload();
@@ -119,43 +112,37 @@ namespace VRCX
using var fileMemoryStream = new MemoryStream(imageData); using var fileMemoryStream = new MemoryStream(imageData);
var image = Image.Load(fileMemoryStream); var image = Image.Load(fileMemoryStream);
if (image.Height > image.Width) image.Mutate(x => x.Rotate(RotateMode.Rotate90)); if (image.Height > image.Width)
image.Mutate(x => x.Rotate(RotateMode.Rotate270));
// increase size to 1920x1080 // increase size to 1920x1080
if (image.Width < desiredWidth || image.Height < desiredHeight) if (image.Width < desiredWidth || image.Height < desiredHeight)
{ {
var newHeight = image.Height; const double expectedAspectRatio = 1920.0 / 1080.0;
var newWidth = image.Width; var target = new Image<Rgba32>(1920, 1080);
if (image.Width < desiredWidth) var aspectRatio = (double)image.Width / image.Height;
int width, height, xOffset, yOffset;
if (aspectRatio > expectedAspectRatio)
{ {
var testHeight = (int)Math.Round(image.Height / (image.Width / (double)desiredWidth)); // Image is wider than 16:9 - scale based on width
if (testHeight <= desiredHeight) width = 1920;
{ height = (int)(width / aspectRatio);
newWidth = desiredWidth; xOffset = 0;
newHeight = testHeight; yOffset = (1080 - height) / 2;
}
} }
if (image.Height < desiredHeight) else
{ {
var testWidth = (int)Math.Round(image.Width / (image.Height / (double)desiredHeight)); // Image is taller than 16:9 - scale based on height
if (testWidth <= desiredWidth) height = 1080;
{ width = (int)(height * aspectRatio);
newHeight = desiredHeight; xOffset = (1920 - width) / 2;
newWidth = testWidth; yOffset = 0;
}
} }
using var scaledImage = image.Clone(ctx => ctx.Resize(width, height));
target.Mutate(x => x.Fill(Color.White)
using Image<Rgba32> resizedImage = new(desiredWidth, desiredHeight); .DrawImage(scaledImage, new Point(xOffset, yOffset), 1f));
resizedImage.Mutate(x image = target;
// ReSharper disable once AccessToModifiedClosure
// ReSharper disable once AccessToDisposedClosure
=> x.Fill(Color.White).DrawImage(image,
new Rectangle((desiredWidth - newWidth) / 2, (desiredHeight - newHeight) / 2, newWidth,
newHeight), 0)
);
image.Dispose();
image = resizedImage;
} }
// limit size to 1920x1080 // limit size to 1920x1080
@@ -174,13 +161,14 @@ namespace VRCX
// add white border // add white border
// wtf are these magic numbers // wtf are these magic numbers
const int xOffset = 64; // 2048 / 32 const int xBorderOffset = 64; // 2048 / 32
const int yOffset = 69; // 1440 / 20.869 const int yBorderOffset = 69; // 1440 / 20.869
using Image<Rgba32> newImage = new(2048, 1440); using Image<Rgba32> newImage = new(2048, 1440);
newImage.Mutate(x => x.Fill(Color.White)); newImage.Mutate(x => x.Fill(Color.White));
// graphics.DrawImage(image, new Rectangle(xOffset, yOffset, image.Width, image.Height)); // graphics.DrawImage(image, new Rectangle(xOffset, yOffset, image.Width, image.Height));
var newX = (2048 - image.Width) / 2; var newX = (2048 - image.Width) / 2;
newImage.Mutate(x => x.DrawImage(image, new Rectangle(newX, yOffset, image.Width, image.Height), 0)); var borderPoint = new Point(newX, yBorderOffset);
newImage.Mutate(x => x.DrawImage(image, borderPoint, 1f));
using var imageSaveMemoryStream = new MemoryStream(); using var imageSaveMemoryStream = new MemoryStream();
newImage.SaveAsPng(imageSaveMemoryStream); newImage.SaveAsPng(imageSaveMemoryStream);
return imageSaveMemoryStream.ToArray(); return imageSaveMemoryStream.ToArray();
+1
View File
@@ -6,6 +6,7 @@
<Import Sdk="Microsoft.NET.Sdk" Project="Sdk.props" /> <Import Sdk="Microsoft.NET.Sdk" Project="Sdk.props" />
<PropertyGroup> <PropertyGroup>
<TargetFramework>net9.0</TargetFramework> <TargetFramework>net9.0</TargetFramework>
<OutputType>Library</OutputType>
<Platforms>x64</Platforms> <Platforms>x64</Platforms>
<ApplicationRevision>0</ApplicationRevision> <ApplicationRevision>0</ApplicationRevision>
<ApplicationVersion>1.0.0.%2a</ApplicationVersion> <ApplicationVersion>1.0.0.%2a</ApplicationVersion>