Windows 8 - XAML/C# How to set aspect ratio of camera - windows-runtime

My Microsoft HD web-cam supports 16:9 aspect ratio. I can preview and capture in 16:9 aspect ratio from Microsoft LifeCam utility.
In my application, the preview only shows in 4:3 aspect ratio. Is there any way to set it to 16:9? I googled it, searched MSDN APIs but couldn't find a way to do it.
The code I have so far looks like this:
XAML
<CaptureElement x:Name="CameraCaptureElement" Stretch="Uniform" ></CaptureElement>
C# Code
private async void InitializeCamera()
{
MediaCapture mediaCaptureMgr = new Windows.Media.Capture.MediaCapture();
await mediaCaptureMgr.InitializeAsync();
CameraCaptureElement.Source = mediaCaptureMgr;
await mediaCaptureMgr.StartPreviewAsync();
}

I don't think there is an API for setting the aspect ratio using MediaCapture, so you may want to consider using CameraCaptureUI instead, if aspect ratio selection is important to you, though CameraCaptureUI will leave the choice of source aspect ratio in the hands of the user (you can, however, programmatically control the starting aspect ratio of the cropped image if the user chooses to crop the original capture).
Check out the following sample:
http://code.msdn.microsoft.com/windowsapps/CameraCaptureUI-Sample-845a53ac
It shows how to use the CameraCaptureUI object to set the aspect ratio for cropping, which is the best you can do programmatically, I believe. Here's the relevant code:
CameraCaptureUI dialog = new CameraCaptureUI();
Size aspectRatio = new Size(16, 9);
dialog.PhotoSettings.CroppedAspectRatio = aspectRatio;
You can also restrict the maximum resolution that the user can select, but not the capture aspect ratio.
When the CameraCaptureUI is invoked via CaptureFileAsync, the user has the option to adjust the aspect ratio via the Camera Options button, as shown below:
For more info on Windows Store app development, register for Generation App.

You could set a Clip on your CameraCaptureElement to clip the preview to desired aspect ratio. Then after you capture a photo - you would need to crop it.

Related

User defined resolution in AS3

For the last couple of days I've been wondering if it would be possible to let the user define the resolution to be used, when building for an AIR application.
Say if I have my SWF set up at a 1280x720 resolution by default, would it be possible to have, in the main menu, a set of resolutions, for instance 1366x768 or 1024x768, that the user can choose and then scale the window that contains the game to that size?
With AIR, you can manipulate a window's size from your code.
For the window of the current code's scope, you can do:
stage.nativeWindow.width = 1280;
stage.nativeWindow.height = 720;
OR, if you want to move the window to a particular spot and size:
stage.nativeWindow.bounds = new Rectangle(0,0,1280,720);
Or, you can use NativeApplication.nativeApplication.activeWindow or one of the items (windows) from NativeApplication.nativeApplication.openedWindows

Using sprite atlases in a multi resolution setup in Cocos2D-x

I've just been able to setup a Cocos2d-x for a multiresolution environment. Ie supporting all/most of the available iPhone screen sizes.
My next step is to scrap the individual files (bunch of pngs) and use sprite atlases (aka sprite sheets) instead.
How does this work in Cocos2D-x? Does anyone have a working sample setup?
Once again, Google and existing documentation (well, I don't think that exists) fail me.
For cocos2d-x v3.5...
The cocos2d-x test classes are always a great place to look to see how things can be done with cocos2d-x.
Check out the AppDelegate.cpp in:
Cocos2d-x/cocos2d-x-3.5/tests/cpp-tests/Classes/AppDelegate.cpp.
In that class the window size is tested to see which set of assets should be loaded. That is part of the issue, deciding which assets to load.
For iOS retina, you can check the size of the screen and then set the content scale factor to either 1.0 for standard resolution or 2.0 for retina resolution.
Unfortunately, cocos2d-x doesn't seem to ever detect certain screen sizes and call Director::getInstanct()->setContentScaleFactor(2.0) for you, so I think we have to do this our self.
I have not tested the impact of setting contentScaleFactor on non-apple devices yet...
Check out the code below. Try running it in your AppDelegate::applicationDidFinishLaunching() method to get an idea of how cocos2d-x sees screen pixels and points; the result is not exactly what I expected. The output below is for an iPhone 5 device.
director->setContentScaleFactor(2);
Size winSizePoints = director->getWinSize();
Size winSizePixels = director->getWinSizeInPixels();
Size visibleSize = director->getVisibleSize();
CCLOG("Content scale factor set to 2.0.");
CCLOG("winSizePoints:%.2f,%.2f", winSizePoints.width, winSizePoints.height);
CCLOG("winSizePixels:%.2f,%.2f", winSizePixels.width, winSizePixels.height);
CCLOG("visibleSize:%.2f,%.2f", visibleSize.width, visibleSize.height);
director->setContentScaleFactor(1);
winSizePoints = director->getWinSize();
winSizePixels = director->getWinSizeInPixels();
visibleSize = director->getVisibleSize();
CCLOG("Content scale factor set to 1.0.");
CCLOG("winSizePoints:%.2f,%.2f", winSizePoints.width, winSizePoints.height);
CCLOG("winSizePixels:%.2f,%.2f", winSizePixels.width, winSizePixels.height);
CCLOG("visibleSize:%.2f,%.2f", visibleSize.width, visibleSize.height);
Output of above code:
Content scale factor set to 2.0.
winSizePoints:1136.00,640.00
winSizePixels:2272.00,1280.00
visibleSize:1136.00,640.00
Content scale factor set to 1.0.
winSizePoints:1136.00,640.00
winSizePixels:1136.00,640.00
visibleSize:1136.00,640.00
So it seems we have to check the the screen size and then choose assets.
One option is to then use code like this to decide which assets to load based on if the screen is retina or not. You could use a similar approach to also loading different size background images to deal with different aspect ratios (more aspect ratios below).
float scaleFactor = CCDirector::getInstance()->getContentScaleFactor();
if (scaleFactor > 1.99)
{
SpriteFrameCache::getInstance()->addSpriteFramesWithFile("spriteSheet-hd.plist", "spriteSheet-hd.png");
}
else
{
SpriteFrameCache::getInstance()->addSpriteFramesWithFile("spriteSheet.png", "spriteSheet.plist");
}
For sprite sheets, I highly recommend Texture Packer. Awesome tool that can create SD and HD sheets and .plist files for you with the press of one button.
If you publish to multiple platforms, you will also want to use the macros to detect the device type and use that information in deciding which assets to load.
e.g.
if (CC_TARGET_PLATFORM == CC_PLATFORM_WIN32)
elif CC_TARGET_PLATFORM == CC_PLATFORM_WP8
elif CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID
elif CC_TARGET_PLATFORM == CC_PLATFORM_IOS
elif CC_TARGET_PLATFORM == CC_PLATFORM_MAC)
endif
Another thing to consider is that on low power CPU and RAM devices, loading large assets might make your frames per second (FPS) go to crap. Or worse, the device might not be able to load the asset or could crash the game. So be sure to test/profile on least common denominator devices that you plan to support.
Aspect Ration is another important issue (landscape width:height).
iPad aspect ratio is 4:3
iPhone 4 is 3:2
iPhone 5 & 6 are 16:9
Android throws in a bunch more width:height ratios.
WP8.1 is 15:9... not sure if others.
The point is that you probably don't want to stretch your backgrounds to get them to fill the screen, or have black bars on the edges where assets are not tall or wide enough.
To deal with this I create background assets that are wider than they need to be going off the right side of the screen. That content looks good but is not vital to convey the meaning of the background. That extra content can be clipped on devices that have narrower aspect ratios, i.e. ipad, and is visible on wider aspect ratio devices, i.e. iPhone 6.
The background images are then scaled up/down to match the screenSize height and retain their aspect ratio.

Set ApplicationDPI in AS3 Mobile application

I developing an application in Flash Builder with AS3 only (no flex stuff). In flex it is possible to set the application's dpi by the following code:
<s:ViewNavigatorApplication xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark" applicationDPI="320">
But I using only AS3. I have read that it is not possible to change the application's DPI in run-time (with AS3), but how can I set this in project settings, compiler settings or is there another way to do it?
Also, what is the default application's DPI setting?
Ask it here because can't find it on the net (only flex based solutions).
The DPI on mobile is set by the hardware, it is entirely dependent on the phone and screen. When you set the applicationDPI in a Flex mobile you're telling Flex to automatically scale your assets.
Automatic scaling. Developers can choose to specify a target DPI for their application by setting the applicationDPI property on the application. When this is explicitly set, developers should set up their skins and layout as if they were running on a device of the given DPI. At runtime, if the device has a different DPI from the specified target DPI, Flex will automatically scale the entire application to preserve the approximate physical size of the application and its controls. For example, if an application is targeted at 160 DPI, it will automatically scale by 1.5x on a 240 DPI device. If you choose not to use this feature, you'll need to make sure your custom skins and view layouts adapt properly to different pixel densities at runtime.
Source
In an AS3 mobile project you're going to need to handle this yourself.
You can get the current DPI using Capabilities.screenDPI but I think what you may be after is a ratio to scale your assets by. One way to do this would be to start with the original game width.
private static const WIDTH:Number = 1024;
You can then get a ratio using
var ratio:Number = stage.fullScreenWidth / WIDTH;
And apply this to your assets
myBitmap.scaleX = myBitmap.scaleY = ratio;
Now this isn't going to take the rotation of the device into account, so fullScreenWidth/Height may be flipped. To check for that you're going to need to do something like this
if (stage.fullScreenWidth > stage.fullScreenHeight){
//portrait
} else {
//landscape
}
Hopefully this helps

AS3 Camera input gets distorted when exported to AIR

I've built an AIR application with flash/as3 that has a webcam display on the stage. While building the app, and in all my tests everything looks and works just dandy, but when I publish for AIR the image gets stretched. The bounds of the image seem to stay the same, but the actual cam output is what's distorted. Has anyone come into this problem before?
I should add, this is a desktop app, which is permanently installed on one machine, so device compatibility should not be an issue.
this is the camera setup:
var cam:Camera = Camera.getCamera();
cam.setMode(280,380,20);
var video:Video = new Video(380,380);
this is where i first call the camera...
video.attachCamera(cam);
video.x = 355;
video.scaleX = -1;
video.y = -100;
addChildAt(video, 0);
the reason for the odd sizing, is that it sits behind a frame, that changes positions throughout the interactive.
Not necessarily the answer you are looking for, but you should keep this in mind:
You are asking the camera to capture at the resolution of 280 x 380, which is not a standard 4:3 aspect ratio.
When you call cam.setMode(280,380,20); the docs say that Flash will try to set the cameras resolution to your specifications, and if the camera does not support that resolution it will try to find one that matches. So you may or may not be getting this actual resolution.
setMode() has a fourth parameter, which can disable this functionality. Read the docs on that so you understand the implications :)
Then you display the video in a Video object that is 380x380. So I would expect the image to be stretched in the horizontal direction (b/c the original source is only 280).
It's not clear why this behaves differently: are you saying that running the debug version of the app works, but when you export the release build and run that it looks funky?
Finally, what is scaleX = -1 doing? I recall this as some sort of nifty trick I used in the past... but it's purpose here is escaping me :)
Yep, source code would be cool. Btw, i suggest you, as soon as you get the video streaming running, to set by hand the video.width and video.height property.
This will force the cam to display at the correct size.

flex is not able to find the Screen class [duplicate]

Can I get the obtain the size of the browser window in AS3?
The best method I've found is to get the size with Javascript and send it to Flash as a FlashVar. One limitation of this method is that it doesn't give the current size if the window is resized.
Is there a pure Flash way to do this?
If you embedd your swf with height: 100%; width:100% you could use stage.stageWidth and stage.stageHeight. If this is not the case you could implement a communication with JavaScript by using ExternalInterface.
It depends if you are trying to set your swf to fullscreen, or simply obtain window dimensions for some other purpose.
If you are doing fullscreen, you need to set your stageScaleMode to NO_SCALE, and embed your flash object into a div that has its height and width parameters set to 100%. To deal with resizing, your flash project needs a resize event listener (applied to the stage), and all display objects need to respond to that resize listener. Once your swf is resizing properly, you can, as already noted, use stage.stageHeight / stageWidth to retrieve exact dimensions internally.
If, on the other hand, you just want to obtain the dimesions of the window, you will need to use ExternalInterface to make a javascript call. jQuery has some nice tools for quickly obtaining screen dimentions. Then its just a matter of sending that data back into flash. Remember that javascript has a resize event, as well, and that you can use it to force state changes in flash.
You're correct in the initial piece of the sequence - sending flashvars in on load, but to respond to screen size changes, you will need to apply one of these techniques.
Good luck