List of Texture2D - c#

I am creating a simple game that need to capture a photo from the webcam every time the user click on some object. To avoid lag issues because of the task of convert the Texture2D to PNG and write the image on the disk, I am trying to store one List of Texture2D from the captures, and after the game ends, write all on the disk.
The problem is, when I capture one Texture2D texture from the webcam and try to do a List.Add(texture), all the elements of the list are updated because it store the reference of texture, not the Texture itself. Can anyone please, suggest me one alternative to store all the textures?
Edit: inserting code.
public class GetPhoto : MonoBehaviour
{
WebCamTexture webcam;
Texture2D photo;
List<Texture2D> photos;
IEnumerator TakePhoto()
{
//run when user click on object.
yield return new WaitForEndOfFrame();
photo.SetPixels(webcam.GetPixels());
photo.Apply();
photos.Add(photo);
}
}

As said rather use a new Texture2D instance for every press like e.g.
IEnumerator TakePhoto()
{
//run when user click on object.
yield return new WaitForEndOfFrame();
var photo = new Texture2D(yourTextureWidth, yourTextureHeight);
photo.SetPixels(webcam.GetPixels());
photo.Apply();
photos.Add(photo);
}
otherwise every entry in your list refers to the exact same Texture2D instance => everytime you overwrite the content of that instance.

Related

Unity : From large image to map / terrain / texture

In Unity, I'd like to generate 2D map from a large image file (965012573).
I already have a tile/image pieces generator but it generates 1900 images 256256, and it seems hard to create a map by hand like this (and I have more then one large image to process...).
These image pieces are sorted like this :
x/y.png
Where x starts from left to right and y from top to bottom.
As MelvMay suggests me here, I should use textures to achieve that, but how?
Do you have any idea of how to achieve that programmatically? Or may be with an existing bundle?
Thanks a lot!
[edit] As a workaround, I tried this :
public class MapGenerator : MonoBehaviour {
private Renderer m_Renderer;
private Texture2D m_MainTexture;
// Use this for initialization
void Start () {
//Fetch the Renderer from the GameObject
m_Renderer = GetComponent<Renderer> ();
m_MainTexture = LoadPNG("Assets/Tiles/Ressources/Map/0/3.png");
m_Renderer.material.mainTexture = m_MainTexture;
}
private Texture2D LoadPNG(string filePath) {
Texture2D tex = null;
byte[] fileData;
if (File.Exists(filePath)) {
UnityEngine.Debug.Log(filePath);
fileData = File.ReadAllBytes(filePath);
tex = new Texture2D(2, 2);
tex.LoadImage(fileData); //..this will auto-resize the texture dimensions.
}
return tex;
}
}
But even if I apply it on an empty object, I only see my dynamic texture in the inspector, not in the scene when I press run...

How can i update an image on runtime in unity?

I'm buidling a smooth transtion from a level scene to a menu scene.
The idea is to make a screenshot of the level just before the next scene(menu) loads.
then take this screenshot which overlays the entire screen and will fade out to reveal the menu.
At the end of a level I take a screen shot.
ScreenCapture.CaptureScreenshot("Resources/DestroyedBoss.png");
When I load the next scene this screenshot should load and overlay the entire scene.
public Texture2D myTexture;
void Start()
{
// load texture from resource folder
myTexture = Resources.Load("DestroyedBoss") as Texture2D;
GameObject rawImage = GameObject.Find("RawImage");
rawImage.GetComponent<RawImage>().texture = myTexture;
}
The screenshot will fade and the object containing it will be destroyed.
public RawImage imageToFade;
void Update()
{
imageToFade.color -= new Color(0, 0, 0, 0.2f * Time.deltaTime);
if (imageToFade.color.a < 0.1)
Destroy(this.gameObject);
}
This all works fine, except for loading of the screenshot itself.
It would seem that unity does not update the image while running the game. And always uses the screenshot from the previous time I ran the game.
I have been searching/googling and trying for 2 days now and I am at a loss.
How can I make this work? Is there a way to update the png file while running my game? Maybe create a temp container for the screenshot and set this to the RawImage?
Like derHugo commented. you can use Application.persistentDataPath to save your image.
ScreenCapture.CaptureScreenshot(Application.persistentDataPath+"DestroyedBoss.png");
For loading the image, you can use UnityWebRequestTexture.GetTexture.
IEnumerator SetImage()
{
yield return new WaitForSeconds(1);
using (UnityWebRequest uwr =
UnityWebRequestTexture.GetTexture(Application.persistentDataPath + "DestroyedBoss.png"))
{
yield return uwr.SendWebRequest();
if (uwr.isNetworkError || uwr.isHttpError)
{
Debug.Log(uwr.error);
}
else
{
// Get downloaded asset bundle
myTexture = DownloadHandlerTexture.GetContent(uwr);
GameObject rawImage = GameObject.Find("RawImage");
rawImage.GetComponent<RawImage>().texture = myTexture;
FadeOut.instance.StartFade();
}
}
}
It works ok, but it takes a few seconds for the screenshot to appear in the folder. So for me... it does not work great.
I'll be using another technique.
Instead of fading the screenshot while loading the menu. I'll stop the game, (Time.timescale = 0) and fade in a screenshot of the menu, then load the actual menu scene.
Thanks again derHugo.

Change Texture2D format in unity

I have a Textured2D loaded which is represented in ETC_RGB4 how can I change this to another format? say RGBA32. Basically I want to switch from 3 channels to 4 and from 4 bit per channel to 8 per channel.
Thanks
You can change texture format during run-time.
1.Create new empty Texture2D and provide RGBA32 to the TextureFormat argument. This will create an empty texture with the RGBA32 format.
2.Use Texture2D.GetPixels to obtain the pixels of the old texture that's in ETC_RGB4 format then use Texture2D.SetPixels to put those pixels in the newly created Texture from #1.
3.Call Texture2D.Apply to apply the changes. That's it.
A simple extension method for this:
public static class TextureHelperClass
{
public static Texture2D ChangeFormat(this Texture2D oldTexture, TextureFormat newFormat)
{
//Create new empty Texture
Texture2D newTex = new Texture2D(2, 2, newFormat, false);
//Copy old texture pixels into new one
newTex.SetPixels(oldTexture.GetPixels());
//Apply
newTex.Apply();
return newTex;
}
}
USAGE:
public Texture2D theOldTextue;
// Update is called once per frame
void Start()
{
Texture2D RGBA32Texture = theOldTextue.ChangeFormat(TextureFormat.RGBA32);
}

Download and open png image?

In Unity, this script loads on the start of the program. I want to download an image, and after that show it on the main screen. What should I do? The following code did not work.
My code:
using UnityEngine;
public class PushNotifications : MonoBehaviour {
IEnumerator Start () {
Texture2D textWebPic = null;
WWW image = new WWW("http://www.test.com/image.png");
yield return image;
image.LoadImageIntoTexture(textWebPic);
}
void Update () {
}
}
You can't pass null to LoadImageIntoTexture, since then Unity has no idea where to put the output (it is not ref). The texture must be initialized first.
It does not really matter, however, with what size or format you initialize it, unity will resize it anyway. So you can initialize some dummy, like this to load the image:
IEnumerator Start () {
Texture2D textWebPic = new Texture2D(2,2);
WWW image = new WWW("http://www.test.com/image.png");
yield return image;
image.LoadImageIntoTexture(textWebPic);
}
Another, and probably better option is to use WWW.texture instead of LoadImageIntoTexture, like this:
IEnumerator Start () {
WWW image = new WWW("http://www.test.com/image.png");
yield return image;
Texture2D textWebPic = image.texture;
}
See WWW class reference for more examples:
http://docs.unity3d.com/ScriptReference/WWW.html
And then to show it on the screen you have multiple option - creating a material with this texture, creating sprite from texture (best for 2d games) or simply use Graphics.DrawTexture.

Texture not Assigning to GameObject on Button Click

I'm hung up on something that I've not been able to work out and I could really use a fresh set of eyes on it. I'm loading up an array of images, assigning one of them to a texture in LoadGallery.cs. Then in LoadImage I have a button that when clicked runs LoadImg but when I click the button nothing happens. The texture doesn't get assigned to the GameObject. I'm not getting any errors either. The script works fine when it's all within the IEnumerator function, but when I pull it out into a different script I'm getting nothing. What am I getting wrong?
LoadGallery.cs
public Texture2D tex;
// Use this for initialization
void Start () {
StartCoroutine("LoadAllImages");
}
IEnumerator LoadAllImages()
{
string[] filePaths = Directory.GetFiles(#"/Users/kenmarold/Screenshots/TATUS/", "*.png");
WWW www = new WWW("file://" + filePaths[0]);
yield return www;
Texture2D tex = new Texture2D(512,512);
www.LoadImageIntoTexture(tex);
}
LoadImage.cs
void LoadImg()
{
GameObject galleryLoader = GameObject.FindGameObjectWithTag("GalleryLoader");
LoadGallery loadGallery = galleryLoader.GetComponent<LoadGallery>();
Rect rct = new Rect(0, 0, loadGallery.tex.width, loadGallery.tex.height);
Vector2 pvt = new Vector2(0.5f, 0.5f);
GameObject screenShotImg = GameObject.FindGameObjectWithTag("screenshot");
Image img = screenShotImg.GetComponent<Image>();
img.sprite = Sprite.Create(loadGallery.tex, rct, pvt);
}
I could not see what's wrong with what you are doing. These are common mistakes from my experience:
1. You might have forgotten to assign the function LoadImg to the button.
2. The size of UI object "screenshot" is too small. Try assigning some dummy image to see if it's actually showing something.
3. There could have been some exception when loading gallery. Try to check for www.error. Debug it carefully.
Good luck with your work.

Categories

Resources