Creating a 2d sprite with saved image in assets - c#

I have in my assets a folder resources and inside an image pig.png, I want to create a sprite from code with this image, Here is my code:
var filePath = Application.dataPath + "/Resources/pig.png";
if (System.IO.File.Exists(filePath))
{
var bytes = System.IO.File.ReadAllBytes(filePath);
Texture2D tex = new Texture2D(1, 1);
tex.LoadImage(bytes);
Sprite sp = new Sprite();
sp = Sprite.Create(tex, new Rect(0, 0, 100, 100), new Vector2(0.5f, 0.5f),40);
}
The code runs when I click a button inside a gui, What's wrong?
Fixed code:
Texture2D tex = Resources.Load<Texture2D>("pig") as Texture2D;
Sprite sprite = new Sprite();
sprite = Sprite.Create(tex, new Rect(0, 0, 250, 150), new Vector2(0.5f, 0.5f));
GameObject newSprite = new GameObject();
newSprite.AddComponent<SpriteRenderer>();
SpriteRenderer SR = newSprite.GetComponent<SpriteRenderer>();
SR.sprite = sprite;

If your pig image is in the Assets/Resources folder, then you have to load the image with Resources.Load function not with File.ReadAllBytes.
//Assign Sprite from Editor. (Where to display the loaded image sprite)
public Image displaySprite;
void loadImage()
{
//Load Image
Texture2D tex = Resources.Load("pig", typeof(Texture2D)) as Texture2D;
if (tex != null)
{
//Create new Sprite from the Loaded Sprite
Sprite sp = new Sprite();
sp = Sprite.Create(tex, new Rect(0, 0, 100, 100), new Vector2(0.5f, 0.5f), 40);
Debug.Log("Not Null");
//Show Image to screen
displaySprite.sprite = sp;
}
else
{
Debug.Log("Null");
}
}

Related

Unity Picture From Camera Clear in Center, Distorted at Edges

I am fairly new to Unity but am trying to take a photo from the camera and save it. Taking a screen capture is not an option. When I take the photo it appears clear in the center of the photo but gets further distorted towards the edges and I am not sure why. The main camera is linked to the realCamera object in Unity.
The screenshot code, which calls on update is:
DirectoryInfo screenshotDirectory = Directory.CreateDirectory(directoryName);
fileO = original + fileNameEnd + count.ToString() + fileType;
string fullPathO = Path.Combine(screenshotDirectory.FullName, fileO);
RenderTexture rt = new RenderTexture(resWidth, resHeight, 24);
Texture2D screenShot = new Texture2D(resWidth, resHeight, TextureFormat.RGB24, false);
byte[] bytes;
realCamera.targetTexture = rt;
realCamera.Render();
RenderTexture.active = rt;
screenShot.ReadPixels(new Rect(0, 0, resWidth, resHeight), 0, 0);
realCamera.targetTexture = null;
RenderTexture.active = null;
Destroy(rt);
bytes = screenShot.EncodeToPNG();
System.IO.File.WriteAllBytes(fullPathO, bytes);

Unity - How to change sprite size to fixed resoltion in code

I have a set of sprites with different resolutions and aspect ratios. I want to create new sprites based on the original sprites but with a fixed 20 x 20 resolution.
When working with bitmaps, what I did was this: Bitmap newImage = new Bitmap(oldImage, new Size(20, 20));
But Unity's Sprites don't have any constructors. How can I do this?
There are 2 ways to create Sprites from image or original sprite.
from image code below..
string url = "";//image url;
WWW image = new WWW(url);
yield return image;
Texture2D texture = new Texture2D(1, 1);
image.LoadImageIntoTexture(texture);
Sprite newSprite = Sprite.Create(texture, new Rect(0, 0, texture.width, texture.height), new Vector2(0, 0), 1);
RectTransform rt = newSprite.GetComponent<RectTransform>();
rt.sizeDelta = new Vector2(20, 20);//make 20px * 20px sprite
clone sprite code below..
Sprite cloneSprite = Instantiate(originalSprite);
RectTransform rt = cloneSprite.GetComponent<RectTransform>();
rt.sizeDelta = new Vector2(20, 20);//make 20px * 20px sprite
I hope it will work on your project.
Not sure how exactly you want to resize an image (make it smaller, or cut the part of it), but you can play around with Sprite.Create method

Saving Target Texture as an image

I have got a quad that has got a target texture set through Unity Editor. I would like to save the output visualization on the quad as an image. Are there any ways to save it as a quad? I have tried through texture2d but its just a black image that is being saved.
Try this
private void SaveImage(Texture t, string path)
{
RenderTexture rt = new RenderTexture(t.width, t.height, 0);
Graphics.Blit(t, rt);
Texture2D t2d = new Texture2D(rt.width, rt.height, TextureFormat.RGB24, false);
t2d.ReadPixels(new Rect(0, 0, rt.width, rt.height), 0, 0);
File.WriteAllBytes(path, t2d.EncodeToPNG());
}
Usage
SaveImage(yourQuad.GetComponent<MeshRenderer>().material.mainTexture, "yourSavePath.png");

Creating a Sprite in size

I have a gallery scene and I want to load PNG's from Persistence path .
The thing is that I want them as thumbnails, theirs no need for me to load the full size file .
How can I defined the scale of the sprite?
that the relevant line for the creating of the sprite:
Sprite sp1 = Sprite.Create(texture1, new Rect(0, 0, texture1.width, texture1.height), new Vector2(0.5f, 0.5f), 100, 0, SpriteMeshType.FullRect);
and that the texture creating code:
Texture2D takeScreenShotImage(string filePath)
{
Texture2D texture = null;
byte[] fileBytes;
if (File.Exists(filePath))
{
fileBytes = File.ReadAllBytes(filePath);
texture = new Texture2D(1, 1, TextureFormat.ETC2_RGB, false);
texture.LoadImage(fileBytes);
}
return texture;
}
The proper place to make that change is on the Texture2D after loading the Texture. If you really want to load them as thumbnails and want the size to be smaller to save memory then resize it with the Texture2D.Resize function after loading the Texture. The height and width of 60 should be fine. You can then create Sprite from it with Sprite.Create.
Texture2D takeScreenShotImage(string filePath)
{
Texture2D texture = null;
byte[] fileBytes;
if (File.Exists(filePath))
{
fileBytes = File.ReadAllBytes(filePath);
texture = new Texture2D(1, 1, TextureFormat.ETC2_RGB, false);
texture.LoadImage(fileBytes);
}
//RE-SIZE THE Texture2D
texture.Resize(60, 60);
texture.Apply();
return texture;
}
Note that TextureFormat.ETC2_RGB is compressed. To resize it you may have to create a copy of it. See #1 solution from my other post on how to do this.

Rerfreshing android camera roll in unity3d

I made a simple app for android devices that uses mobile's camera to take a photo and save it in internal storage folder /mnt/sdcard/DCIM/Camerizeman/
Photos are saved correctly but the problem that i am faceing is that i can't see the photos from mobile's gallery. I can see them correctly if i use a file manager or reboot me device. i am searchig 10 days now and the problem is that i have to refresh the gallery after saving the image.
I didn't found any working solution.
my code is bellow:
RenderTexture renderTex;
Texture2D screenshot;
Texture2D LoadScreenshot;
int width = Screen.width; // for Taking Picture
int height = Screen.height; // for Taking Picture
string fileName;
string myScreenshotLocation;
string screenShotName = "MyImage_AR_" + System.DateTime.Now.ToString("yyyy-MM-dd-HHmmss") + ".png";
public void Snapshot ()
{
StartCoroutine (CaptureScreen ());
}
public IEnumerator CaptureScreen ()
{
yield return null; // Wait till the last possible moment before screen rendering to hide the UI
//GameObject.FindGameObjectWithTag("Snapshoot").SetActive(false);
yield return new WaitForEndOfFrame (); // Wait for screen rendering to complete
if (Screen.orientation == ScreenOrientation.Portrait || Screen.orientation == ScreenOrientation.PortraitUpsideDown) {
mainCamera = Camera.main.GetComponent<Camera> (); // for Taking Picture
renderTex = new RenderTexture (width, height, 24);
mainCamera.targetTexture = renderTex;
RenderTexture.active = renderTex;
mainCamera.Render ();
screenshot = new Texture2D (width, height, TextureFormat.RGB24, false);
screenshot.ReadPixels (new Rect (0, 0, width, height), 0, 0);
screenshot.Apply (); //false
RenderTexture.active = null;
mainCamera.targetTexture = null;
}
if (Screen.orientation == ScreenOrientation.LandscapeLeft || Screen.orientation == ScreenOrientation.LandscapeRight) {
mainCamera = Camera.main.GetComponent<Camera> (); // for Taking Picture
renderTex = new RenderTexture (height, width, 24);
mainCamera.targetTexture = renderTex;
RenderTexture.active = renderTex;
mainCamera.Render ();
screenshot = new Texture2D (height, width, TextureFormat.RGB24, false);
screenshot.ReadPixels (new Rect (0, 0, height, width), 0, 0);
screenshot.Apply (); //false
RenderTexture.active = null;
mainCamera.targetTexture = null;
}
myScreenshotLocation = myFolderLocation + screenShotName;
File.WriteAllBytes (myFolderLocation + screenShotName, screenshot.EncodeToPNG ());
}
Please help!
The second working solution is:
using (AndroidJavaClass jcUnityPlayer = new AndroidJavaClass("com.unity3d.player.UnityPlayer"))
using (AndroidJavaObject joActivity = jcUnityPlayer.GetStatic<AndroidJavaObject>("currentActivity"))
using (AndroidJavaObject joContext = joActivity.Call<AndroidJavaObject>("getApplicationContext"))
using (AndroidJavaClass jcMediaScannerConnection = new AndroidJavaClass("android.media.MediaScannerConnection"))
using (AndroidJavaClass jcEnvironment = new AndroidJavaClass("android.os.Environment"))
using (AndroidJavaObject joExDir = jcEnvironment.CallStatic<AndroidJavaObject>("getExternalStorageDirectory"))
{
jcMediaScannerConnection.CallStatic("scanFile", joContext, new string[] { YOURFULL IMAGE PATH}, null, null);
}
Use MediaScannerConnection. You need the image "scanned into" the gallery.
Native Java Code goes something like:
MediaScannerConnection.scanFile(unityPlayerActivity, new String[]{externalImagePath}, null, null);
May Create plugin - Unity Android plugin tutorial (1/3) Fundamentals -, or use AndroidJavaClass.CallStatic to invoke a MediaScannerConnection.scanFile.

Categories