Created
July 29, 2023 04:22
-
-
Save AldeRoberge/1f4887193c7438a788d48bcb09ef022f to your computer and use it in GitHub Desktop.
RotMG-inspired sprite upscaler. Converts 16x16 sprites to 80x80 with border and drop shadow.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Diagnostics; | |
using System.IO; | |
using System.Threading.Tasks; | |
using SkiaSharp; | |
namespace AGES_Sprite_Processor | |
{ | |
internal class Program | |
{ | |
const string inputFilePath = @"C:\Users\Alde\Documents\GitHub\AGES\AGES-Demo\Assets\Entities\Runtime\Sprites\Items"; | |
const string outputFilePath = "Output/"; | |
private static SKColor DropShadowColor = new(0, 0, 0, 145); | |
public static void Main(string[] args) | |
{ | |
// Ensure file exists | |
if (!Directory.Exists(inputFilePath)) | |
{ | |
Console.WriteLine($"Error, directory {inputFilePath} does not exist."); | |
return; | |
} | |
var filesInDirectory = Directory.GetFiles(inputFilePath, "*.png", SearchOption.AllDirectories); | |
Parallel.ForEach(filesInDirectory, s => { UpscaleSprite(s, outputFilePath); }); | |
// Open image in explorer | |
Process.Start("explorer", $"/select,\"{AppDomain.CurrentDomain.BaseDirectory}"); | |
} | |
private static void UpscaleSprite(string s, string outputFilePath) | |
{ | |
// Load the image | |
using var bitmap = SKBitmap.Decode(s); | |
// Upscale the image | |
var scaledBitmap = bitmap.Resize(new SKImageInfo(bitmap.Width * 4, bitmap.Height * 4), SKFilterQuality.None); | |
// Calculate the padding for the shadow | |
var shadowRadius = 2; | |
var paddingX = shadowRadius + 4; | |
var paddingY = shadowRadius + 4; | |
// Create a new bitmap with added padding for the border | |
var bitmapWithBorder = new SKBitmap(scaledBitmap.Width + 2 * paddingX, scaledBitmap.Height + 2 * paddingY); | |
using var canvas = new SKCanvas(bitmapWithBorder); | |
// Draw the image 8 times to create a border | |
var paint = new SKPaint(); | |
paint.Color = new SKColor(0, 0, 0); | |
for (int dx = -1; dx <= 1; dx++) | |
{ | |
for (int dy = -1; dy <= 1; dy++) | |
{ | |
if (dx != 0 || dy != 0) | |
{ | |
canvas.DrawBitmap(scaledBitmap, dx + paddingX, dy + paddingY, paint); | |
} | |
} | |
} | |
// Replace all non-transparent pixels with black | |
for (int x = 0; x < bitmapWithBorder.Width; x++) | |
{ | |
for (int y = 0; y < bitmapWithBorder.Height; y++) | |
{ | |
var pixel = bitmapWithBorder.GetPixel(x, y); | |
if (pixel.Alpha != 0) | |
{ | |
bitmapWithBorder.SetPixel(x, y, new SKColor(0, 0, 0)); | |
} | |
} | |
} | |
// Draw the main image over the top with padding | |
canvas.DrawBitmap(scaledBitmap, paddingX, paddingY, paint); | |
// Create bitmap for shadow with extra padding | |
var shadowWidth = bitmapWithBorder.Width + 2 * shadowRadius; | |
var shadowHeight = bitmapWithBorder.Height + 2 * shadowRadius; | |
var shadowBitmap = new SKBitmap(shadowWidth, shadowHeight); | |
// Create black paint | |
var shadowPaint = new SKPaint | |
{ | |
Color = new SKColor(0, 0, 0), | |
ImageFilter = SKImageFilter.CreateDropShadow(0, 0, shadowRadius, shadowRadius, DropShadowColor) | |
}; | |
using var shadowCanvas = new SKCanvas(shadowBitmap); | |
// Draw shadow with padding | |
shadowCanvas.DrawBitmap(bitmapWithBorder, shadowRadius, shadowRadius, shadowPaint); | |
// Draw the main bitmap over the top with padding | |
shadowCanvas.DrawBitmap(bitmapWithBorder, shadowRadius, shadowRadius, paint); | |
// Save the image to disk | |
using var image = SKImage.FromBitmap(shadowBitmap); | |
using var data = image.Encode(); | |
var fileName = Path.GetFileNameWithoutExtension(s); | |
var fileFolder = Path.GetDirectoryName(s); | |
var subFolder = fileFolder.Replace(inputFilePath, ""); | |
var outputFolder = $"{outputFilePath}{subFolder}"; | |
var outputFile = $"{outputFolder}{Path.DirectorySeparatorChar}{fileName}-output.png"; | |
Console.WriteLine($"Would have outputted to {outputFile}"); | |
// Create the directory if it doesn't exist | |
if (!Directory.Exists(outputFolder)) | |
Directory.CreateDirectory(outputFolder); | |
File.WriteAllBytes(outputFile, data.ToArray()); | |
} | |
} | |
} |
Author
AldeRoberge
commented
Jul 29, 2023
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment