Unity - Generated sprite not visible on iOS - c#

currently i'm downloading an image from web via WWW. That works perfect for all targeted platforms excepting iOS.
On iOS the image appears just black.
Here is the code:
public void receiveData(WWW receivedData)
{
image.sprite = Sprite.Create(receivedData.texture, new Rect(new Vector2(0,0), new Vector2(50, 50)), new Vector2(0.5f, 0.5f));
image.color = Color.white;
}
I've been trying around for some time now without any results...
F.E. i tried to change the format of the texture with textureFormat or creating a new Texture2D and changed the pixel. But all results in a black image.
Does anyone have an idea what the matter is?
Best Regards

It is likely black because the WWW is not yet finished downloading on iOS. That code should be in a coroutine function and you have to wait with yield return receivedData. If this does not solve your problem, you have to post the rest of your code but this is likely the problem.
public IEnumerator receiveData(WWW receivedData)
{
//Wait to finish downloading image
yield return receivedData;
//You can now create sprite from the data image
image.sprite = Sprite.Create(receivedData.texture, new Rect(new Vector2(0,0), new Vector2(50, 50)), new Vector2(0.5f, 0.5f));
image.color = Color.white;
}

How large is the image? Is it possible you are exceeding the maximum allowed image size for the hardware?

Related

Take a screenshot without the UI elements in Unity [duplicate]

This question already has answers here:
Can I take a photo in Unity using the device's camera?
(8 answers)
Closed 1 year ago.
I am trying to capture what the camera sees in phone in an AR app and take a photo of it. What I found was to take a screenshot of the device and then save that as an image. However, I want to take a screenshot of what the camera sees instead of the screen. That is without any 2D or 3D elements created in the application. Just purely what the camera sees. How do I do this?
public void Start() {
StartCoroutine ("SaveImage");
}
WaitForEndOfFrame frameEnd = new WaitForEndOfFrame ();
IEnumerator SaveImage() {
// Create a texture the size of the screen, RGB24 format
int width = Screen.width;
int height = Screen.height;
yield return frameEnd;
var tex = new Texture2D (width, height, TextureFormat.RGB24, false);
// Read screen contents into the texture
tex.ReadPixels (new Rect (0, 0, width, height), 0, 0);
tex.Apply ();
byte[] bytes = tex.EncodeToPNG ();
Destroy (tex);
var form = new WWWForm ();
form.AddField ("plant", plantComponentID);
form.AddBinaryData ("image", bytes, "screenShot.png", "image/png");
yield return null;
}
Interesting question.
What I would try is to set up a RenderTexture, and tell a camera in your scene to render to it. Then I would try to use the
ImageConversion class to get my camera eye screenshot to a file.
This is just what my attempt would be. Not sure if that is the correct way, so providing that just in case it helps. I would be glad to know the outcome of your attempt in case you try it :)

How to create a Texture2D without corrupting video memory?

In Monogame, I'm creating a 2D texture that's a horizontal flip of an existing texture using GetData and SetData like this:
private static Texture2D Flip(Texture2D art)
{
Color[] oldData = new Color[art.Width * art.Height];
art.GetData(oldData);
Texture2D newTexture = new Texture2D(Root.Graphics.GraphicsDevice, art.Width, art.Height);
Color[] newData = new Color[art.Width * art.Height];
// Edit newData using oldData
newTexture.SetData(newData);
return newTexture;
}
This seemed to work on Windows but when running it on Android, although the flip itself works, some other, seemingly random and unrelated, texture gets corrupted: it becomes an amalgam of several textures and partially vertically flipped.
I suspect that my call to SetData somehow overwrites another region of memory or something.
How can I create programatically a new texture without this corruption happening?

Why does unity show question mark instead of desired sprite?

In unity3d, I am using WWW class to download a texture from link, then I am creating a Sprite with the obtained texture and I am displaying it on the screen. This is working just fine in Unity Editor, but when I run it in the browser as HTML5 instead of displaying my Sprite, there is a red question mark. Why?
This is my C# code:
GameObject myImage;
Sprite neededSprite;
IEnumerator Start () {
WWW getMyImage= new WWW("http://previews.123rf.com/images/burakowski/burakowski1202/burakowski120200228/12221967-Grunge-Example-stamp-Stock-Vector-demo.jpg");
myImage = GameObject.Find("myImage");
yield return getMyImage;
Texture2D rawImage = getMyImage.texture;
neededSprite = Sprite.Create(rawImage, new Rect(0.0f, 0.0f, rawImage.width, rawImage.height), new Vector2(0.5f, 0.5f), 100.0f);
myImage.GetComponent<Image>().sprite = neededSprite;
}
After placing Header set Access-Control-Allow-Origin "*" in .htaccess file, everything is working as excepted

XNA Second Graphics Device for RenderToTarget

I'm creating an XNA game that creates random islands from multiple sprites. It creates them in a separate thread, then compiles them to a single texture using RenderTarget2D.
To create my RenderTarget2D I need a graphics device. If I use the automatically created graphics device, things work okay for the most part, except that draw calls in the main game thread conflict with it. Using lock() on the graphics device causes flickering, and even then the texture is sometimes not created properly.
If I create my own Graphics device, there are no conflicts but the islands never render correctly, instead coming out pure black and white. I have no idea why this happens. Basically I need a way to create a second graphics device that lets me get the same results, instead of the black / white. Anyone got any ideas?
Here's the code I'm using to try and create my second graphics device for exclusive use by the TextureBuilder:
var presParams = game.GraphicsDevice.PresentationParameters.Clone();
// Configure parameters for secondary graphics device
GraphicsDevice2 = new GraphicsDevice(game.GraphicsDevice.Adapter, GraphicsProfile.HiDef, presParams);
Here's the code I'm using to render my islands to a single texture:
public IslandTextureBuilder(List<obj_Island> islands, List<obj_IslandDecor> decorations, SeaGame game, Vector2 TL, Vector2 BR, int width, int height)
{
gDevice = game.Game.GraphicsDevice; //default graphics
//gDevice = game.GraphicsDevice2 //created graphics
render = new RenderTarget2D(gDevice, width, height, false, SurfaceFormat.Color, DepthFormat.None);
this.islands = islands;
this.decorations = decorations;
this.game = game;
this.width = width;
this.height = height;
this.TL = TL; //top left coordinate
this.BR = BR; //bottom right coordinate
}
public Texture2D getTexture()
{
lock (gDevice)
{
//Set render target. Clear the screen.
gDevice.SetRenderTarget(render);
gDevice.Clear(Color.Transparent);
//Point camera at the island
Camera cam = new Camera(gDevice.Viewport);
cam.Position = TL;
cam.Update();
//Draw all of the textures to render
SpriteBatch batch = new SpriteBatch(gDevice);
batch.Begin(SpriteSortMode.BackToFront, BlendState.AlphaBlend, null, null, null, null, cam.Transform);
{
foreach (obj_Island island in islands)
{
island.Draw(batch);
}
foreach (obj_IslandDecor decor in decorations)
{
decor.Draw(batch);
}
}
batch.End();
//Clear render target
gDevice.SetRenderTarget(null);
//Copy to texture2D for permanant storage
Texture2D texture = new Texture2D(gDevice, render.Width, render.Height);
Color[] color = new Color[render.Width * render.Height];
render.GetData<Color>(color);
texture.SetData<Color>(color);
Console.WriteLine("done");
return texture;
}
Here's what should happen, with a transparent background (and usually does if I use the default device)
http://i110.photobucket.com/albums/n81/taumonkey/GoodIsland.png
Here's happens when the default device conflicts and the main thread manages to call Clear() (even though it's locked too)
NotSoGoodIsland.png (need 10 reputation....)
Here's what happens when I use my own Graphics device
http://i110.photobucket.com/albums/n81/taumonkey/BadIsland.png
Thanks in advance for any help provided!
I may have solved this by moving the RenderToTarget code into the Draw() method and calling it from within the main thread the first time Draw() is called.

How to save a texture2D as a jpeg to a file

I'm attempting to draw many textures onto one texture to create a map for an RTS game, and while I can can draw an individual texture onscreen, drawing them all to a render target seems to have no effect (the window remains AliceBlue when debugging) . I am trying to determine whether or not anything is even drawn to the render target, and so I am trying to save it as a Jpeg to a file and then view that Jpeg, from my desktop. How can I access that Jpeg from MemoryStream?
protected override void LoadContent()
{
spriteBatch = new SpriteBatch(GraphicsDevice);
gridImage = new RenderTarget2D(GraphicsDevice, 1000, 1000);
GraphicsDevice.SetRenderTarget(gridImage);
GraphicsDevice.Clear(Color.AliceBlue);
spriteBatch.Begin();
foreach (tile t in grid.tiles)
{
Texture2D dirt = Content.Load<Texture2D>(t.texture);
spriteBatch.Draw(dirt, t.getVector2(), Color.White);
}
test = Content.Load<Texture2D>("dirt");
GraphicsDevice.SetRenderTarget(null);
MemoryStream memoryStream = new MemoryStream();
gridImage.SaveAsJpeg(memoryStream, gridImage.Width, gridImage.Height); //Or SaveAsPng( memoryStream, texture.Width, texture.Height )
// rt.Dispose();
spriteBatch.End();
}
I made a simple screenshot method,
void Screenie()
{
int width = GraphicsDevice.PresentationParameters.BackBufferWidth;
int height = GraphicsDevice.PresentationParameters.BackBufferHeight;
//Force a frame to be drawn (otherwise back buffer is empty)
Draw(new GameTime());
//Pull the picture from the buffer
int[] backBuffer = new int[width * height];
GraphicsDevice.GetBackBufferData(backBuffer);
//Copy to texture
Texture2D texture = new Texture2D(GraphicsDevice, width, height, false, GraphicsDevice.PresentationParameters.BackBufferFormat);
texture.SetData(backBuffer);
//Get a date for file name
DateTime date = DateTime.Now; //Get the date for the file name
Stream stream = File.Create(SCREENSHOT FOLDER + date.ToString("MM-dd-yy H;mm;ss") + ".png");
//Save as PNG
texture.SaveAsPng(stream, width, height);
stream.Dispose();
texture.Dispose();
}
Also, Are you loading Texture2D dirt = Content.Load<Texture2D>(t.texture); Every frame? It looks like it... Dont do that! That will cause massive lag loading hundreds of tiles, hundreds of times per second! instead make a global texture Texture2D DirtDexture and in your LoadContent() method do DirtTexture = Content.Load<Texture2D>(t.texture); Now when you draw you can do spriteBatch.Draw(DirtTexture,...
Do the same with spriteBatch = new SpriteBatch(GraphicsDevice); and
gridImage = new RenderTarget2D(GraphicsDevice, 1000, 1000);
You dont need to make new RenderTarget and Spritebatch each frame! Just do it in the Initialize() Method!
Also see RenderTarget2D and XNA RenderTarget Sample For more information on using render targets
EDIT: I realize its all in LoadContent, I didnt see that because the formatting was messed up, remember to add your Foreach (Tile, etc) in your Draw Method

Categories