Search Unity

Getting original size of texture asset in pixels

Discussion in 'Editor & General Support' started by numberkruncher, Jan 7, 2013.

  1. numberkruncher

    numberkruncher

    Joined:
    Feb 18, 2012
    Posts:
    953
    Hey guys

    Unity does not provide a documented API for accessing the width and height of a texture asset before any processing has been applied by the texture importer. So if you have a texture that measures 210x210 in Photoshop, when imported into Unity the texture will likely read 256x256 due to NPOT and/or maximum resolution.

    It is often useful to access the original width and height of the texture asset from editor scripts when performing certain calculations, especially when working with things like atlases. Having searched the web thoroughly the best solution that I could come across was to temporarily alter the texture importer settings for a texture asset, and then restore them. This worked but was very slow due to the need to reimport the texture asset twice.

    For example of this approach see: http://philippseifried.com/blog/2012/07/30/unity3d-code-original-texture-siz/

    After chatting with some developers in the IRC channel we discovered the internal function "TextureImporter.GetWidthAndHeight". Using reflection to invoke this function it seems to return the original size of the texture (as opposed to the imported size).

    Here is a wrapper function that I wrote which seems to work fine, and more importantly is significantly faster and more efficient than the other approach:

    Code (csharp):
    1. public static bool GetImageSize(Texture2D asset, out int width, out int height) {
    2.     if (asset != null) {
    3.         string assetPath = AssetDatabase.GetAssetPath(asset);
    4.         TextureImporter importer = AssetImporter.GetAtPath(assetPath) as TextureImporter;
    5.  
    6.         if (importer != null) {
    7.             object[] args = new object[2] { 0, 0 };
    8.             MethodInfo mi = typeof(TextureImporter).GetMethod("GetWidthAndHeight", BindingFlags.NonPublic | BindingFlags.Instance);
    9.             mi.Invoke(importer, args);
    10.  
    11.             width = (int)args[0];
    12.             height = (int)args[1];
    13.  
    14.             return true;
    15.         }
    16.     }
    17.  
    18.     height = width = 0;
    19.     return false;
    20. }
    The ability to access the original width and height of a texture asset is very useful for extension developers. In fact there are a number of forum, Q&A and blog posts by editor developers who have asked for this functionality. An important feature of an asset that I am working on requires this functionality for sure!

    Please vote here to have the internal function made public and documented for safe usage:

    http://feedback.unity3d.com/unity/all-categories/1/hot/active/get-original-width-and-height-of
     
    Last edited: Jan 7, 2013
  2. KyleStaves

    KyleStaves

    Joined:
    Nov 4, 2009
    Posts:
    821
    Thanks, we found this quite useful!
     
  3. Juruhn

    Juruhn

    Joined:
    Jun 25, 2013
    Posts:
    13
    Hi,

    I voted on the idea on the given site. I am really more a unityscript user so don’t really know how to implement this given solution.
    It is exactly what I was looking for so if you can give me a shot in the right direction I would appreciate it.

    Thnx
     
  4. numberkruncher

    numberkruncher

    Joined:
    Feb 18, 2012
    Posts:
    953
    I have converted this to UnityScript for you, though have made a few changes to workaround the fact that UnityScript does not support parametrized outputs:
    Code (csharp):
    1.  
    2. #pragma strict
    3.  
    4. import System.Reflection;
    5.  
    6. class ImageSize extends System.ValueType {
    7.  
    8.     public static var zero:ImageSize = new ImageSize(0, 0);
    9.  
    10.     public static function GetImageSize(asset:Texture2D):ImageSize {
    11.         if (asset != null) {
    12.             var assetPath:String = AssetDatabase.GetAssetPath(asset);
    13.             var importer:TextureImporter = AssetImporter.GetAtPath(assetPath) as TextureImporter;
    14.            
    15.             if (importer != null) {
    16.                 var args:System.Object[] = [ 0, 0 ];
    17.                 var mi:MethodInfo = typeof(TextureImporter).GetMethod('GetWidthAndHeight', BindingFlags.NonPublic | BindingFlags.Instance);
    18.                 mi.Invoke(importer, args);
    19.                
    20.                 return new ImageSize(args[0], args[1]);
    21.             }
    22.         }
    23.        
    24.         return zero;
    25.     }
    26.  
    27.     public var width:int;
    28.     public var height:int;
    29.    
    30.     public function ImageSize(width:int, height:int) {
    31.         this.width = width;
    32.         this.height = height;
    33.     }
    34.    
    35. }
    36.  
    And a window to test this:
    Code (csharp):
    1.  
    2. #pragma strict
    3.  
    4. class ImageSizeTest extends EditorWindow {
    5.  
    6.     @MenuItem('Window/Test')
    7.     static function Show() {
    8.         GetWindow.<ImageSizeTest>();
    9.     }
    10.    
    11.     var texture:Texture2D;
    12.     var size:ImageSize;
    13.    
    14.     function OnGUI() {
    15.         texture = EditorGUILayout.ObjectField(texture, typeof(Texture2D)) as Texture2D;
    16.         if (GUILayout.Button('Find Size'))
    17.             size = ImageSize.GetImageSize(texture);
    18.        
    19.         GUILayout.Label(String.Format('{0} x {1}', size.width, size.height));
    20.     }
    21.    
    22. }
    23.  
     
  5. andymads

    andymads

    Joined:
    Jun 16, 2011
    Posts:
    1,614
    Thanks very much for this.
     
  6. LoTekK

    LoTekK

    Joined:
    Jul 19, 2010
    Posts:
    136
    Thanks much for this. I ran into this issue just today, so your method has basically solved any issues I was having. Would definitely be nice to have this be officially available to the API, but for now this'll do nicely (since it's for an internal tool).

    As a side note, I made a modification to the method, since I'm currently using it exclusively in a custom AssetPostprocessor. I'm basically passing it the TextureImporter directly, instead of a texture:

    Code (csharp):
    1. public static bool GetImageSize(TextureImporter importer, out int width, out int height)
    Which saves the step of needing the AssetDatabase to find the file.
     
    jcuriel_glu likes this.
  7. Adrian

    Adrian

    Joined:
    Apr 5, 2008
    Posts:
    1,065
    Here's my version that caches the reflection in a delegate and should be much faster if used frequently. It also has overloads for both Texture2D and TextureImporter and returns the size instead of using out parameters.

    Code (CSharp):
    1. private delegate void GetWidthAndHeight(TextureImporter importer, ref int width, ref int height);
    2. private static GetWidthAndHeight getWidthAndHeightDelegate;
    3.  
    4. public struct Size {
    5.     public int width;
    6.     public int height;
    7. }
    8.  
    9. public static Size GetOriginalTextureSize(Texture2D texture)
    10. {
    11.     if (texture == null)
    12.         throw new NullReferenceException();
    13.  
    14.     var path = AssetDatabase.GetAssetPath(texture);
    15.     if (string.IsNullOrEmpty(path))
    16.         throw new Exception("Texture2D is not an asset texture.");
    17.  
    18.     var importer = AssetImporter.GetAtPath(path) as TextureImporter;
    19.     if (importer == null)
    20.         throw new Exception("Failed to get Texture importer for " + path);
    21.  
    22.     return GetOriginalTextureSize(importer);
    23. }
    24.  
    25. public static Size GetOriginalTextureSize(TextureImporter importer)
    26. {
    27.     if (getWidthAndHeightDelegate == null) {
    28.         var method = typeof(TextureImporter).GetMethod("GetWidthAndHeight", BindingFlags.NonPublic | BindingFlags.Instance);
    29.         getWidthAndHeightDelegate = Delegate.CreateDelegate(typeof(GetWidthAndHeight), null, method) as GetWidthAndHeight;
    30.     }
    31.  
    32.     var size = new Size();
    33.     getWidthAndHeightDelegate(importer, ref size.width, ref size.height);
    34.  
    35.     return size;
    36. }
     
  8. Wolkenschauer

    Wolkenschauer

    Joined:
    Jan 27, 2014
    Posts:
    2
    And how would you guys get the real size on runtime? I mean not unityeditor only wise? What is the point in hiding the aspect rate from the developer anyway?
     
    Fangh likes this.
  9. Adrian

    Adrian

    Joined:
    Apr 5, 2008
    Posts:
    1,065
    @Wolkenschauer
    You don't. That information is not accessible and Unity likely only has the imported scaled-down texture without any information about the original image at runtime.

    Your only option is to collect the information yourself at edit-time (using the methods lined out above), somehow save the information (e.g. in a ScriptableObject, text file, on some prefab etc) and then retrieve that information at runtime.

    Or figure out a way where you don't need this information in the first place.
     
  10. nicloay

    nicloay

    Joined:
    Jul 11, 2012
    Posts:
    540
    Hey.. thanks for this function.

    Still useful =)

    Here is autofix post processor
    Code (CSharp):
    1. public class AtlasTexturePostprocessor : AssetPostprocessor {
    2.     public const int PixelsPerUnit = 100;
    3.     void OnPreprocessTexture(){
    4.         Texture2D tex = AssetDatabase.LoadAssetAtPath(assetPath, typeof(Texture2D )) as Texture2D;
    5.         TextureImporter importer = assetImporter as TextureImporter;
    6.         int textureHeight;
    7.         FixTextureSize(tex,importer, out textureHeight);
    8.     }
    9.     static int[] textureSizes = new int[] {
    10.         32,
    11.         64,
    12.         128,
    13.         256,
    14.         512,
    15.         1024,
    16.         2048,
    17.         4096
    18.     };
    19.     void FixTextureSize (Texture2D tex, TextureImporter importer, out int textureRealHeigh)
    20.     {
    21.         int width, height, max;
    22.         GetImageSize(tex,out width, out height);
    23.         textureRealHeigh = height;
    24.         max = Mathf.Max(width, height);
    25.         int size = 1024; //Default size
    26.         for (int i = 0; i < textureSizes.Length; i++) {
    27.             if (textureSizes[i] >= max){
    28.                 size = textureSizes[i];
    29.                 break;          
    30.             }
    31.         }
    32.         importer.maxTextureSize = size;
    33.     }
    34. }

    One issue here, is that GetWidthAndHeight return zero when you use "Reimport All"
     
    Last edited: Feb 18, 2015
    ROBYER1 likes this.
  11. Diablo404

    Diablo404

    Joined:
    Mar 15, 2013
    Posts:
    136
    Thoses scripts are great but I needed to do it in a standalone export, and since theses ones are using UnityEditor, it was non exploitable.

    So I found a solution that could maybe help someone. In this link: http://www.codeproject.com/Articles/35978/Reading-Image-Headers-to-Get-Width-and-Height , they read the binary header of the file to determine which type of file it is, then read the appropriate size. I've modified it a bit so I don't have to import the unwanted System.Drawing. Here is the modified (and only) script needed:

    ImageHeader.cs
    Code (CSharp):
    1. using System;
    2. using System.Collections.Generic;
    3. using System.IO;
    4. using System.Linq;
    5.  
    6.  
    7. public class Vector2Int
    8. {
    9.     public int x;
    10.     public int y;
    11.    
    12.     public Vector2Int( int _x, int _y )
    13.     {
    14.         x = _x;
    15.         y = _y;
    16.     }
    17. }
    18.  
    19. /// <summary>
    20. /// Taken from http://stackoverflow.com/questions/111345/getting-image-dimensions-without-reading-the-entire-file/111349
    21. /// Minor improvements including supporting unsigned 16-bit integers when decoding Jfif and added logic
    22. /// to load the image using new Bitmap if reading the headers fails
    23. /// </summary>
    24. public static class ImageHeader
    25. {
    26.     const string errorMessage = "Could not recognise image format.";
    27.  
    28.     private static Dictionary<byte[], Func<BinaryReader, Vector2Int>> imageFormatDecoders = new Dictionary<byte[], Func<BinaryReader, Vector2Int>>()
    29.     {
    30.         { new byte[] { 0x42, 0x4D }, DecodeBitmap },
    31.         { new byte[] { 0x47, 0x49, 0x46, 0x38, 0x37, 0x61 }, DecodeGif },
    32.         { new byte[] { 0x47, 0x49, 0x46, 0x38, 0x39, 0x61 }, DecodeGif },
    33.         { new byte[] { 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A }, DecodePng },
    34.         { new byte[] { 0xff, 0xd8 }, DecodeJfif },
    35.     };
    36.  
    37.     /// <summary>      
    38.     /// Gets the dimensions of an image.      
    39.     /// </summary>      
    40.     /// <param name="path">The path of the image to get the dimensions of.</param>      
    41.     /// <returns>The dimensions of the specified image.</returns>      
    42.     /// <exception cref="ArgumentException">The image was of an unrecognised format.</exception>      
    43.     public static Vector2Int GetDimensions(string path)
    44.     {
    45.         try
    46.         {
    47.             using (BinaryReader binaryReader = new BinaryReader(File.OpenRead(path)))
    48.             {
    49.                 try
    50.                 {
    51.                     return GetDimensions(binaryReader);
    52.                 }
    53.                 catch (ArgumentException e)
    54.                 {
    55.                     string newMessage = string.Format("{0} file: '{1}' ", errorMessage, path);
    56.  
    57.                     throw new ArgumentException(newMessage, "path", e);
    58.                 }
    59.             }
    60.         }
    61.         catch (ArgumentException)
    62.         {
    63.             UnityEngine.Debug.LogError("And error occured");
    64.             return new Vector2Int(0,0);
    65.         }
    66.     }
    67.  
    68.     /// <summary>      
    69.     /// Gets the dimensions of an image.      
    70.     /// </summary>      
    71.     /// <param name="path">The path of the image to get the dimensions of.</param>      
    72.     /// <returns>The dimensions of the specified image.</returns>      
    73.     /// <exception cref="ArgumentException">The image was of an unrecognised format.</exception>          
    74.     public static Vector2Int GetDimensions(BinaryReader binaryReader)
    75.     {
    76.         int maxMagicBytesLength = imageFormatDecoders.Keys.OrderByDescending(x => x.Length).First().Length;
    77.         byte[] magicBytes = new byte[maxMagicBytesLength];
    78.         for (int i = 0; i < maxMagicBytesLength; i += 1)
    79.         {
    80.             magicBytes[i] = binaryReader.ReadByte();
    81.             foreach (var kvPair in imageFormatDecoders)
    82.             {
    83.                 if (StartsWith(magicBytes, kvPair.Key))
    84.                 {
    85.                     return kvPair.Value(binaryReader);
    86.                 }
    87.             }
    88.         }
    89.  
    90.         throw new ArgumentException(errorMessage, "binaryReader");
    91.     }
    92.  
    93.     private static bool StartsWith(byte[] thisBytes, byte[] thatBytes)
    94.     {
    95.         for (int i = 0; i < thatBytes.Length; i += 1)
    96.         {
    97.             if (thisBytes[i] != thatBytes[i])
    98.             {
    99.                 return false;
    100.             }
    101.         }
    102.  
    103.         return true;
    104.     }
    105.  
    106.     private static short ReadLittleEndianInt16(BinaryReader binaryReader)
    107.     {
    108.         byte[] bytes = new byte[sizeof(short)];
    109.  
    110.         for (int i = 0; i < sizeof(short); i += 1)
    111.         {
    112.             bytes[sizeof(short) - 1 - i] = binaryReader.ReadByte();
    113.         }
    114.         return BitConverter.ToInt16(bytes, 0);
    115.     }
    116.  
    117.     private static ushort ReadLittleEndianUInt16(BinaryReader binaryReader)
    118.     {
    119.         byte[] bytes = new byte[sizeof(ushort)];
    120.  
    121.         for (int i = 0; i < sizeof(ushort); i += 1)
    122.         {
    123.             bytes[sizeof(ushort) - 1 - i] = binaryReader.ReadByte();
    124.         }
    125.         return BitConverter.ToUInt16(bytes, 0);
    126.     }
    127.  
    128.     private static int ReadLittleEndianInt32(BinaryReader binaryReader)
    129.     {
    130.         byte[] bytes = new byte[sizeof(int)];
    131.         for (int i = 0; i < sizeof(int); i += 1)
    132.         {
    133.             bytes[sizeof(int) - 1 - i] = binaryReader.ReadByte();
    134.         }
    135.         return BitConverter.ToInt32(bytes, 0);
    136.     }
    137.  
    138.     private static Vector2Int DecodeBitmap(BinaryReader binaryReader)
    139.     {
    140.         binaryReader.ReadBytes(16);
    141.         int width = binaryReader.ReadInt32();
    142.         int height = binaryReader.ReadInt32();
    143.         return new Vector2Int(width, height);
    144.     }
    145.  
    146.     private static Vector2Int DecodeGif(BinaryReader binaryReader)
    147.     {
    148.         int width = binaryReader.ReadInt16();
    149.         int height = binaryReader.ReadInt16();
    150.         return new Vector2Int(width, height);
    151.     }
    152.  
    153.     private static Vector2Int DecodePng(BinaryReader binaryReader)
    154.     {
    155.         binaryReader.ReadBytes(8);
    156.         int width = ReadLittleEndianInt32(binaryReader);
    157.         int height = ReadLittleEndianInt32(binaryReader);
    158.         return new Vector2Int(width, height);
    159.     }
    160.  
    161.     private static Vector2Int DecodeJfif(BinaryReader binaryReader)
    162.     {
    163.         while (binaryReader.ReadByte() == 0xff)
    164.         {
    165.             byte marker = binaryReader.ReadByte();
    166.             short chunkLength = ReadLittleEndianInt16(binaryReader);
    167.             if (marker == 0xc0)
    168.             {
    169.                 binaryReader.ReadByte();
    170.                 int height = ReadLittleEndianInt16(binaryReader);
    171.                 int width = ReadLittleEndianInt16(binaryReader);
    172.                 return new Vector2Int(width, height);
    173.             }
    174.  
    175.             if (chunkLength < 0)
    176.             {
    177.                 ushort uchunkLength = (ushort)chunkLength;
    178.                 binaryReader.ReadBytes(uchunkLength - 2);
    179.             }
    180.             else
    181.             {
    182.                 binaryReader.ReadBytes(chunkLength - 2);
    183.             }
    184.         }
    185.  
    186.         throw new ArgumentException(errorMessage);
    187.     }
    188. }
    189.  
    And here is how to use it:
    Code (CSharp):
    1. Vector2Int imgSize  = ImageHeader.GetDimensions(Application.persistentDataPath+"/Mouse.png");
    2.         Debug.Log("imgSize.x =" + imgSize.x);
    3. Debug.Log("imgSize.y =" + imgSize.y);
     
    Fangh, long_axie, fherbst and 8 others like this.
  12. Beloudest

    Beloudest

    Joined:
    Mar 13, 2015
    Posts:
    247
    Looks good to me. Thx
     
    Diablo404 likes this.
  13. 670ok

    670ok

    Joined:
    Jun 6, 2017
    Posts:
    2
    This is very useful, thanks bro
     
    Diablo404 likes this.
  14. jtok4j

    jtok4j

    Joined:
    Dec 6, 2013
    Posts:
    322
    I'd like to pipe-up and confirm that the script and usage lines of code by Diablo404 are working for me as well.
    Thanks and...
    Keep on Creating!
     
    Diablo404 likes this.
  15. atomicjoe

    atomicjoe

    Joined:
    Apr 10, 2013
    Posts:
    1,869
    Just a tip for using these methods:
    You will have to include both system and reflection libraries for them to compile.
    Add this lines at the top of your script:
    Code (CSharp):
    1. using System;
    2. using System.Reflection;
     
    Diablo404 likes this.
  16. MeessenPhilips

    MeessenPhilips

    Joined:
    Oct 3, 2016
    Posts:
    4
    Still useful 6 years later, thank you.
     
    Diablo404 and jtok4j like this.
  17. jtok4j

    jtok4j

    Joined:
    Dec 6, 2013
    Posts:
    322
    So, So true @MeessenPhilips
     
    Diablo404 likes this.
  18. kblood

    kblood

    Joined:
    Jun 20, 2012
    Posts:
    92
    This solution is just awesome. Been searching and searching for a good way to do this that did not rely on importing / referencing other projects. I am modding a Unity game, so I cannot import or reference new DLLs and its based on Unity 5.6.

    I have come to like the challenge of relying on what you already got. This script looking at certain bytes to check for the image type is really cool.

     
    Diablo404 likes this.
  19. mattstromandev

    mattstromandev

    Joined:
    Dec 25, 2013
    Posts:
    4
    Unity now has a built-in way to do this based on what is found in the Sprite Editor source code:

    Code (CSharp):
    1. private static bool GetImageSize(string assetPath, out int width, out int height)
    2.         {
    3.             SpriteDataProviderFactories dataProviderFactories = new SpriteDataProviderFactories();
    4.                
    5.             dataProviderFactories.Init();
    6.                
    7.             ISpriteEditorDataProvider importer = dataProviderFactories.GetSpriteEditorDataProviderFromObject(AssetImporter.GetAtPath(assetPath));
    8.  
    9.             if (importer != null)
    10.             {
    11.                 importer.InitSpriteEditorDataProvider();
    12.  
    13.                 ITextureDataProvider textureDataProvider = importer.GetDataProvider<ITextureDataProvider>();
    14.  
    15.                 textureDataProvider.GetTextureActualWidthAndHeight(out width, out height);
    16.  
    17.                 return true;
    18.             }
    19.  
    20.             width = height = 0;
    21.             return true;
    22.         }
     
  20. Max-om

    Max-om

    Joined:
    Aug 9, 2017
    Posts:
    499
    Here is a script to set all selected textures to max size

    Code (CSharp):
    1.     [MenuItem("2D/Set textures to max res")]
    2.     public static void SetTexturesToMax()
    3.     {
    4.         var textures = Selection.objects.OfType<Texture2D>();
    5.         foreach (var t in textures)
    6.         {
    7.             var assetPath = AssetDatabase.GetAssetPath(t);
    8.             var importer = AssetImporter.GetAtPath(assetPath) as TextureImporter;
    9.             if (importer != null)
    10.             {
    11.                 var args = new object[2] { 0, 0 };
    12.                 var mi = typeof(TextureImporter).GetMethod("GetWidthAndHeight", BindingFlags.NonPublic | BindingFlags.Instance);
    13.                 mi.Invoke(importer, args);
    14.                 var width = (int)args[0];
    15.                 var height = (int)args[1];
    16.                 if (t.width != width || t.height != height)
    17.                 {
    18.                     Debug.Log($"Imported dimensions differ from actual dimension; {t.name}: {width}x{height}");
    19.                     importer.maxTextureSize = width;
    20.                     AssetDatabase.ImportAsset(assetPath, ImportAssetOptions.ForceUpdate);
    21.                 }
    22.             }
    23.         }
    24.     }
     
  21. ROBYER1

    ROBYER1

    Joined:
    Oct 9, 2015
    Posts:
    1,453
    'tex' is always null when trying to use this so max texture size is always 32 by error. Anyone found a fix?

    The problematic line is
    Code (CSharp):
    1. Texture2D tex = AssetDatabase.LoadAssetAtPath(assetPath, typeof(Texture2D)) as Texture2D;
    Which always returns null

    EDIT:
    I wanted to automate setting the max texture size to the lowest size based on the texture size, e.g. a 1080px texture would be set to 2048 max size, a 1000px texture would be set to 2048px etc.

    This is for the purpose of the Sprite sheet Atlas packer in Sprite Packer v2.0 relying on max texture size for the sizes of the textures in the sprite sheet. For example, some 64x64px icons in a sprite sheet would be huge due to their max texture size being the default 2048x2048 in our project.

    Just did my own version of this, this is for any texture contained inside a folder called 'UI' e.g. Assets/UI/... so feel free to remove that part of the if/else in void OnPreProcessTexture if you want this to work on any textures outside of a folder called 'UI'

    Tested on Unity 2021.3x and requires 2d Sprite/Spritesheet package too

    Code (CSharp):
    1. using System.Reflection;
    2. using UnityEditor;
    3. using UnityEditor.U2D.Sprites;
    4. using UnityEngine;
    5.  
    6. // Automatically sets Textures settings upon first import and prints the
    7. // path from  where is being imported
    8.  
    9. class CustomImportSettings : AssetPostprocessor
    10. {
    11.     public const int PixelsPerUnit = 100;
    12.  
    13.     void OnPreprocessTexture()
    14.     {
    15.  
    16.         // Only post process textures if they are in a folder
    17.         // "invert color" or a sub folder of it.
    18.         string lowerCaseAssetPath = assetPath.ToLower();
    19.         if (lowerCaseAssetPath.IndexOf("/ui/") == -1)
    20.         {
    21.             return;
    22.         }
    23.         else
    24.         {
    25.             TextureImporter importer = (TextureImporter)assetImporter;
    26.             importer.textureType = TextureImporterType.Sprite;
    27.             importer.crunchedCompression = true;
    28.             importer.compressionQuality = 50;
    29.             int textureHeight;
    30.             FixTextureSize(assetPath, importer, out textureHeight);
    31.             // importer.maxTextureSize =
    32.         }
    33.     }
    34.  
    35.     #region Texture Size fix
    36.     static int[] textureSizes = new int[] {
    37.         32,
    38.         64,
    39.         128,
    40.         256,
    41.         512,
    42.         1024,
    43.         2048,
    44.         4096
    45.     };
    46.  
    47.     void FixTextureSize(string assetPath, TextureImporter importer, out int textureRealHeigh)
    48.     {
    49.         int width, height, max;
    50.         GetImageSize(assetPath, out width, out height);
    51.         textureRealHeigh = height;
    52.         max = Mathf.Max(width, height);
    53.         int size = 1024; //Default size
    54.         for (int i = 0; i < textureSizes.Length; i++)
    55.         {
    56.             if (textureSizes[i] >= max)
    57.             {
    58.                 size = textureSizes[i];
    59.                 break;
    60.             }
    61.         }
    62.         importer.maxTextureSize = size;
    63.     }
    64.     private static bool GetImageSize(string assetPath, out int width, out int height)
    65.     {
    66.         SpriteDataProviderFactories dataProviderFactories = new SpriteDataProviderFactories();
    67.  
    68.         dataProviderFactories.Init();
    69.  
    70.         ISpriteEditorDataProvider importer = dataProviderFactories.GetSpriteEditorDataProviderFromObject(AssetImporter.GetAtPath(assetPath));
    71.  
    72.         if (importer != null)
    73.         {
    74.             importer.InitSpriteEditorDataProvider();
    75.  
    76.             ITextureDataProvider textureDataProvider = importer.GetDataProvider<ITextureDataProvider>();
    77.  
    78.             textureDataProvider.GetTextureActualWidthAndHeight(out width, out height);
    79.  
    80.             return true;
    81.         }
    82.  
    83.         width = height = 0;
    84.         return true;
    85.     }
    86.     #endregion
    87. }
     
    Last edited: Aug 8, 2022
  22. Fangh

    Fangh

    Joined:
    Apr 19, 2013
    Posts:
    274
    Warning, it doesn't work with jpg
     
  23. Thaina

    Thaina

    Joined:
    Jul 13, 2012
    Posts:
    1,161
    This was something that should always publicly available