8

Surprisingly in Unity, for years the only way to simply scale an actual PNG is to use the very awesome library http://wiki.unity3d.com/index.php/TextureScale

Example below

How do you scale a PNG using Unity5 functions? There must be a way now with new UI and so on.

So, scaling actual pixels (such as in Color[]) or literally a PNG file, perhaps downloaded from the net.

(BTW if you're new to Unity, the Resize call is unrelated. It merely changes the size of an array.)

public WebCamTexture wct;

public void UseFamousLibraryToScale()
    {
    // take the photo. scale down to 256
    // also  crop to a central-square

    WebCamTexture wct;
    int oldW = wct.width; // NOTE example code assumes wider than high
    int oldH = wct.height;

    Texture2D photo = new Texture2D(oldW, oldH,
          TextureFormat.ARGB32, false);
    //consider WaitForEndOfFrame() before GetPixels
    photo.SetPixels( 0,0,oldW,oldH, wct.GetPixels() );
    photo.Apply();

    int newH = 256;
    int newW = Mathf.FloorToInt(
           ((float)newH/(float)oldH) * oldW );

    // use a famous Unity library to scale
    TextureScale.Bilinear(photo, newW,newH);

    // crop to central square 256.256
    int startAcross = (newW - 256)/2;
    Color[] pix = photo.GetPixels(startAcross,0, 256,256);
    photo = new Texture2D(256,256, TextureFormat.ARGB32, false);
    photo.SetPixels(pix);
    photo.Apply();
    demoImage.texture = photo;

    // consider WriteAllBytes(
    //   Application.persistentDataPath+"p.png",
    //   photo.EncodeToPNG()); etc
    }

Just BTW it occurs to me I'm probably only talking about scaling down here (as you often have to do to post an image, create something on the fly or whatever.) I guess, there would not often be a need to scale up in size an image; it's pointless quality-wise.

user229044
  • 232,980
  • 40
  • 330
  • 338
Fattie
  • 27,874
  • 70
  • 431
  • 719
  • 2
    There is still no built in way of scaling a png using Unity functions, the code on the Wiki the best way, however it could be possible to integrate devIL or freeimage to do the scaling or manipulation if more advanced stuff is needed. – Chris Jun 01 '16 at 08:05

1 Answers1

4

If you're okay with stretch-scaling, actually there's simpler way by using a temporary RenderTexture and Graphics.Blit. If you need it to be Texture2D, swapping RenderTexture.active temporarily and read its pixels to Texture2D should do the trick. For example:

public Texture2D ScaleTexture(Texture src, int width, int height){
    RenderTexture rt = RenderTexture.GetTemporary(width, height);
    Graphics.Blit(src, rt);

    RenderTexture currentActiveRT = RenderTexture.active;
    RenderTexture.active = rt;
    Texture2D tex = new Texture2D(rt.width,rt.height); 

    tex.ReadPixels(new Rect(0, 0, tex.width, tex.height), 0, 0);
    tex.Apply();

    RenderTexture.ReleaseTemporary(rt);
    RenderTexture.active = currentActiveRT;

    return tex;
}
dkrprasetya
  • 114
  • 5