Skip to content

Instantly share code, notes, and snippets.

@AldeRoberge
Created July 29, 2023 04:22
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save AldeRoberge/1f4887193c7438a788d48bcb09ef022f to your computer and use it in GitHub Desktop.
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.
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());
}
}
}
@AldeRoberge
Copy link
Author

image
image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment