Last active
July 13, 2018 08:12
-
-
Save Hotrian/e453948223cc8101fd1fabdbaa8289b3 to your computer and use it in GitHub Desktop.
Automatically Scales Sprite Texture2Ds, allowing you to multiply the image size safely, and effectively. Not guaranteed to work on every Sprite, or at all for that matter :P.
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.Collections.Generic; | |
using UnityEditor; | |
using UnityEngine; | |
/* Unity Sprite Resizer v1.6 © Hotrian 2017 | |
* | |
* This has only been tested on PNG files. | |
* | |
* Usage instructions: | |
* 1. Put SpriteResizer.cs at | |
* ..\Assets\Editor\SpriteResizer.cs | |
* 2. After Unity recompiles, at the top Click Window > SpriteResizer | |
* 3. In the SpriteResizer window, select your Sprite's Texture2D | |
* 4. Select a Multiplier value | |
* 5. Click Upscale Texture | |
* | |
* This generates replacements for your Sprite, but cannot install them automatically as they are locked by Unity. | |
* Your replacement files will be named: | |
* [originalName.png2] | |
* [originalName.png.meta2] | |
* | |
* To install your new sprite: | |
* 1. First, make sure Unity is closed so it is not locking your assets | |
* 2. Navigate to your Sprite in File Explorer | |
* 3. Delete the [originalName.png] and [originalName.png.meta] files | |
* 4. Rename the new files by removing the 2 that has been added after the extension: | |
* [originalName.png2] -> [originanName.png] | |
* [originalName.png.meta2] -> [originanName.png.meta] | |
* 5. Restart Unity and Marvel! | |
* | |
*/ | |
public class SpriteResizer : EditorWindow | |
{ | |
private Texture2D _tex; | |
private Powers _multiplier = Powers.Two; | |
[MenuItem("Window/SpriteResizer")] | |
public static void ShowWindow() | |
{ | |
EditorWindow.GetWindow(typeof(SpriteResizer)); | |
} | |
void OnGUI() | |
{ | |
_tex = (Texture2D)EditorGUILayout.ObjectField("Sprite", _tex, typeof(Texture2D), false); | |
if (_tex == null) return; | |
var w1 = _tex.width; | |
var w2 = _tex.width * (int)_multiplier; | |
var h1 = _tex.height; | |
var h2 = _tex.height * (int)_multiplier; | |
_multiplier = (Powers)EditorGUILayout.EnumPopup("Multiplier:", _multiplier); | |
GUILayout.Label(string.Format("Width:\t({0})\t{1}\nHeight:\t({2})\t{3}", w1, w2, h1, h2), EditorStyles.boldLabel); | |
if (GUILayout.Button("Upscale Texture")) | |
{ | |
// Generate some information about this action | |
var path = AssetDatabase.GetAssetPath(_tex); | |
var filePath = Application.dataPath + path.Substring(6); | |
var metaPath = Application.dataPath + path.Substring(6) + ".meta"; | |
var file = path.LastIndexOf(System.IO.Path.DirectorySeparatorChar); | |
if (file == -1) file = path.LastIndexOf(System.IO.Path.AltDirectorySeparatorChar); | |
if (file == -1) Debug.LogWarning("Couldn't find last Path Seperator"); | |
var fileName = path.Substring(file + 1); | |
try | |
{ | |
_tex.GetPixels(); | |
} | |
catch (UnityException e) | |
{ | |
if (e.Message.Contains("' is not readable, the texture memory can not be accessed from scripts.")) | |
{ | |
Debug.LogWarning("Texture [" + fileName + "] is not readable.. Doing this the hard way.."); | |
_tex = LoadPng(filePath); | |
} | |
else | |
{ | |
Debug.LogException(e); | |
return; | |
} | |
} | |
// Attempt to save the resized texture to disk | |
Debug.LogWarning("Resizing Texture [" + fileName + "]"); | |
System.IO.File.WriteAllBytes(filePath + "2", Resize(_tex, (int)_multiplier).EncodeToPNG()); | |
Debug.LogWarning("Resized. Fixing Sprite Meta..."); | |
// Parse the Metadata file | |
var lines = System.IO.File.ReadAllLines(metaPath); | |
var newLines = new List<string>(); | |
foreach (var line in lines) | |
{ | |
// Handles resizing the Pixels Per Unit | |
if (line.TrimStart().StartsWith("spritePixelsToUnits: ")) | |
{ | |
var len = line.IndexOf("spritePixelsToUnits: ", StringComparison.CurrentCulture); | |
var baseVal = int.Parse(line.Substring(len + 21).Trim()); | |
switch (baseVal) | |
{ | |
case 1: | |
case 4: | |
case 8: | |
case 16: | |
case 32: | |
case 64: | |
case 128: | |
case 256: | |
case 512: | |
case 1024: | |
break; | |
default: | |
Debug.LogWarning("Pixels Per Unit should be a Power of 2! Current value: " + baseVal); | |
break; | |
} | |
var val = baseVal * (int)_multiplier; | |
newLines.Add(line.Substring(0, len + 21) + val); | |
} // Handles resizing sliced Sprite X | |
else if (line.TrimStart().StartsWith("x: ")) | |
{ | |
var len = line.IndexOf("x: ", StringComparison.CurrentCulture); | |
var val = int.Parse(line.Substring(len + 3).Trim()) * (int)_multiplier; | |
newLines.Add(line.Substring(0, len + 3) + val); | |
} // Handles resizing sliced Sprite Y | |
else if (line.TrimStart().StartsWith("y: ")) | |
{ | |
var len = line.IndexOf("y: ", StringComparison.CurrentCulture); | |
var val = int.Parse(line.Substring(len + 3).Trim()) * (int)_multiplier; | |
newLines.Add(line.Substring(0, len + 3) + val); | |
} // Handles resizing sliced Sprite Width | |
else if (line.TrimStart().StartsWith("width: ")) | |
{ | |
var len = line.IndexOf("width: ", StringComparison.CurrentCulture); | |
var val = int.Parse(line.Substring(len + 7).Trim()) * (int)_multiplier; | |
newLines.Add(line.Substring(0, len + 7) + val); | |
} // Handles resizing sliced Sprite Height | |
else if (line.TrimStart().StartsWith("height: ")) | |
{ | |
var len = line.IndexOf("height: ", StringComparison.CurrentCulture); | |
var val = int.Parse(line.Substring(len + 8).Trim()) * (int)_multiplier; | |
newLines.Add(line.Substring(0, len + 8) + val); | |
} // Add all other lines verbatim | |
else newLines.Add(line); | |
} | |
// Attempt to save the new metadata to disk | |
try | |
{ | |
System.IO.File.WriteAllLines(metaPath + "2", newLines.ToArray()); | |
} | |
catch (Exception e) | |
{ | |
Debug.LogException(e); | |
return; | |
} | |
Debug.Log("Texture Resized Successfully!"); | |
Debug.Log(string.Format("Please close Unity, then delete [{0}] and [{1}], and rename [{2}] and [{3}] to replace them.", fileName, fileName + ".meta", fileName + "2", fileName + ".meta2")); | |
} | |
} | |
public static Texture2D LoadPng(string filePath) | |
{ | |
if (!System.IO.File.Exists(filePath)) return null; | |
var fileData = System.IO.File.ReadAllBytes(filePath); | |
var tex = new Texture2D(2, 2) {filterMode = FilterMode.Point}; | |
tex.LoadImage(fileData); //..this will auto-resize the texture dimensions. | |
return tex; | |
} | |
/// <summary> | |
/// Scale a given texture to a larger multiple of the same texture | |
/// </summary> | |
Texture2D Resize(Texture2D t, int scale) | |
{ | |
// Generate a Point Filtered texture which is [scale] times larger than the source Texture2D | |
var tex = new Texture2D(t.width * scale, t.height * scale, t.format, false) { filterMode = FilterMode.Point }; | |
var c = t.GetPixels(); // Get the pixel data for the source texture | |
var cExpand = new Color[c.Length * scale * scale]; // Create an array to store our working data | |
var i = 0; | |
var j = 0; | |
// Run through every line of the source texture | |
for (var h = 0; h < t.height; h++) | |
{ | |
var lJ = j; | |
// Repeat this line [scale] number of times | |
for (var y = 0; y < scale; y++) | |
{ | |
j = lJ; | |
// Run through every column of the source texture | |
for (var w = 0; w < t.width; w++) | |
{ | |
// Repeat this line [scale] number of times | |
for (var x = 0; x < scale; x++) | |
{ | |
// Save this color to our working data | |
cExpand[i] = c[j]; | |
i++; | |
} | |
j++; | |
} | |
} | |
} | |
// Update our new texture with the working data | |
tex.SetPixels(cExpand); | |
tex.filterMode = FilterMode.Point; | |
tex.Apply(); | |
return tex; | |
} | |
public enum Powers | |
{ | |
One = 1, // Effectively does nothing. Duplicates the Texture as is. | |
Two = 2, // Doubles the Texture size on each axis. | |
Four = 4, // Quadruples the Texture size on each axis. | |
Eight = 8, // etc. | |
Sixteen = 16, | |
Thirtytwo = 32, | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment