Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 14 Next capture
2021 2022 2023
2 captures
13 Jun 22 - 14 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
2
Question by CgShady · Nov 14, 2011 at 01:12 AM · guitextureimageresizepng

How can I resize an image and save it to disk ?

Hi,

I need to save thumbnails and then be able to load them back in a GUI.

I figured the reading part Ok, using WWW for reading from a file, using a "file://" type of url.

Right now, I'm using the code from the doc to read from the screen and save to a png file, which I load back in the GUI later. http://unity3d.com/support/documentation/ScriptReference/Texture2D.EncodeToPNG.html

Now, to lighten storage and free some video memory, I'd like to resize those thumbnails prior to saving them.

I am trying the following, with no luck :

function SaveSmallThumbnail () { var path = "test.png"; if (path) { yield WaitForEndOfFrame();

     // Create a texture the size of the screen, RGB24 format
     var width = Screen.width;
     var height = Screen.height;
     var tex = new Texture2D (width, height, TextureFormat.RGB24, false);
     
     // Read screen contents into the texture
     tex.ReadPixels (Rect(0, 0, width, height), 0, 0);
     tex.Apply ();
     
     tex.Resize(tex.width/2,tex.height/2,TextureFormat.RGB24, false); // this screws the saved image, why ?
 tex.Apply ();
     
     // Encode texture into PNG
     var bytes = tex.EncodeToPNG();

// Destroy (tex);

     File.WriteAllBytes(path, bytes);
     
 }

}

For a reason that I don't get, when I use the resize function, the saved image turns black, or pixel jam. I someone can provide at least an explanation, I'd be glad to read it.

If someone has a solution, even better. Btw, I'd like to keep the aspect ratio, and crop to the smallest dimension of the image. Something tells me I'll end writing a custom function... :)

Comment
Add comment · Show 1
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image idbrii · Apr 26, 2018 at 11:15 PM 0
Share

See also question "Texture scale".

6 Replies

· Add your reply
  • Sort: 
avatar image
5

Answer by ProFive · Jul 14, 2013 at 10:32 AM

Screen shot and resize texture

 public void MyCapture(string filename){
     Texture2D screenshot = new Texture2D(Screen.width, Screen.height, TextureFormat.RGB24, true);
     screenshot.ReadPixels(new Rect(0,0,Screen.width, Screen.height), 0, 0);
     screenshot.Apply();
     

     Texture2D newScreenshot =ScaleTexture(screenshot, 1024,576);
         
     byte[] bytes = newScreenshot.EncodeToPNG();
     File.WriteAllBytes(filename, bytes);
 }
 private Texture2D ScaleTexture(Texture2D source,int targetWidth,int targetHeight) {
        Texture2D result=new Texture2D(targetWidth,targetHeight,source.format,true);
        Color[] rpixels=result.GetPixels(0);
        float incX=((float)1/source.width)*((float)source.width/targetWidth);
        float incY=((float)1/source.height)*((float)source.height/targetHeight);
        for(int px=0; px<rpixels.Length; px++) {
                rpixels[px] = source.GetPixelBilinear(incX*((float)px%targetWidth),
                                  incY*((float)Mathf.Floor(px/targetWidth)));
        }
        result.SetPixels(rpixels,0);
        result.Apply();
        return result;
 }
Comment
Add comment · Show 1 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image manny003 · Oct 08, 2014 at 06:54 PM 1
Share

I tried using the above (ProFive's solution) and it seems to work except that is there a memory leak going on? When I run my Unity Game build on my iPad Device, and I monitor the $$anonymous$$emory meter in Xcode, the memory usage of my app, there is a 20 $$anonymous$$B spike on the take screenshot and resize. It never returns back to prior level.

I write the screenshot to file with the following line:` System.IO.File.WriteAllBytes(fileNameWithPath, screenshot.EncodeToJPG(75.0f));`

And I follow after that with Destory(screenshot) but memory usage does not return to the level it was at prior.

Is there a memory leak?

Thanks, $$anonymous$$anny

avatar image
3

Answer by inewland · May 22, 2013 at 07:13 PM

I ran into this problem as well and I wanted to share a unique solution I found from another source. It basically takes the mipmap level of the texture and uses that pixel data.

1) First, create a new texture and make sure mipmaps are set to TRUE (this takes the screenshot)

 Texture2D screenshot = new Texture2D(Screen.width, Screen.height, TextureFormat.RGB24, true);
 screenshot.ReadPixels(new Rect(0,0,Screen.width, Screen.height), 0, 0);
 screenshot.Apply();

2) Next we need to create a dummy texture - this will be used as our new texture (dividing by 2 cuts our texture in half) - Make sure the mipmap level is set to 1

 Texture2D newScreenshot = new Texture2D(screenshot.width/2, screenshot.height/2);
 newScreenshot.SetPixels(screenshot.GetPixels(1));
 newScreenshot.Apply();

3) Now you can encode and save to disk or whatever...

 byte[] bytes = newScreenshot.EncodeToPNG();
 string localURL = Application.persistentDataPath + "/screenshot.png";
 File.WriteAllBytes(localURL, bytes);
Comment
Add comment · Show 1 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image Yiming075 · Mar 19 at 11:01 AM 0
Share

How to scale more than 0.5?

avatar image
1

Answer by CgShady · Nov 15, 2011 at 01:07 AM

Ok, I got this to work, but not as expected. I turned around this using a RenderTexture the size of the thumbnail and rendering the camera to it, which is even better as it doesn't even pop like when taking a screenshot.

Comment
Add comment · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image
0

Answer by jonomf · Jan 12, 2012 at 08:07 PM

The saved image is black because Resize() clears the image (as the documentation says, "After resizing, texture pixels will be undefined"). I found the same problem trying to do a very similar thing, and Render To Texture was my answer too.

Comment
Add comment · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image
0

Answer by Streamfall · Feb 18, 2016 at 11:03 PM

Manny, had that same trouble. I've had some success using a rotating array of textures. So I create an array of Texture2D[] of some size, and each screenshot I increment the index in that array. Each of these textures is being converted into a thumbnail (this is the part im working on now). After I reach the last item in that array, I destroy each of them. Then call GC.Collect. This means if those textures are still being used, they'll turn black. So I am effectively going to have to limit the number of screenshots which can be captured. If you found a solution for this, please get back to me.

Thanks

Comment
Add comment · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
  • 1
  • 2
  • ›

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

11 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

Guilayout problems with image resize 0 Answers

How do I trigger GUI elements 1 Answer

How do I change the texture of a Raw image? 0 Answers

GUIUtiliy.RotateAroundPivot() doesn't work 0 Answers

GUI Button using .png image? 1 Answer


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges