Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

"Scale2x" sample code and project

Discussion in 'Scripting' started by Agent_007, Mar 19, 2013.

  1. Agent_007

    Agent_007

    Joined:
    Dec 18, 2011
    Posts:
    899
    I once needed pixel scaling algorithm for one test scene, so I ported Scale2x to Unity C# that uses Texture operations for the job. Since the Scale2x author has following disclaimer Instead, you are free to use the algorithm, but please call the effect "Scale2x", I am calling this "Scale2x".

    Since Color components are floats, the comparison of colors is done somewhat cumbersomely, but it works. And if you want to use this, make sure the Read/Write enabled is checked from texture import settings (also set the Filter mode: Point).

    Sample shot:
    $Xll83a0.png

    (sample textures are from BrowserQuest and they are under CC-BY-SA 3.0)

    Unitypackage:
    View attachment $_scale2x_.unitypackage

    Actual scaling part
    Code (csharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public static class Scaledoublex {
    5.    
    6.     /// <summary>
    7.     /// Use "Scale2x" algorithm to produce new texture from inputTexture.
    8.     /// </summary>
    9.     /// <param name='inputTexture'>
    10.     /// Input texture.
    11.     /// </param>
    12.     public static Texture2D Scale2x(Texture2D inputTexture)
    13.     {
    14.         Texture2D returnTexture = new Texture2D(inputTexture.width*2, inputTexture.height*2);
    15.        
    16.         // Every pixel from input texture produces 4 output pixels, for more details check out http://scale2x.sourceforge.net/algorithm.html
    17.         int y = 0;
    18.         while (y < inputTexture.height)
    19.         {
    20.             int x = 0;
    21.             while (x < inputTexture.width)
    22.             {
    23.                 Color colorB = inputTexture.GetPixel(x, y-1);
    24.                 Color colorH = inputTexture.GetPixel(x, y+1);
    25.                 Color colorD = inputTexture.GetPixel(x-1, y);
    26.                 Color colorF = inputTexture.GetPixel(x+1, y);
    27.                
    28.                 Color colorE = inputTexture.GetPixel(x, y);
    29.                
    30.                 if(!AreColorsSame(colorB, colorH)  !AreColorsSame(colorD, colorF))
    31.                 {
    32.                     returnTexture.SetPixel(2*x,   2*y,   AreColorsSame(colorD, colorB) ? colorD : colorE);
    33.                     returnTexture.SetPixel(2*x+1, 2*y,   AreColorsSame(colorB, colorF) ? colorF : colorE);
    34.                     returnTexture.SetPixel(2*x,   2*y+1, AreColorsSame(colorD, colorH) ? colorD : colorE);
    35.                     returnTexture.SetPixel(2*x+1, 2*y+1, AreColorsSame(colorH, colorF) ? colorF : colorE);
    36.                 }
    37.                 else
    38.                 {
    39.                     returnTexture.SetPixel(2*x,   2*y, colorE);
    40.                     returnTexture.SetPixel(2*x+1, 2*y, colorE);
    41.                     returnTexture.SetPixel(2*x,   2*y+1, colorE);
    42.                     returnTexture.SetPixel(2*x+1, 2*y+1, colorE);
    43.                 }
    44.                
    45.                 x++;
    46.             }
    47.             y++;
    48.            
    49.         }
    50.        
    51.         returnTexture.Apply(false, true);
    52.         return returnTexture;
    53.     }
    54.    
    55.     /// <summary>
    56.     /// Checks if the colors are the same.
    57.     /// </summary>
    58.     /// <returns>
    59.     /// True if they are; otherwise false
    60.     /// </returns>
    61.     /// <param name='a'>
    62.     /// First color.
    63.     /// </param>
    64.     /// <param name='b'>
    65.     /// Second color.
    66.     /// </param>
    67.     private static bool AreColorsSame(Color aColor, Color bColor)
    68.     {
    69.         return Mathf.Approximately(aColor.r, bColor.r)  Mathf.Approximately(aColor.g, bColor.g)  Mathf.Approximately(aColor.b, bColor.b)  Mathf.Approximately(aColor.a, bColor.a);
    70.     }
    71. }
    and usage
    Code (csharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public class Controller : MonoBehaviour {
    5.    
    6.     public Texture2D house;
    7.     public Texture2D skull;
    8.    
    9.     private Texture2D scale2Xhouse;
    10.     private Texture2D scale2Xskull;
    11.    
    12.     // Use this for initialization
    13.     void Start () {
    14.         scale2Xhouse = Scaledoublex.Scale2x(house);
    15.         scale2Xskull = Scaledoublex.Scale2x(skull);
    16.     }
    17.    
    18.     // Update is called once per frame
    19.     void Update () {
    20.    
    21.     }
    22.    
    23.     void OnGUI() {
    24.         // Normal house
    25.         GUI.Label(new Rect(10, 0, 100, 20), "Normal");
    26.         GUI.DrawTexture(new Rect(5, 20, house.width, house.height), house);
    27.        
    28.         // 2x house with normal scaling
    29.         GUI.Label(new Rect(house.width+20, 0, 100, 20), "Point scale 2x");
    30.         GUI.DrawTexture(new Rect(house.width+10, 20, house.width*2, house.height*2), house);
    31.        
    32.         // 2x house with "scale2x" scaling
    33.         GUI.Label(new Rect(3*house.width+30, 0, 100, 20), '"' + "scale2x" + '"');
    34.         GUI.DrawTexture(new Rect(3*house.width+20, 20, scale2Xhouse.width, scale2Xhouse.height), scale2Xhouse);
    35.        
    36.        
    37.        
    38.         // Normal skull
    39.         GUI.Label(new Rect(10, 320, 100, 20), "Normal");
    40.         GUI.DrawTexture(new Rect(5, 340, skull.width, skull.height), skull);
    41.        
    42.         // 2x skull with normal scaling
    43.         GUI.Label(new Rect(skull.width+20, 320, 100, 20), "Point scale 2x");
    44.         GUI.DrawTexture(new Rect(skull.width+10, 340, skull.width*2, skull.height*2), skull);
    45.        
    46.         // 2x skull with "scale2x" scaling
    47.         GUI.Label(new Rect(3*skull.width+30, 320, 100, 20), '"' + "scale2x" + '"');
    48.         GUI.DrawTexture(new Rect(3*skull.width+20, 340, scale2Xskull.width, scale2Xskull.height), scale2Xskull);
    49.     }
    50. }
     
    Peter-Bailey likes this.
  2. trialforce

    trialforce

    Joined:
    Apr 15, 2012
    Posts:
    22
    Thansk! Very good!