Search Unity

"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!