Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 13 Next capture
2021 2022 2023
1 capture
13 Jun 22 - 13 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
0
Question by np1970 · Feb 06, 2013 at 06:00 PM · mobileguitexturewebcamtextureportrait

Mobile Camera Feed in Portrait Mode

Hi everyone,

I am having a major issue with getting the camera feed of mobile devices to display correctly in portrait mode. I have managed to make it work (display in the correct orientation and position) in landscape mode by manipulating the GUI Texture of an object in the scene; performing a scale transformation on the vector and assigning a WebCamTexture to the GUI Texture of the object.

To make things easier to grasp, I would like to know a solution to this for Android, not iOS, as I do not have a developer account, however I understand that a solution would be similar on either platforms.

For reference, I have used this webpage as a rough guide: http://www.mat-d.com/site/unity-3d-webcamtexture-rotation-problem-with-android-how-to-rotate-the-camera-picture/

As a note, I know it may not seem logical to view the camera feed in portrait mode, but what I'm doing specifically requires the feature to be in portrait.

Thanks :)

Comment
Add comment
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

2 Replies

· Add your reply
  • Sort: 
avatar image
1

Answer by ninthjarl · Feb 16, 2013 at 03:37 PM

EDIT: This bit of code does the copying. using UnityEngine; using System.Collections; using System.IO;

 public class CameraBlitBehaviour : MonoBehaviour {
     
     WebCamTexture cam_texture;
     int requestedTextureWidth, requestedTextureHeight;
     bool appPaused = false;
     //GameObject camFeedPlane2;
     // Use this for initialization
     void Start () {
         requestedTextureWidth = 400;
         requestedTextureHeight = 400;
         WebCamDevice[] cam_devices = WebCamTexture.devices;
         
         if(Application.platform == RuntimePlatform.IPhonePlayer)
         {
             gameObject.transform.localScale = new Vector3(1f*gameObject.transform.localScale.x, 1f, -1f*gameObject.transform.localScale.z);
             cam_texture = new WebCamTexture(cam_devices[0].name, 640, 480, 30);
         }
         else
         {
             cam_texture = new WebCamTexture(cam_devices[0].name, 480, 640, 30);
         }
         //if(Application.HasUserAuthorization(UserAuthorization.WebCam))
         {
             if(cam_texture != null)
                 cam_texture.Play();
         }
 
         
     }
     void OnGUI()
     {
         if(GUI.Button(new Rect(110,10, 100, 60), new GUIContent("capture")))
         {
             cam_texture.Pause();
             BlitImage();
         }
         int wOffset = cam_texture.width - requestedTextureWidth;
         int hOffset = cam_texture.height - requestedTextureHeight;
         GUI.Label(new Rect(10,500,600,50), Application.persistentDataPath);
         GUI.Label(new Rect(10,550,600,50), "sourceTex"+ cam_texture.width+" "+ cam_texture.height);    
         GUI.Label(new Rect(10,600,600,50), ""+wOffset/2+" "+hOffset/2);
     }
     /// <summary>
     /// Blits the image. Well it's not exactly blitting as Unity doesnt provide a blitting interface. The Graphics.Blit blits the texture
     /// to a render texture which is of not much help. We copy the image to a temporary buffer and then copy it to a Texture2D.
     /// </summary>
     void BlitImage()
     {
         
         int width = cam_texture.width;
         int height = cam_texture.height;
         //assuming the source texture is always greater than the destination texture
         int wOffset = width - requestedTextureWidth;
         int hOffset = height - requestedTextureHeight;
         Debug.Log(width+" : "+height);
         Debug.Log(cam_texture.requestedWidth+" : "+cam_texture.requestedHeight);
     
         BlitImageAndroid(wOffset/2, hOffset/2);
         BlitImageIOS(wOffset/2,hOffset/2);
     }
     /// <summary>
     /// In this function we blit the texture using the calculated texture dimensions. 
     /// </summary>
     /// <param name='widthOffset'>
     /// Width offset.
     /// </param>
     /// <param name='heightOffset'>
     /// Height offset.
     /// </param>
     void BlitImageAndroid(int widthOffset, int heightOffset)
     {
         Debug.Log("starting blitting from"+widthOffset+" :"+(requestedTextureHeight + heightOffset));
         Texture2D bufferTexture = new Texture2D(requestedTextureWidth, requestedTextureHeight, TextureFormat.ARGB32, false);
         
         //This is the android version of blitting
         for(int x = (requestedTextureWidth + widthOffset), destY = 0; x > widthOffset; x--, destY++)
         {
             for(int y = heightOffset, destX=0; y < (requestedTextureHeight+ heightOffset); y++, destX++)
             {
                 bufferTexture.SetPixel(destX,destY, cam_texture.GetPixel(x,y));
             }
         }
         
         bufferTexture.Apply();
         
         byte[] pngData = bufferTexture.EncodeToPNG();
         if(File.Exists(Application.persistentDataPath+"/capturedPic.png"))
         {
             File.Delete(Application.persistentDataPath+"/capturedPic.png");
         }
         File.WriteAllBytes(Application.persistentDataPath+"/capturedPic.png",pngData);
         Debug.Log("pic saved to"+Application.persistentDataPath);
     }
     /// <summary>
     /// In this function we flip the pixels around and copy them as we are flipping the texture using localscale, 
     /// hence the destX start from requestedTextureHeight and copies until 0
     /// </summary>
     /// <param name='widthOffset'>
     /// Width offset.
     /// </param>
     /// <param name='heightOffset'>
     /// Height offset.
     /// </param>
     void BlitImageIOS(int widthOffset, int heightOffset)
     {
         Texture2D destTexture = new Texture2D(requestedTextureWidth, requestedTextureHeight, TextureFormat.ARGB32, false);
         for(int x = (requestedTextureWidth + widthOffset), destY = 0; x > widthOffset; x--, destY++)
         {
             for(int y = heightOffset, destX=requestedTextureHeight; y < (requestedTextureHeight+ heightOffset); y++, destX--)
             {
                 destTexture.SetPixel(destX,destY, cam_texture.GetPixel(x,y));
             }
         }
                 
         destTexture.Apply();
     
         byte[] pngData = destTexture.EncodeToPNG();
         if(File.Exists(Application.persistentDataPath+"/capturedPic2.png"))
         {
             File.Delete(Application.persistentDataPath+"/capturedPic2.png");
         }
         File.WriteAllBytes(Application.persistentDataPath+"/capturedPic2.png",pngData);
         Debug.Log("pic saved to"+Application.persistentDataPath);
 
     }
     /// <summary>
     /// Blits the image using the GetPixels function.
     /// </summary>
     /// <param name='widthOffset'>
     /// Width offset.
     /// </param>
     /// <param name='heightOffset'>
     /// Height offset.
     /// </param>
     void BlitImageNormal(int widthOffset, int heightOffset)
     {
         Texture2D destTexture = new Texture2D(requestedTextureWidth, requestedTextureHeight, TextureFormat.ARGB32, false);
 
         Color[] textureData = cam_texture.GetPixels(widthOffset, heightOffset,requestedTextureWidth,requestedTextureHeight);
         
         destTexture.SetPixels(textureData);
         destTexture.Apply();
     
         byte[] pngData = destTexture.EncodeToPNG();
         if(File.Exists(Application.persistentDataPath+"/capturedPic3.png"))
         {
             File.Delete(Application.persistentDataPath+"/capturedPic3.png");
         }
         File.WriteAllBytes(Application.persistentDataPath+"/capturedPic3.png",pngData);
         Debug.Log("pic saved to"+Application.persistentDataPath);
     }
     
     // Update is called once per frame
     void Update () {
         if(!appPaused)
         {
             if (cam_texture != null && cam_texture.didUpdateThisFrame)
             {
     
                 gameObject.renderer.material.mainTexture = cam_texture;
     
             }
         }
                 
     }
     public void StopCamera()
     {
         cam_texture.Stop();
     }
     void OnApplicationPause(bool pause)
     {
         if(pause)
         {
             appPaused = true;
             cam_texture.Stop();
         }
         else
         {
             appPaused = false;
             if(cam_texture != null)
                 cam_texture.Play();
             
         }
     }
 }
 
Comment
Add comment · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image
0

Answer by ninthjarl · Feb 16, 2013 at 03:37 PM

I am also facing the same problem. My app also needs the camera feed to be displayed in portrait mode. One work around I used was to use a plane that faced the camera with rotation set to (0,270,90). In iOS I would have to flip the plane by modifying the localscale. gameObject.transform.localScale = new Vector3(1f*gameObject.transform.localScale.x, 1f, -1f*gameObject.transform.localScale.z)

Then I am setting the WebCamTexture to the plane's material texture. I needed a 400x400 image out of the WebCamTexture with dimensions 640x480. The SetPixel and GetPixel start reading the image from bottom left corner of the texture. ![alt text][1] [1]: /storage/temp/7932-texturecopyexplanation.png


texturecopyexplanation.png (12.1 kB)
Comment
Add comment · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

10 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

Screenshot from camera 0 Answers

WebCam background optimisation 1 Answer

How to stop second finger from manipulating position of gui joystick 1 Answer

Android GUI.DrawTexture not working 0 Answers

Reduce Draw call for Multiple GUI Textures with same Texture 1 Answer


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges