I want to make a Xamarin.iOS app where I can capture pictures like the camera... My app supports only portrait.
I want to turn the captured picture to portrait if the camera was landscape when i capture the picture.
Does someone know how I can do this?
Code
public async void CapturePhoto()
{
var videoConnection = stillImageOutput.ConnectionFromMediaType(AVMediaType.Video);
var sampleBuffer = await stillImageOutput.CaptureStillImageTaskAsync(videoConnection);
var jpegImageAsBytes = AVCaptureStillImageOutput.JpegStillToNSData(sampleBuffer).ToArray();
string base64StringImage = Convert.ToBase64String(jpegImageAsBytes);
FaceRecognition faceRecognition = new FaceRecognition();
int result = faceRecognition.SendPhoto(base64StringImage);
}
Try this :
var currentOrientation = UIApplication.SharedApplication.StatusBarOrientation;
if (currentOrientation == UIInterfaceOrientation.Portrait)
{
videoConnection.VideoOrientation = AVCaptureVideoOrientation.Portrait;
}
else if (currentOrientation == UIInterfaceOrientation.LandscapeRight)
{
videoConnection.VideoOrientation = AVCaptureVideoOrientation.LandscapeRight;
}
//xxx
Update:
If the app only supports an orientation or you lock the screen , there is another old way to detect device orientation. Core Motion
public void LockOrientation()
{
CMMotionManager CMManager = new CMMotionManager();
CMManager.DeviceMotionUpdateInterval = 0.2f;
CMManager.StartDeviceMotionUpdates(NSOperationQueue.MainQueue, (motion, error) => {
if (Math.Abs(motion.Gravity.X) > Math.Abs(motion.Gravity.Y))
{
Console.WriteLine("Lan");
if (motion.Gravity.X > 0)
{
UIDevice.CurrentDevice.SetValueForKey(new NSNumber((int)UIInterfaceOrientation.LandscapeLeft), new NSString("orientation"));
Console.WriteLine("Left");
}
else
{
UIDevice.CurrentDevice.SetValueForKey(new NSNumber((int)UIInterfaceOrientation.LandscapeRight), new NSString("orientation"));
Console.WriteLine("Right");
}
}
else
{
if (motion.Gravity.Y >= 0)
{
Console.WriteLine("Down");
}
else
{
Console.WriteLine("UP");
}
}
CMManager.StopDeviceMotionUpdates();
});
}
Refer to here
Related
Anybody knows how to turn On/Off android flashlight using C# only in Unity?
I don't like plugins, and I don't want to make one of my own. Is there a why to make my device switch the flashlight On or Off using pure C#?
I tried to add this script to the main camera, but it just didn't do the trick :(
private bool Active;
private AndroidJavaObject camera1;
void FL_Start()
{
AndroidJavaClass cameraClass = new AndroidJavaClass("android.hardware.Camera");
WebCamDevice[] devices = WebCamTexture.devices;
int camID = 0;
camera1 = cameraClass.CallStatic<AndroidJavaObject>("open", camID);
if (camera1 != null)
{
AndroidJavaObject cameraParameters = camera1.Call<AndroidJavaObject>("getParameters");
cameraParameters.Call("setFlashMode", "torch");
camera1.Call("setParameters", cameraParameters);
Active = true;
}
else
{
Debug.LogError("[CameraParametersAndroid] Camera not available");
}
}
void OnDestroy()
{
FL_Stop();
}
void FL_Stop()
{
if (camera1 != null)
{
camera1.Call("stopPreview");
camera1.Call("release");
Active = false;
}
else
{
Debug.LogError("[CameraParametersAndroid] Camera not available");
}
}
void OnGUI()
{
GUILayout.BeginArea(new Rect(Screen.width * 0.1f, Screen.height * 0.1f, Screen.width * 0.3f, Screen.height * 0.1f));
if (!Active)
{
if (GUILayout.Button("ENABLE FLASHLIGHT"))
FL_Start();
}
else
{
if (GUILayout.Button("DISABLE FLASHLIGHT"))
FL_Stop();
}
GUILayout.EndArea();
}
Newer Samsung phones are very picky about code.
You need to use camera1.Call("startPreview");
as shown below;
if (camera1 != null)
{
AndroidJavaObject cameraParameters = camera1.Call<AndroidJavaObject>("getParameters");
cameraParameters.Call("setFlashMode", "torch");
camera1.Call("setParameters", cameraParameters);
///FIX/////
camera1.Call("startPreview");
Active = true;
}
You could have a look at the Android plugin source for Camera Capture Kit (https://www.assetstore.unity3d.com/en/#!/content/56673) - I know you said you don't like plugins however with this one the source is availble and lets you see what goes on for you to tweak. With regards to your problem, Not all phones have the Torch functionality so that might be what you should check for for that ? Maybe you sohuld use the referance that unity itself is using ?
AndroidJavaObject camera=null;
AndroidJavaObject cameraParameters=null;
void ToggleAndroidFlashlight()
{
if (camera == null)
{
AndroidJavaClass cameraClass = new AndroidJavaClass("android.hardware.Camera");
camera = cameraClass.CallStatic<AndroidJavaObject>("open", 0);
if (camera != null)
{
cameraParameters = camera.Call<AndroidJavaObject>("getParameters");
cameraParameters.Call("setFlashMode","torch");
camera.Call("setParameters",cameraParameters);
}
}
else
{
cameraParameters = camera.Call<AndroidJavaObject>("getParameters");
string flashmode = cameraParameters.Call<string>("getFlashMode");
if(flashmode!="torch")
cameraParameters.Call("setFlashMode","torch");
else
cameraParameters.Call("setFlashMode","off");
camera.Call("setParameters",cameraParameters);
}
}
void ReleaseAndroidJavaObjects()
{
if (camera != null)
{
camera.Call("release");
camera = null;
}
}
The swipe gestures Left,Right, Up and Down are not optimized. If a task has to be performed with an upward swipe, it would get confused with a left swipe and still perform it.Please suggest me the parameters to be optimized for differentiating swipes.Or commands for perfect swipe recognition
Also it gets confused with a circle and a swipe.
I have added my code. In one single frame only one gesture should be detected.How do i limit this here.
public MainWindow()
{
InitializeComponent();
this.controller = new Controller();
this.listener = new LeapListener(this);
controller.AddListener(listener);
for (int iCount = 1; iCount < 23; iCount++)
{
images[iCount] = new BitmapImage();
images[iCount].BeginInit();
images[iCount].UriSource = new Uri("Images/" + iCount + ".png", UriKind.Relative);
images[iCount].EndInit();
}
image.Source = images[1];
}
delegate void LeapEventDelegate(string EventName);
public void LeapEventNotification(string EventName)
{
if (this.CheckAccess())
{
switch (EventName)
{
case "onInit":
break;
case "onConnect":
this.connectHandler();
break;
case "onFrame":
this.checkGestures(this.controller.Frame());
break;
}
}
else
{
Dispatcher.Invoke(new LeapEventDelegate(LeapEventNotification
), new object[] { EventName });
}
}
public void connectHandler()
{
controller.EnableGesture(Gesture.GestureType.TYPE_SWIPE);
this.controller.EnableGesture(Gesture.GestureType.TYPE_CIRCLE);
this.controller.EnableGesture(Gesture.GestureType.TYPE_KEY_TAP);
this.controller.EnableGesture(Gesture.GestureType.TYPE_SCREEN_TAP);
// controller.Config.SetFloat("Gesture.Swipe.Speed", 4000.0f);
controller.Config.SetFloat("Gesture.Swipe.MinVelocity", 750f);
controller.Config.SetFloat("Gesture.Swipe.MinLength", 200f);
controller.Config.SetFloat("Gesture.KeyTap.MinDownVelocity", 40.0f);
controller.Config.SetFloat("Gesture.KeyTap.HistorySeconds", .2f);
controller.Config.SetFloat("Gesture.KeyTap.MinDistance", 40.0f);
controller.Config.SetFloat("Gesture.Circle.MinRadius", 15.0f);
controller.Config.SetFloat("Gesture.Circle.MinArc", 15f);
controller.Config.SetFloat("InteractionBox.Width", 1600.0f);
controller.Config.SetFloat("InteractionBox.Height", 1600.0f);
controller.Config.Save();
}
public void checkGestures(Frame frame)
{
GestureList gestures = frame.Gestures();
foreach (Gesture gesture in gestures)
{
// For Image 1
if (image.Source.Equals(images[1]))
{
if (gesture.Type == Gesture.GestureType.TYPE_SWIPE)
{
SwipeGesture swipe = new SwipeGesture(gesture);
if (swipe.State == Gesture.GestureState.STATE_START && swipe.Direction.x > 0 && Math.Abs(swipe.Direction.y) < 5)
{
image.Source = images[2];
// Console.WriteLine("Second");
}
}
}
// For Image 2
else if (image.Source.Equals(images[2]))
{
if (gesture.Type == Gesture.GestureType.TYPE_SWIPE)
{
SwipeGesture swipe = new SwipeGesture(gesture);
if (swipe.State == Gesture.GestureState.STATE_START && swipe.Direction.y > 0)
{
image.Source = images[3];
}
else if (swipe.State == Gesture.GestureState.STATE_START && swipe.Direction.x > 0 && Math.Abs(swipe.Direction.y) < 5)
{
image.Source = images[7];
}
}
if (gesture.Type == Gesture.GestureType.TYPE_KEY_TAP)
{
KeyTapGesture TapGesture = new KeyTapGesture(gesture);
image.Source = images[1];
Console.WriteLine("Circle");
}
}
// For Image 3
else if (image.Source.Equals(images[3]))
{
if (gesture.Type == Gesture.GestureType.TYPE_SWIPE)
{
SwipeGesture swipe = new SwipeGesture(gesture);
if (swipe.State == Gesture.GestureState.STATE_START && swipe.Direction.y < 0)
{
image.Source = images[4];
}
else if (swipe.State == Gesture.GestureState.STATE_START && swipe.Direction.x < 0 && Math.Abs(swipe.Direction.y) < 5)
{
image.Source = images[16];
}
}
if (gesture.Type == Gesture.GestureType.TYPE_KEY_TAP)
{
KeyTapGesture TapGesture = new KeyTapGesture(gesture);
image.Source = images[1];
}
}
}//foreach
}
}
}
The out of the box Gestures were deprecated in 3.x (Orion) as they weren't to reliable.
The best thing to do is to understand the SDK and just create your own gestures, you can go beyond whats already Out of the box and more reliable.
Everything its about 3d positioning so pay attention to your Y,X,Z, use the debuger hands or create your own debug system to see how it behaves.
I'm trying to capture video on Windows Phone using the AudioVideoCaptureDevice but when I try to set the captureSource I get a error message saying " Operation not valid due to the state of the object". Can you tell me what to do right in the following code?
Code snippet:
// Viewfinder for capturing video.
private VideoBrush videoRecorderBrush;
// Source and device for capturing video.
private CaptureSource _cs;
private VideoCaptureDevice _cd;
private AudioVideoCaptureDevice vcDevice;
double w, h;
// File details for storing the recording.
private IsolatedStorageFileStream isoVideoFile;
private FileSink fileSink;
private string isoVideoFileName = "iClips_Video.mp4";
private StorageFile sfVideoFile;
// For managing button and application state.
private enum ButtonState { Initialized, Stopped, Ready, Recording, Playback, Paused, NoChange, CameraNotSupported };
private ButtonState currentAppState;
// Constructor
public MainPage()
{
try
{
InitializeComponent();
//setup recording
// Prepare ApplicationBar and buttons.
PhoneAppBar = (ApplicationBar)ApplicationBar;
PhoneAppBar.IsVisible = true;
StartRecording = ((ApplicationBarIconButton)ApplicationBar.Buttons[0]);
StopPlaybackRecording = ((ApplicationBarIconButton)ApplicationBar.Buttons[1]);
StartPlayback = ((ApplicationBarIconButton)ApplicationBar.Buttons[2]);
PausePlayback = ((ApplicationBarIconButton)ApplicationBar.Buttons[3]);
SetScreenResolution();
//initialize the camera task
cameraCaptureTask = new CameraCaptureTask();
cameraCaptureTask.Completed += new EventHandler<PhotoResult>(cameraCaptureTask_Completed);
if (isFilePresent("username") && isFilePresent("Password"))
{
if (isFilePresent("IsProfilePhotoOnServer"))
{
connectToSocket();
}
else
{
SignUpProfilePhoto();
}
}
else
{
SignIn();
}
}
catch (Exception ex)
{
this.Dispatcher.BeginInvoke(delegate()
{
MessageBox.Show("Constructor Error:\n"+ ex.Message);
});
}
}
protected override void OnNavigatedTo(NavigationEventArgs e)
{
base.OnNavigatedTo(e);
// Initialize the video recorder.
InitializeVideoRecorder();
//prepare shutter hot keys
CameraButtons.ShutterKeyHalfPressed += OnButtonHalfPress;
CameraButtons.ShutterKeyPressed += OnButtonFullPress;
CameraButtons.ShutterKeyReleased += OnButtonRelease;
}
protected override void OnNavigatedFrom(NavigationEventArgs e)
{
// Dispose of camera and media objects.
DisposeVideoPlayer();
DisposeVideoRecorder();
base.OnNavigatedFrom(e);
CameraButtons.ShutterKeyHalfPressed -= OnButtonHalfPress;
CameraButtons.ShutterKeyPressed -= OnButtonFullPress;
CameraButtons.ShutterKeyReleased -= OnButtonRelease;
}
protected override void OnOrientationChanged(OrientationChangedEventArgs e)
{
if (vcDevice != null)
{
if (e.Orientation == PageOrientation.LandscapeLeft)
{
txtDebug.Text = "LandscapeLeft";
videoRecorderBrush.RelativeTransform =
new CompositeTransform() { CenterX = 0.5, CenterY = 0.5, Rotation = 90 };
//rotate logo
if (logo != null)
{
RotateTransform rt = new RotateTransform();
rt.Angle = 90;
//default rotation is around top left corner of the control,
//but you sometimes want to rotate around the center of the control
//to do that, you need to set the RenderTransFormOrigin
//of the item you're going to rotate
//I did not test this approach, maybe You're going to need to use actual coordinates
//so this bit is for information purposes only
logo.RenderTransformOrigin = new Point(0.5, 0.5);
logo.RenderTransform = rt;
}
//rotate sign in link
if (MyGrid != null)
{
RotateTransform rt = new RotateTransform();
rt.Angle = 90;
//default rotation is around top left corner of the control,
//but you sometimes want to rotate around the center of the control
//to do that, you need to set the RenderTransFormOrigin
//of the item you're going to rotate
//I did not test this approach, maybe You're going to need to use actual coordinates
//so this bit is for information purposes only
MyGrid.RenderTransformOrigin = new Point(0.5, 0.5);
MyGrid.RenderTransform = rt;
}
}
if (e.Orientation == PageOrientation.PortraitUp)
{
txtDebug.Text = "PortraitUp";
videoRecorderBrush.RelativeTransform =
new CompositeTransform() { CenterX = 0.5, CenterY = 0.5, Rotation = 90 };
//rotate logo
if (logo != null)
{
RotateTransform rt = new RotateTransform();
rt.Angle = 0;
//default rotation is around top left corner of the control,
//but you sometimes want to rotate around the center of the control
//to do that, you need to set the RenderTransFormOrigin
//of the item you're going to rotate
//I did not test this approach, maybe You're going to need to use actual coordinates
//so this bit is for information purposes only
logo.RenderTransformOrigin = new Point(0.5, 0.5);
logo.RenderTransform = rt;
}
//rotate sign in link
if (MyGrid != null)
{
RotateTransform rt = new RotateTransform();
rt.Angle = 0;
//default rotation is around top left corner of the control,
//but you sometimes want to rotate around the center of the control
//to do that, you need to set the RenderTransFormOrigin
//of the item you're going to rotate
//I did not test this approach, maybe You're going to need to use actual coordinates
//so this bit is for information purposes only
MyGrid.RenderTransformOrigin = new Point(0.5, 0.5);
MyGrid.RenderTransform = rt;
}
}
if (e.Orientation == PageOrientation.LandscapeRight)
{
this.Dispatcher.BeginInvoke(delegate()
{
txtDebug.Text = "LandscapeRight";
// Rotate for LandscapeRight orientation.
//videoRecorderBrush.RelativeTransform =
//new CompositeTransform() { CenterX = 0.5, CenterY = 0.5, Rotation = 180 };
//rotate logo
if (logo != null)
{
RotateTransform rt = new RotateTransform();
rt.Angle = -90;
//default rotation is around top left corner of the control,
//but you sometimes want to rotate around the center of the control
//to do that, you need to set the RenderTransFormOrigin
//of the item you're going to rotate
//I did not test this approach, maybe You're going to need to use actual coordinates
//so this bit is for information purposes only
logo.RenderTransformOrigin = new Point(0.5, 0.5);
logo.RenderTransform = rt;
}
//rotate MyGrid
if (MyGrid != null)
{
RotateTransform rt = new RotateTransform();
rt.Angle = -90;
//default rotation is around top left corner of the control,
//but you sometimes want to rotate around the center of the control
//to do that, you need to set the RenderTransFormOrigin
//of the item you're going to rotate
//I did not test this approach, maybe You're going to need to use actual coordinates
//so this bit is for information purposes only
MyGrid.RenderTransformOrigin = new Point(0.5, 0.5);
MyGrid.RenderTransform = rt;
}
});
}
if (e.Orientation == PageOrientation.PortraitDown)
{
this.Dispatcher.BeginInvoke(delegate()
{
txtDebug.Text = "PortraitDown";
videoRecorderBrush.RelativeTransform =
new CompositeTransform() { CenterX = 0.5, CenterY = 0.5, Rotation = 270 };
});
}
}
}
// Hardware shutter button Hot-Actions.
private void OnButtonHalfPress(object sender, EventArgs e)
{
//toggle between video- play and pause
try
{
this.Dispatcher.BeginInvoke(delegate()
{
if (StartPlayback.IsEnabled)
{
PlayVideo();
}
if (PausePlayback.IsEnabled)
{
PauseVideo();
}
});
}
catch (Exception focusError)
{
// Cannot focus when a capture is in progress.
this.Dispatcher.BeginInvoke(delegate()
{
txtDebug.Text = focusError.Message;
});
}
}
private void OnButtonFullPress(object sender, EventArgs e)
{
// Focus when a capture is not in progress.
try
{
this.Dispatcher.BeginInvoke(delegate()
{
if (vcDevice != null)
{
//stopVideoPlayer if it's playing back
if (currentAppState == ButtonState.Playback || currentAppState == ButtonState.Paused)
{
DisposeVideoPlayer();
StartVideoPreview();
}
if (StartRecording.IsEnabled)
{
StartVideoRecording();
}
else
{
StopVideoRecording();
}
}
});
}
catch (Exception focusError)
{
// Cannot focus when a capture is in progress.
this.Dispatcher.BeginInvoke(delegate()
{
txtDebug.Text = focusError.Message;
});
}
}
private void OnButtonRelease(object sender, EventArgs e)
{
try
{
this.Dispatcher.BeginInvoke(delegate()
{
});
}
catch (Exception focusError)
{
// Cannot focus when a capture is in progress.
this.Dispatcher.BeginInvoke(delegate()
{
txtDebug.Text = focusError.Message;
});
}
}
// Update the buttons and text on the UI thread based on app state.
private void UpdateUI(ButtonState currentButtonState, string statusMessage)
{
// Run code on the UI thread.
Dispatcher.BeginInvoke(delegate
{
switch (currentButtonState)
{
// When the camera is not supported by the phone.
case ButtonState.CameraNotSupported:
StartRecording.IsEnabled = false;
StopPlaybackRecording.IsEnabled = false;
StartPlayback.IsEnabled = false;
PausePlayback.IsEnabled = false;
break;
// First launch of the application, so no video is available.
case ButtonState.Initialized:
StartRecording.IsEnabled = true;
StopPlaybackRecording.IsEnabled = false;
StartPlayback.IsEnabled = false;
PausePlayback.IsEnabled = false;
break;
// Ready to record, so video is available for viewing.
case ButtonState.Ready:
StartRecording.IsEnabled = true;
StopPlaybackRecording.IsEnabled = false;
StartPlayback.IsEnabled = true;
PausePlayback.IsEnabled = false;
break;
// Video recording is in progress.
case ButtonState.Recording:
StartRecording.IsEnabled = false;
StopPlaybackRecording.IsEnabled = true;
StartPlayback.IsEnabled = false;
PausePlayback.IsEnabled = false;
break;
// Video playback is in progress.
case ButtonState.Playback:
StartRecording.IsEnabled = false;
StopPlaybackRecording.IsEnabled = true;
StartPlayback.IsEnabled = false;
PausePlayback.IsEnabled = true;
break;
// Video playback has been paused.
case ButtonState.Paused:
StartRecording.IsEnabled = false;
StopPlaybackRecording.IsEnabled = true;
StartPlayback.IsEnabled = true;
PausePlayback.IsEnabled = false;
break;
default:
break;
}
// Display a message.
txtDebug.Text = statusMessage;
// Note the current application state.
currentAppState = currentButtonState;
});
}
public async void InitializeVideoRecorder()
{
try
{
if (_cs == null)
{
_cs = new CaptureSource();
fileSink = new FileSink();
_cd = CaptureDeviceConfiguration.GetDefaultVideoCaptureDevice();
CameraSensorLocation location = CameraSensorLocation.Back;
var captureResolutions =
AudioVideoCaptureDevice.GetAvailableCaptureResolutions(location);
vcDevice = await AudioVideoCaptureDevice.OpenAsync(location, captureResolutions[0]);
vcDevice.RecordingFailed += OnCaptureFailed;
vcDevice.VideoEncodingFormat = CameraCaptureVideoFormat.H264;
vcDevice.AudioEncodingFormat = CameraCaptureAudioFormat.Aac;
// Initialize the camera if it exists on the phone.
if (vcDevice != null)
{
//initialize fileSink
await InitializeFileSink();
// Create the VideoBrush for the viewfinder.
videoRecorderBrush = new VideoBrush();
videoRecorderBrush.SetSource(_cs);
// Display the viewfinder image on the rectangle.
viewfinderRectangle.Fill = videoRecorderBrush;
_cs.Start();
// Set the button state and the message.
UpdateUI(ButtonState.Initialized, "Tap record to start recording...");
}
else
{
// Disable buttons when the camera is not supported by the phone.
UpdateUI(ButtonState.CameraNotSupported, "A camera is not supported on this phone.");
}
}
}
catch(Exception ex)
{
MessageBox.Show("InitializeVideoRecorder Error:\n" + ex.Message);
}
}
public async Task InitializeFileSink()
{
StorageFolder isoStore = ApplicationData.Current.LocalFolder;
sfVideoFile = await isoStore.CreateFileAsync(
isoVideoFileName,
CreationCollisionOption.ReplaceExisting);
}
private void OnCaptureFailed(AudioVideoCaptureDevice sender, CaptureFailedEventArgs args)
{
MessageBox.Show(args.ToString());
}
private void OnCaptureSourceFailed(object sender, ExceptionRoutedEventArgs e)
{
MessageBox.Show(e.ErrorException.Message.ToString());
}
// Set the recording state: display the video on the viewfinder.
private void StartVideoPreview()
{
try
{
// Display the video on the viewfinder.
if (_cs.VideoCaptureDevice != null
&& _cs.State == CaptureState.Stopped)
{
// Add captureSource to videoBrush.
videoRecorderBrush.SetSource(_cs);
// Add videoBrush to the visual tree.
viewfinderRectangle.Fill = videoRecorderBrush;
_cs.Start();
// Set the button states and the message.
UpdateUI(ButtonState.Ready, "Ready to record.");
//Create optional Resolutions
}
}
// If preview fails, display an error.
catch (Exception e)
{
this.Dispatcher.BeginInvoke(delegate()
{
txtDebug.Text = "ERROR: " + e.Message.ToString();
});
}
}
// Set recording state: start recording.
private void StartVideoRecording()
{
try
{
// Connect fileSink to captureSource.
if (_cs.VideoCaptureDevice != null
&& _cs.State == CaptureState.Started)
{
_cs.Stop();
// Connect the input and output of fileSink.
fileSink.CaptureSource = _cs;
fileSink.IsolatedStorageFileName = isoVideoFileName;
}
// Begin recording.
if (_cs.VideoCaptureDevice != null
&& _cs.State == CaptureState.Stopped)
{
_cs.Start();
}
// Set the button states and the message.
UpdateUI(ButtonState.Recording, "Recording...");
StartTimer();
}
// If recording fails, display an error.
catch (Exception e)
{
this.Dispatcher.BeginInvoke(delegate()
{
txtDebug.Text = "ERROR: " + e.Message.ToString();
});
}
}
// Set the recording state: stop recording.
private void StopVideoRecording()
{
try
{
// Stop recording.
if (_cs.VideoCaptureDevice != null
&& _cs.State == CaptureState.Started)
{
_cs.Stop();
// Disconnect fileSink.
fileSink.CaptureSource = null;
fileSink.IsolatedStorageFileName = null;
// Set the button states and the message.
UpdateUI(ButtonState.Stopped, "Preparing viewfinder...");
StopTimer();
StartVideoPreview();
}
}
// If stop fails, display an error.
catch (Exception e)
{
this.Dispatcher.BeginInvoke(delegate()
{
txtDebug.Text = "ERROR: " + e.Message.ToString();
});
}
}
// Start the video recording.
private void StartRecording_Click(object sender, EventArgs e)
{
// Avoid duplicate taps.
StartRecording.IsEnabled = false;
StartVideoRecording();
}
private void DisposeVideoRecorder()
{
if (_cs != null)
{
// Stop captureSource if it is running.
if (_cs.VideoCaptureDevice != null
&& _cs.State == CaptureState.Started)
{
_cs.Stop();
}
// Remove the event handler for captureSource.
_cs.CaptureFailed -= OnCaptureFailed;
// Remove the video recording objects.
_cs = null;
vcDevice = null;
fileSink = null;
videoRecorderBrush = null;
}
}
private void OnCaptureFailed(object sender, ExceptionRoutedEventArgs e)
{
throw new NotImplementedException();
}
//STOP WATCH
private void StartTimer()
{
dispatcherTimer = new System.Windows.Threading.DispatcherTimer();
dispatcherTimer.Tick += new EventHandler(dispatcherTimer_Tick);
dispatcherTimer.Interval = new TimeSpan(0, 0, 1);
dispatcherTimer.Start();
startTime = System.DateTime.Now;
}
private void StopTimer()
{
dispatcherTimer.Stop();
}
private void dispatcherTimer_Tick(object sender, EventArgs e)
{
System.DateTime now = System.DateTime.Now;
txtRecTime.Text = now.Subtract(startTime).ToString();
}
the error is thrown inside initializeVideoRecorder().
Seems like you're code is too long to analyze as #john mentioned in the comment. But since you've suggested to post some helpful links here you go: Following these steps here in msdn, would work without any issues as I've tried it once.
If you really need a sample to kick off, there's one from msdn. Hope you'll maximize the utilities.
I figured out I have to pass the capture device to the videobrush to make it work. I'm still not sure where and if I should use CaptureSource when capturing with AudioVideoCaptureDevice. Anyway here is the solution code:
// Create the VideoBrush for the viewfinder.
videoRecorderBrush = new VideoBrush();
videoRecorderBrush.SetSource(vcDevice); //substitute vcDevice with captureSource - vcDevice is the reference of AudioVideoCaptureDevice
// Display the viewfinder image on the rectangle.
viewfinderRectangle.Fill = videoRecorderBrush;
Anybody knows how to turn On/Off android flashlight using C# only in Unity?
I don't like plugins, and I don't want to make one of my own. Is there a why to make my device switch the flashlight On or Off using pure C#?
I tried to add this script to the main camera, but it just didn't do the trick :(
private bool Active;
private AndroidJavaObject camera1;
void FL_Start()
{
AndroidJavaClass cameraClass = new AndroidJavaClass("android.hardware.Camera");
WebCamDevice[] devices = WebCamTexture.devices;
int camID = 0;
camera1 = cameraClass.CallStatic<AndroidJavaObject>("open", camID);
if (camera1 != null)
{
AndroidJavaObject cameraParameters = camera1.Call<AndroidJavaObject>("getParameters");
cameraParameters.Call("setFlashMode", "torch");
camera1.Call("setParameters", cameraParameters);
Active = true;
}
else
{
Debug.LogError("[CameraParametersAndroid] Camera not available");
}
}
void OnDestroy()
{
FL_Stop();
}
void FL_Stop()
{
if (camera1 != null)
{
camera1.Call("stopPreview");
camera1.Call("release");
Active = false;
}
else
{
Debug.LogError("[CameraParametersAndroid] Camera not available");
}
}
void OnGUI()
{
GUILayout.BeginArea(new Rect(Screen.width * 0.1f, Screen.height * 0.1f, Screen.width * 0.3f, Screen.height * 0.1f));
if (!Active)
{
if (GUILayout.Button("ENABLE FLASHLIGHT"))
FL_Start();
}
else
{
if (GUILayout.Button("DISABLE FLASHLIGHT"))
FL_Stop();
}
GUILayout.EndArea();
}
Newer Samsung phones are very picky about code.
You need to use camera1.Call("startPreview");
as shown below;
if (camera1 != null)
{
AndroidJavaObject cameraParameters = camera1.Call<AndroidJavaObject>("getParameters");
cameraParameters.Call("setFlashMode", "torch");
camera1.Call("setParameters", cameraParameters);
///FIX/////
camera1.Call("startPreview");
Active = true;
}
You could have a look at the Android plugin source for Camera Capture Kit (https://www.assetstore.unity3d.com/en/#!/content/56673) - I know you said you don't like plugins however with this one the source is availble and lets you see what goes on for you to tweak. With regards to your problem, Not all phones have the Torch functionality so that might be what you should check for for that ? Maybe you sohuld use the referance that unity itself is using ?
AndroidJavaObject camera=null;
AndroidJavaObject cameraParameters=null;
void ToggleAndroidFlashlight()
{
if (camera == null)
{
AndroidJavaClass cameraClass = new AndroidJavaClass("android.hardware.Camera");
camera = cameraClass.CallStatic<AndroidJavaObject>("open", 0);
if (camera != null)
{
cameraParameters = camera.Call<AndroidJavaObject>("getParameters");
cameraParameters.Call("setFlashMode","torch");
camera.Call("setParameters",cameraParameters);
}
}
else
{
cameraParameters = camera.Call<AndroidJavaObject>("getParameters");
string flashmode = cameraParameters.Call<string>("getFlashMode");
if(flashmode!="torch")
cameraParameters.Call("setFlashMode","torch");
else
cameraParameters.Call("setFlashMode","off");
camera.Call("setParameters",cameraParameters);
}
}
void ReleaseAndroidJavaObjects()
{
if (camera != null)
{
camera.Call("release");
camera = null;
}
}
I have been searching this issue in the web and have gone trough the documentation,however was not successful in finding a solution.
In my code I have created a MasterPane and utilize 13 GraphPanes,The problem is that if there are many graphs, the details become indistinguishable,hence I want to select(by clicking) a graph and enlarge it.Is there a specific function to realize this goal.If not,which steps are to be followed.
Thank you in advance
Even late,i hope it'll will help others.
The idea is to use the MasterPan PaneList collection.
I added a few buttons to the Window and do the control from them, another way
is to use FindPane method in the MasterPan class and do this by clicking.
I'll show both ways.
The code follows:
// graphSystem Class
MasterPane masterPane;
PaneList plist = new PaneList();
private void InitGraphs()
{
//Zedgraph control
var zgc = Apprefs.Zedgraph;
//MasterPan
masterPane = zgc.CreateMasterPan(Title, System.Drawing.Color.White);
// CreateMultiGraph is my own API to create Graph
zgc.CreateMultiGraph("Graph1", 1, "G1xtitle", "G1ytitle", false);
zgc.CreateMultiGraph("Graph2", 1, "G2xtitle", "G2ytitle", false);
zgc.CreateMultiGraph("Graph3", 1, "G3xtitle", "G3ytitle", false);
// save the Pans
foreach (GraphPane graph in masterPane.PaneList)
plist.Add(graph);
}
//---------------------------------------------------------------------------
public void Englare(RichButton button)
{
var graph = Apprefs.Zedgraph2.graph;
if (button.Name == "Show1")
{
ShowOneGraph(0);
}
else if (button.Name == "Show2")
{
ShowOneGraph(1);
}
else if (button.Name == "ShowAll")
{
ShowAllGraphs();
}
}
//---------------------------------------------------------------------------
private void ShowOneGraph(int Graphindex)
{
if (masterPane == null) return;
var graph = Apprefs.Zedgraph.graph;
if (Graphindex >= 0 && Graphindex < plist.Count)
{
masterPane.PaneList.Clear();
masterPane.PaneList.Add(plist[Graphindex]);
Layout();
}
}
//---------------------------------------------------------------------------
private void ShowAllGraphs()
{
if (masterPane == null) return;
var graph = Apprefs.Zedgraph.graph;
masterPane.PaneList.Clear();
foreach (GraphPane gr in plist)
masterPane.PaneList.Add(gr);
Layout();
}
//---------------------------------------------------------------------------
private void Layout()
{
var graph = Apprefs.Zedgraph2.graph;
using (Graphics g = graph.CreateGraphics())
{
masterPane.SetLayout(g, PaneLayout.SingleColumn);
graph.AxisChange();
graph.Refresh();
}
}
//---------------------------------------------------------------------------
way2: englare by click On Graph:
Add this method:
//---------------------------------------------------------------------------
GraphPane lastpan;
public void UCclicked(PointF mousePt)
{
GraphPane pan= masterPane.FindPane(mousePt);
if (pan != null)
{
if (pan == lastpan)
{
ShowAllGraphs();
lastpan = null;
}
else
{
ShowOneGraph(plist.IndexOf(pan));
lastpan = pan;
}
} }
Also register to the click event:
zgcGraph.MouseDoubleClick += new MouseEventHandler(zgcGraph_MouseDoubleClick);
And finally:
void zgcGrzgcGraph_MouseDoubleClick(object source, System.Windows.Forms.MouseEventArgs e)
{
if (Apprefs.graphSystem != null)
{
System.Drawing.PointF mousePt = new System.Drawing.PointF(e.X, e.Y);
Apprefs.graphSystem.UCclicked(mousePt);
}
}
thats it!