How to encode to png a webcam texture? - c#

Setup: Unity 2019
I am trying to get the texture from a plane.
I capture the camera input and map it on a plane. Then i want to read the texture continuously.
I tried something like this. PS: I am new with unity.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class CameraInput : MonoBehaviour
{
static WebCamTexture backCam;
void Start()
{
if (backCam == null)
backCam = new WebCamTexture();
GetComponent<Renderer>().material.mainTexture = backCam;
if (!backCam.isPlaying)
backCam.Play();
}
void Update()
{
byte[] bytes = GetComponent<Renderer>().material.mainTexture.EncodeToPNG();
System.IO.File.WriteAllBytes(path, bytes);
Debug.Log(bytes.Length/1024 + "Kb was saved as: " + path);
}
}
Error received:
Unable to retrieve image reference
UnityEngine.ImageConversion:EncodeToPNG(Texture2D)

I think you are missing a few steps
get list of available devices
set device name into webcam
play the webcam before setting the texture

Webcam is a Texture and you can encodetopng Texture2d.
So the solution to this is:
Texture2D tex = new Texture2D(backCam.width, backCam.height);
tex.SetPixels(backCam.GetPixels());
tex.Apply();
byte[] bytes = tex.EncodeToPNG();

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...

Build and Load AssetBundles with Unity for videos?

I'm trying to build an application for OculusGO but the file is too big so I'm working with AssetBundles to lower the size. I've worked with this link so far Build and load Assetbundles in Unity but I don't know how to do this with videos.
I currently have this as my loader for the application but I need it to load from the AssetBundle
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Video;
[CreateAssetMenu(fileName = "Situation", menuName = "Situation", order = 1)]
public class SituationData : ScriptableObject
{
public VideoClip video;
public AssetBundle.LoadFromFileAsync(Assets/StreamingAssets/AssetBundles);
public Sprite screenshot;
public Sprite situationPanel;
public Sprite situationPanelSelected;
public string objectiveText;
public string sessionName;
public float startRotation;
IEnumerator LoadAsset(string assetBundleName, string objectNameToLoad)
{
string filePath = System.IO.Path.Combine(Application.streamingAssetsPath, "AssetBundles");
filePath = System.IO.Path.Combine(filePath, assetBundleName);
//Load "animals" AssetBundle
var assetBundleCreateRequest = AssetBundle.LoadFromFileAsync(filePath);
yield return assetBundleCreateRequest;
AssetBundle asseBundle = assetBundleCreateRequest.assetBundle;
//Load the "dog" Asset (Use Texture2D since it's a Texture. Use GameObject if prefab)
AssetBundleRequest asset = asseBundle.LoadAssetAsync<VideoClip>(objectNameToLoad);
yield return asset;
//Retrieve the object (Use Texture2D since it's a Texture. Use GameObject if prefab)
VideoClip loadedAsset = asset.asset as VideoClip;
//Do something with the loaded loadedAsset object (Load to RawImage for example)
image.texture = loadedAsset;
}
}
Just for clarity, I've already built the AssetBundles, I just don't know how to load those in instead of the actual video files so I can reduce the file size.

Capture and Show Video from IP camera source (Unity3d + c#)

Need your help.
I am making simple application (and I'm a new to Unity3d also), which takes video from IP-camera and displays it onto Texture2D.
Video format is MJPG.
For simple jpg-images the code below works fine, but when I try to display MJPG I just get gray screen.
Did I make a mistake in code?
public class testVid : MonoBehaviour {
//public string uri = "http://24.172.4.142/mjpg/video.mjpg"; //url for example
public Texture2D cam;
public void Start() {
cam = new Texture2D(1, 1, TextureFormat.RGB24, false);
StartCoroutine(Fetch());
}
public IEnumerator Fetch() {
while(true) {
Debug.Log("loading... " + Time.realtimeSinceStartup);
WWWForm form = new WWWForm();
WWW www = new WWW("http://24.172.4.142/mjpg/video.mjpg");
yield return www;
if(!string.IsNullOrEmpty(www.error))
throw new UnityException(www.error);
www.LoadImageIntoTexture(cam);
}
}
public void OnGUI() {
GUI.DrawTexture(new Rect(0, 0, Screen.width, Screen.height), cam);
}
}
I used this plugin https://www.assetstore.unity3d.com/en/#!/content/15580
Add the script to a game object
Set the URL of the video in the script
Create a new material of Unlit 2D
Add this material to the movie script in the inspector
Then assign the same material to the game object you
want to display the video (e.g. a quad)
Hope it helps

Unity3d attach texture to the cube problems

I have created a cube in the scene and I want to attach the texture to the cube by scripting.
The problem is there is no error of my code but The cube doesn't change after I press run in my program...
Here is my code
using UnityEngine;
using System.Collections;
public class testing : MonoBehaviour {
void start(){
Texture2D tex = (Texture2D)Resources.Load("BlueColorTex.png", typeof(Texture2D));
renderer.material.mainTexture = tex;
}
}
void start()
{
Texture2D tex = (Texture2D)Resources.Load("BlueColorTex", typeof(Texture2D));
renderer.material.mainTexture = tex;
}
Resources.Load does not use extensions. This is a common mistake.
Returns the asset at path if it can be found otherwise returns null.
Only objects of type T will be returned. The path is relative to any
Resources folder inside the Assets folder of your project,
extensions must be omitted.
from: http://docs.unity3d.com/ScriptReference/Resources.Load.html

Texture downloaded from server appears black on iOS

I am building an application in Unity3d, and I need to download textures from my server and apply them to prefabs.
I have two types of prefabs;
The first is a simple plane that I use to display 2d images, and the second is a prefab to play videos and have a thumbnail texture that is displayed before the video is played in full screen.
I am having problems with the video prefab. If I create a public texture in my script and apply it to the prefab, everything works fine. However, if I download the texture from my server and apply it to the prefab it appears black. This only happens in iOS, in the Unity Player everything appears fine.
Here is my code:
Instantiate the prefab:
newVideo = (GameObject)Instantiate(arvideo, new Vector3(15*i, 0, 0), Quaternion.identity);
newVideo.GetComponent<VideoPlaybackBehaviour>().m_path = ((Assets)Data.Assets[i]).AssetContent; // SET THE URL FOR THE VIDEO
string url = ((Assets)Data.Assets[i]).AssetThumbnail;
StartCoroutine(DownloadImage(url, newVideo, ((Assets)Data.Assets[i]).AssetFilename, "VIDEO"));
newVideo.transform.rotation = Quaternion.Euler(0, -180, 0);
Download IEnumerator:
public IEnumerator DownloadImage(string url, GameObject tex, string filename, string type)
{
WWW www = new WWW(url);
yield return www;
/* EDIT: */
if (!string.IsNullOrEmpty(www.error)){
Debug.LogWarning("LOCAL FILE ERROR: "+www.error);
} else if(www.texture == null) {
Debug.LogWarning("LOCAL FILE ERROR: TEXTURE NULL");
} else {
/* EOF EDIT */
tex.GetComponent<VideoPlaybackBehaviour>().KeyframeTexture = www.texture;
Color color = tex.renderer.material.color;
color.a = 1f;
tex.renderer.material.color = color;
}
}
I struggled with same issue. And after several hours search, for my case i solved this problem with disabling "Metal write-only BackBuffer" in iOS player settings. I'm using unity 2020.1.8f1 and actually i have no any idea about why back buffer setting is causing black texture problem in iOS devices.

Categories

Resources