• 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
11
Question by Maisey · Aug 18, 2014 at 07:39 PM · cameraiosresolutionwebcamtextureratio

WebCamTexture, get correct resolution and RATIO.

After searching for a while, I've seen different solutions to get this right. Most of them suggesting first instantiating the WebCamTexture to a high resoulution. This does not work at all.

How do you, correctly, get the actual camera aspect ratio and the actual pixels??

Comment
Add comment · Show 1
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 Fattie · Jul 19, 2016 at 06:05 AM 0
Share

Note

at this point 2016 the only real solution is to use "NatCam" on the asset store.

you can avoid 4-10 weeks of work, it is the only realistic solution until Unity fix their shit

5 Replies

· Add your reply
  • Sort: 
avatar image
9
Best Answer

Answer by Fattie · Feb 29, 2016 at 12:16 AM

note

Thes days just use

NatCam

on the asset store. It saves 4-10 man-weeks of work.


Jonny Roy's answer is partially correct. This is a huge know bug / disaster in Unity. For years they have not fixed, mentioned or addressed the issue.

(1) The solution is this: the reported size only becomes correct after some time (1/2 sec or so).

(2) Before that the width is reported as a small number under 100. it sounds bizarre but you have to watch each frame for a number over 100. It works 100% reliably.

Note these days you would never use a WebCamTexture on anything but UI, here is a post to save some typing: http://answers.unity3d.com/questions/909967/getting-a-web-cam-to-play-on-ui-texture-image.html

And nowm how to spin the image!

Here is the state of the art, 2016, for fixing the ratio, spin, and mirror of WebCamTexture. Works on both Android and iOS:

 private void Update()
   {
   if ( wct.width < 100 )
     {
     Debug.Log("Still waiting another frame for correct info...");
     return;
     }
   
   // change as user rotates iPhone or Android:
   
   int cwNeeded = wct.videoRotationAngle;
   // Unity helpfully returns the _clockwise_ twist needed
   // guess nobody at Unity noticed their product works in counterclockwise:
   int ccwNeeded = -cwNeeded;
   
   // IF the image needs to be mirrored, it seems that it
   // ALSO needs to be spun. Strange: but true.
   if ( wct.videoVerticallyMirrored ) ccwNeeded += 180;
   
   // you'll be using a UI RawImage, so simply spin the RectTransform
   rawImageRT.localEulerAngles = new Vector3(0f,0f,ccwNeeded);
   
   float videoRatio = (float)wct.width/(float)wct.height;
   
   // you'll be using an AspectRatioFitter on the Image, so simply set it
   rawImageARF.aspectRatio = videoRatio;
   
   // alert, the ONLY way to mirror a RAW image, is, the uvRect.
   // changing the scale is completely broken.
   if ( wct.videoVerticallyMirrored )
     rawImage.uvRect = new Rect(1,0,-1,1);  // means flip on vertical axis
   else
     rawImage.uvRect = new Rect(0,0,1,1);  // means no flip
   
   // devText.text =
   //  videoRotationAngle+"/"+ratio+"/"+wct.videoVerticallyMirrored;
   }


Hope it saves someone a LOT of time.

However see George's critical notes in the other answer!!!!!!!

Comment
Add comment · Show 7 · 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 georgehbr · Mar 14, 2016 at 03:01 PM 1
Share

Thanks for this answer. I have a question about:

 if ( wct.videoVertically$$anonymous$$irrored )
      rawImage.uvRect = new Rect(1,0,-1,1);  // means flip on vertical axis

Why Rect(1,0,-1,1), i.e. horizontal flip and not Rect(0, 1, 1, -1), i.e. vertical flip?

Shouldn't a vertical flip be required for a "videoVertically$$anonymous$$irrored" WebCamTexture?

Also, I can't seem to be able to mirror the RawImage for front-facing cameras without making it also flip vertically for some reason...

avatar image Fattie · Mar 14, 2016 at 06:11 PM 0
Share

Hi George - I m absolutely not sure, and you may be perfectly correct about what Unity means ........... (also, their doco is often plain wrong, so I don't know) ...

A great point. Let me know what you find out from experimentation!!

Thanks for this.

avatar image Guy-Corbett · Apr 24, 2016 at 08:43 PM 0
Share

This has been really useful for me too, so thanks, however I have something to add. I was trying to get the camera image as large on the screen as possible. However it was appearing quite small. It turned out that in my case the code was having to rotate the image 90 degrees, which was confusing the aspect ratio fitter, so that the final image I saw on screen was only as tall as my screen was wide.

I'm solving this by checking whether the imaging is being rotated and scaling the object containing my raw image by the aspect ratio if it is.

In your code it would look something like this;

                 if (ccwNeeded != 0 &&
                     ccwNeeded % 90)
                 {
                     parentTransform.localScale = new Vector3(videoRatio, videoRatio, 1);
                 }
                 else
                 {
                     parentTransform.localScale = new Vector3(1, 1, 1);
                 }

I don't know if there's something I missed which caused this but it seems to fix it for so I though I would mention it in case anyone runs into the same issue.

avatar image sumit9236 · Jun 22, 2016 at 10:55 AM 0
Share

This is not a right way.

avatar image Olly · Jul 19, 2016 at 08:34 PM 0
Share

But it's also very expensive for us free users :-/

avatar image Lanre Olly · Jul 19, 2016 at 08:57 PM 0
Share

NatCam's developer here. I often wish that Unity would offer a way to pay for assets by implementing a plan. We would have jumped on creating a lite version of NatCam but the nature of the API does not permit it--it's either all or nothing. You could email me at olokobayusuf@gmail.com and we'll see if we can work something out for you. I honestly don't want the price to be a difficulty for developers, but I have specific instructions when it comes to pricing.

Show more comments
avatar image
23

Answer by georgehbr · Mar 15, 2016 at 01:31 PM

Update:

Here's the full script I'm using for displaying the device camera feed on a UI image with correct orientation and ratio, front and back cameras, and mirroring the front camera to make it look more natural, along with a screenshot of my hierarchy and RawImage game object. It's based on this answer by @Fattie, this other answer by Max Bot, reading the Unity documentation on WebCamTexture and WebCamDevice, and trial and error on a Nexus 5 running Android 6 and an iPhone 5S running iOS 9.

Hierarchy:

alt text

DeviceCameraController.cs:

 using UnityEngine;
 using UnityEngine.UI;
 using System.Linq;
 using System.Collections;
 
 public class DeviceCameraController : MonoBehaviour
 {
     public RawImage image;
     public RectTransform imageParent;
     public AspectRatioFitter imageFitter;
 
     // Device cameras
     WebCamDevice frontCameraDevice;
     WebCamDevice backCameraDevice;
     WebCamDevice activeCameraDevice;
 
     WebCamTexture frontCameraTexture;
     WebCamTexture backCameraTexture;
     WebCamTexture activeCameraTexture;
 
     // Image rotation
     Vector3 rotationVector = new Vector3(0f, 0f, 0f);
 
     // Image uvRect
     Rect defaultRect = new Rect(0f, 0f, 1f, 1f);
     Rect fixedRect = new Rect(0f, 1f, 1f, -1f);
 
     // Image Parent's scale
     Vector3 defaultScale = new Vector3(1f, 1f, 1f);
     Vector3 fixedScale = new Vector3(-1f, 1f, 1f);
 
 
     void Start()
     {
         // Check for device cameras
         if (WebCamTexture.devices.Length == 0)
         {
             Debug.Log("No devices cameras found");
             return;
         }
 
         // Get the device's cameras and create WebCamTextures with them
         frontCameraDevice = WebCamTexture.devices.Last();
         backCameraDevice = WebCamTexture.devices.First();
 
         frontCameraTexture = new WebCamTexture(frontCameraDevice.name);
         backCameraTexture = new WebCamTexture(backCameraDevice.name);
 
         // Set camera filter modes for a smoother looking image
         frontCameraTexture.filterMode = FilterMode.Trilinear;
         backCameraTexture.filterMode = FilterMode.Trilinear;
 
         // Set the camera to use by default
         SetActiveCamera(frontCameraTexture);
     }
 
     // Set the device camera to use and start it
     public void SetActiveCamera(WebCamTexture cameraToUse)
     {
         if (activeCameraTexture != null)
         {
             activeCameraTexture.Stop();
         }
             
         activeCameraTexture = cameraToUse;
         activeCameraDevice = WebCamTexture.devices.FirstOrDefault(device => 
             device.name == cameraToUse.deviceName);
 
         image.texture = activeCameraTexture;
         image.material.mainTexture = activeCameraTexture;
 
         activeCameraTexture.Play();
     }
 
     // Switch between the device's front and back camera
     public void SwitchCamera()
     {
         SetActiveCamera(activeCameraTexture.Equals(frontCameraTexture) ? 
             backCameraTexture : frontCameraTexture);
     }
         
     // Make adjustments to image every frame to be safe, since Unity isn't 
     // guaranteed to report correct data as soon as device camera is started
     void Update()
     {
         // Skip making adjustment for incorrect camera data
         if (activeCameraTexture.width < 100)
         {
             Debug.Log("Still waiting another frame for correct info...");
             return;
         }
 
         // Rotate image to show correct orientation 
         rotationVector.z = -activeCameraTexture.videoRotationAngle;
         image.rectTransform.localEulerAngles = rotationVector;
 
         // Set AspectRatioFitter's ratio
         float videoRatio = 
             (float)activeCameraTexture.width / (float)activeCameraTexture.height;
         imageFitter.aspectRatio = videoRatio;
 
         // Unflip if vertically flipped
         image.uvRect = 
             activeCameraTexture.videoVerticallyMirrored ? fixedRect : defaultRect;
 
         // Mirror front-facing camera's image horizontally to look more natural
         imageParent.localScale = 
             activeCameraDevice.isFrontFacing ? fixedScale : defaultScale;
     }
 }


Comments on Fattie's Answer:

So I'm pretty sure at this point that "verticallyMirrored" means that a rotation about the horizontal axis is needed. So I've modified the code in Fattie's answer to:

    int ccwNeeded = -wct.videoRotationAngle;
    
    rawImageRT.localEulerAngles = new Vector3(0f,0f,ccwNeeded);
    
    float videoRatio = (float)wct.width/(float)wct.height;
    
    rawImageARF.aspectRatio = videoRatio;
    
    if ( wct.videoVerticallyMirrored )
      rawImage.uvRect = new Rect(0,1,1,-1);  // flip on HORIZONTAL axis
    else
      rawImage.uvRect = new Rect(0,0,1,1); // no flip


i.e. I removed "if ( wct.videoVerticallyMirrored ) ccwNeeded += 180;" and changed the flipped uvRect values. I'll post a new answer here or somewhere on this site with my full script once I iron it out which includes using both front and back cameras and mirroring the front camera's texture to make it more natural.


hierarchy.png (237.7 kB)
Comment
Add comment · Show 11 · 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 Fattie · Mar 15, 2016 at 01:34 PM 0
Share

I converted your comment to an answer since it is so important, good one

avatar image Fattie · Mar 15, 2016 at 01:34 PM 1
Share

I also sent 100 "reward points" ! :) Am waiting with bated breath to see your further info, be sure to post it here please!!!! Cheers...

avatar image drewwise · Jun 15, 2016 at 02:50 AM 0
Share

That's really helpful!

I don't suppose you could share what's in the aspect filter?

avatar image kuravista · Jul 19, 2016 at 04:52 AM 0
Share

Thank , that totaly worked. but i have litte problem about resolution . after i build in my phone 13 $$anonymous$$P camera the image saved in my phoe blurry :( .

How to get the best resolution and not blurry

alt text

myscreenshot-10-37-10-19-07-16.jpg (33.9 kB)
avatar image Fattie kuravista · Jul 19, 2016 at 06:03 AM 0
Share

really suggest you just get NatCam .... save you weeks of time!

suggest you email the NatCam dudes they are very helpful. Even if you are not a customer they will solve your problem. it is very "specialized" field, you have to work on it all day every day.

enjoy!

avatar image Olly · Jul 19, 2016 at 08:41 PM 0
Share

Bugs out and displays on the whole screen.

Show more comments
avatar image
1

Answer by Lanre · Mar 17, 2016 at 06:01 PM

Have you tried NatCam? It works wonders and has a lot more features.

Comment
Add comment · Show 4 · 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 Fattie · Mar 17, 2016 at 06:08 PM 0
Share

Fantastic, I'm glad you told us about it. I will test it.

I sent you 50 "reward points" for bringing this to our attention :)

I would like to see a video of that plugin working, that would be reassuring. Does it replace WebCamTexture?

avatar image Lanre · Mar 17, 2016 at 06:16 PM 0
Share

Hi Fattie. It does! I am the publisher and my email address is olokobayusuf@gmail.com. Sorry for the inconvenience.

avatar image Fattie Lanre · Mar 17, 2016 at 06:18 PM 0
Share

awesome...

avatar image Lanre · Mar 17, 2016 at 06:17 PM 0
Share

The email is in "Support Email" right next to "Publisher Website". Will be more clear when I upload package v1.1

avatar image
1

Answer by Zoophish · May 24, 2017 at 07:39 AM

Unity 5.6.1 Release Notes [Extract]:

  • Android: Fixed WebCamTexture crash with denied permissions. (877837)

  • Android: Webcam - Fixed the wrong orientation returned on first frames. (875247)

Hope this solves a small issue faced here.

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 highpockets · Nov 18, 2020 at 12:11 PM

Hey I was having good fun with this on iOS, but I resolved it in the end with something pretty short and sweet.


I still needed to wait for the WebCamTexture.width to be more than 100 before adding it to the raw image texture/material and then I used SetNativeSize() on the raw texture. Here is my code for initialization:

         private IEnumerator WaitForWebCamAndInitialize( WebCamTexture _webCamTexture ) 
         {
             while( _webCamTexture.width < 100 )
                 yield return null;
 
             _isWebCamSet = true;
             _rawCamImage.texture = _webCamTexture;
             _rawCamImage.material.mainTexture = _webCamTexture;
             _rawCamImage.SetNativeSize();
 
             StartCoroutine( FadeToCameraView() );
         }

FadeToCameraView() does as it suggests.


I also had to rotate the rect transform negative 90 on the z axis because the app runs in portrait mode only and the raw data from the iOS camera seems to be aligned with landscape mode. Now everything works like a charm on iOS, but testing on the iMac shows the image rotated by the negative 90 I gave it.


Hope that helps someone

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.

Welcome to Unity Answers

The best place to ask and answer questions about development with Unity.

To help users navigate the site we have posted a site navigation guide.

If you are a new user to Unity Answers, check out our FAQ for more information.

Make sure to check out our Knowledge Base for commonly asked Unity questions.

If you are a moderator, see our Moderator Guidelines page.

We are making improvements to UA, see the list of changes.



Follow this Question

Answers Answers and Comments

22 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 avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

WebCamTexture, correct resolution and RATIO.And FPS 1 Answer

,iOS WebCamera Texture GetPixels() call returns only black colours? 1 Answer

iOS WebCamTexture Blur Get/Set Pixels 0 Answers

Unwanted delay with WebCamTexture on Phone 0 Answers

newbe scaling maze sceen for different resolutions 0 Answers

  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges