- Home /
Rotate the contents of a texture
I have this simple bit of code to load an image from a file and display it:
Texture2D text = new Texture2D(1024, 1024);
Debug.Log ("text" + text.ToString());
www.LoadImageIntoTexture(text);
Debug.Log ("Text loaded" + text.ToString());
GameObject imageObject = GameObject.Find ("PlayerRawImage");
RawImage raw = imageObject.GetComponentInChildren<RawImage>();
Debug.Log ("Got raw");
raw.texture = text;
Now it turns out that the image the camera writes to the file is rotated by 90 degrees. Is there any not too complicated way to have that be rotated? I have seen lots of stuff about custom shaders but I don't have the first clue where to begin.
Is there really no easy way to do this?
If this is the object that displays the texture: imageObject And you know the image always faces imageObject.transform.forward You can rotate the DISPLAY of the object, without ever touching the image data.
imageObject.transform.localRotation *= Quaternion.AngleAxis(90, Vector3.forward);
Answer by KwahuNashoba · Sep 02, 2017 at 11:35 PM
Here is my solution. It takes Texture2D and returns Texture2D. You can also set if you want it to rotate clockwise or counterclockwise.
Texture2D rotateTexture(Texture2D originalTexture, bool clockwise)
{
Color32[] original = originalTexture.GetPixels32();
Color32[] rotated = new Color32[original.Length];
int w = originalTexture.width;
int h = originalTexture.height;
int iRotated, iOriginal;
for (int j = 0; j < h; ++j)
{
for (int i = 0; i < w; ++i)
{
iRotated = (i + 1) * h - j - 1;
iOriginal = clockwise ? original.Length - 1 - (j * w + i) : j * w + i;
rotated[iRotated] = original[iOriginal];
}
}
Texture2D rotatedTexture = new Texture2D(h, w);
rotatedTexture.SetPixels32(rotated);
rotatedTexture.Apply();
return rotatedTexture;
}
$$anonymous$$uch better than the top answer. This one doesn't crash if the texture is not squared.
Answer by Sykoh · Sep 19, 2015 at 03:27 AM
Late reply to this but this is what I use.
public Texture2D image;
Color32[] pixels = image.GetPixels32();
pixels = RotateMatrix(pixels, image.width);
image.SetPixels32(pixels);
static Color32[] RotateMatrix(Color32[] matrix, int n) {
Color32[] ret = new Color32[n * n];
for (int i = 0; i < n; ++i) {
for (int j = 0; j < n; ++j) {
ret[i*n + j] = matrix[(n - j - 1) * n + i];
}
}
return ret;
}
Lol, it's what he named his function. You can call it whatever you want.
don't forget to make sure your texture has mip-maps turned off, otherwise it will turn your texture into a jumbled mess of pixels.
Answer by JonnyHilly · Mar 23, 2016 at 08:05 PM
Multiple possible ways to do this.. if texture is on a quad or sprite, just rotate the game-object instead. Use a camera Just to draw that object on a layer.. and rotate the camera instead.
If you need to rotate the pixels in the texture itself sykoh has good method above... Here is a slightly better version, that works with non-square textures also. But make sure your source texture does not have mip-maps enabled or they won't work.
public Texture2D rotateTexture(Texture2D image )
{
Texture2D target = new Texture2D(image.height, image.width, image.format, false); //flip image width<>height, as we rotated the image, it might be a rect. not a square image
Color32[] pixels = image.GetPixels32(0);
pixels = rotateTextureGrid(pixels, image.width, image.height);
target.SetPixels32(pixels);
target.Apply();
//flip image width<>height, as we rotated the image, it might be a rect. not a square image
return target;
}
public Color32[] rotateTextureGrid(Color32[] tex, int wid, int hi)
{
Color32[] ret = new Color32[wid * hi]; //reminder we are flipping these in the target
for (int y = 0; y < hi; y++)
{
for (int x = 0; x < wid; x++)
{
ret[(hi-1)-y + x * hi] = tex[x + y * wid]; //juggle the pixels around
}
}
return ret;
}
Thanks - that was very helpful!
This code rotates CCW, if you need to rotate CW ins$$anonymous$$d change line 25 to:
ret[y + (wid-1-x) * hi] = tex[x + y * wid]; //juggle the pixels around
Answer by videep · Apr 21, 2015 at 07:21 PM
@Illustir Can you please try whats written in this blog: https://themaxscriptguy.wordpress.com/2014/11/20/rotating-cubemap-in-unity/
That looks slightly complicated (touching code at that many locations is not good from a maintainability point of view) but I'll see if I'll get around to it tomorrow.
That's for a cube$$anonymous$$ap, which the OP isn't using, and is a custom shader, which the OP said they were trying to avoid. And it's in DoItYourself format ins$$anonymous$$d of showing a solution.
The useful part there is setting a shader rotation matrix, but there have to be simpler guides than that (w/o the cube$$anonymous$$ap.)
I had actually found this post while Googling and upon reading it it at least sort of explains what's going on in the shader which is helpful. I have not been able to find a tutorial to quickly get into shaders either (because I was considering whether it might fix my problem).
the shader is actually the way to rotate a map. you can change the cubemap to be anyother texture. The graphics card understands shaders. now unity hasn't made any shader in a way which can rotate. I can send a sample scene so that you can use the scripts/shaders needed. Let me know if you need a sample scene.
Cheers!
I would really love to see a sample for how to set that up. That would be great!
Answer by Owen-Reynolds · Apr 21, 2015 at 06:47 PM
There are technical fixes, but main fix is usually person to person communication. If one texture is rotated 90 degrees, maybe they all are, but probably another is perfect, another is 90 the other way ... . Best way is to TELL the artist this are "WWW-textures," and WWW-textures are oriented like X. Go into photoshop and flip them all the right way (takes a few seconds.)
If might also mean YOU are inconsistent. Maybe some meshes are rotated different ways.
For rotating in Unity:
o Rotate the mesh they are on. Easiest thing to do.
o Material scaling can flip it L/R or UD (by 180, or backwards,) but can't spin it by 90.
o Custom shaders are when you want it to fully rotate to any angle, and can't just rotate the mesh.
o Can redo the texture in code, to make a "rotated by 90" version, using SetPixels, Apply and a double-loop. Can rotate by anything, but 90 is easy, no-trig lossless pixel copying.
Person to person communication does not work here since the image is written to file by a poorly written plugin on a mobile phone. If I could touch any of this stuff in the Unity player I would have fixed this long ago.
It would be great if the asset was written better but it isn't and this needs to work one way or another.
Rotating the mesh is not really an option because that messes up the autolayout. This can probably be fixed but a second problem did not seem like a good idea to solve an initial problem.
I've cobbled something together based on various solutions but you're right that that may be the easiest solution. Still odd that there isn't a built-in straight-forward way.
Your answer
Follow this Question
Related Questions
What's the most effecient way to rotate a texture? 1 Answer
Texture rotation by renderer.material.SetMatrix 1 Answer
Why is my texture like this? 1 Answer
Encoding metadata in a texture 1 Answer