How can I turn the iPhone's LED camera flash on/off programatically?
#import <AVFoundation/AVFoundation.h>
...
- (void) turnTorchOn: (bool) on {
// check if flashlight available
Class captureDeviceClass = NSClassFromString(#"AVCaptureDevice");
if (captureDeviceClass != nil) {
AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
if ([device hasTorch] && [device hasFlash]){
[device lockForConfiguration:nil];
if (on) {
[device setTorchMode:AVCaptureTorchModeOn];
[device setFlashMode:AVCaptureFlashModeOn];
//torchIsOn = YES; //define as a variable/property if you need to know status
} else {
[device setTorchMode:AVCaptureTorchModeOff];
[device setFlashMode:AVCaptureFlashModeOff];
//torchIsOn = NO;
}
[device unlockForConfiguration];
}
} }
I combined the timer with the above code.it worked for me...
- (void)viewDidLoad
{
[super viewDidLoad];
myTimer = [NSTimer scheduledTimerWithTimeInterval:0.5 target:self selector:#selector(toggleFlashlight) userInfo:nil repeats:YES];
// Do any additional setup after loading the view from its nib.
}
- (void) toggleFlashlight
{
// check if flashlight available
Class captureDeviceClass = NSClassFromString(#"AVCaptureDevice");
if (captureDeviceClass != nil) {
AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
if ([device hasTorch] && [device hasFlash]){
[device lockForConfiguration:nil];
if (device.torchMode == AVCaptureTorchModeOff)
{
[device setTorchMode:AVCaptureTorchModeOn];
[device setFlashMode:AVCaptureFlashModeOn];
//torchIsOn = YES;
}
else
{
[device setTorchMode:AVCaptureTorchModeOff];
[device setFlashMode:AVCaptureFlashModeOff];
// torchIsOn = NO;
}
[device unlockForConfiguration];
}
} }
Related
To turn on torch and flashlight I'm using this code:
if ([device hasTorch]) {
[device lockForConfiguration:nil];
[device setTorchMode: on ? AVCaptureTorchModeOn : AVCaptureTorchModeOff];
[device setFlashMode: on ? AVCaptureFlashModeOn : AVCaptureFlashModeOff];
[device setFocusMode:AVCaptureFocusModeAutoFocus];
[device unlockForConfiguration];
}
But if you compare it with the native camera app you will see that the native flashlight is more powerful when capturing photo
Is there a way to make it powerful when capturing a photo similar to native camera flash?
you can update your code with this code:
- (void)setTorchToLevel:(float)torchLevel
{
AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
if ([device hasTorch]) {
[device lockForConfiguration:nil];
if (torchLevel <= 0.0) {
[device setTorchMode:AVCaptureTorchModeOff];
}
else {
if (torchLevel >= 1.0)
torchLevel = AVCaptureMaxAvailableTorchLevel;
BOOL success = [device setTorchModeOnWithLevel:torchLevel error:nil];
}
[device unlockForConfiguration];
}
}
hope this will help you.
Try adding the following code.
[device setTorchModeOnWithLevel:AVCaptureMaxAvailableTorchLevel error:nil];
I'm using Apple's AVCam source code to create a custom camera, I'm trying to toggle flash on/off but its not working. Here is my code, not sure what's wrong. I'm new to AVCam.
- (void) toggleFlash:(id)sender {
dispatch_async([self sessionQueue], ^{
AVCaptureDevice *currentVideoDevice = [[self videoDeviceInput] device];
AVCaptureDevicePosition currentPosition = [currentVideoDevice position];
if(currentPosition == AVCaptureDevicePositionUnspecified || currentPosition == AVCaptureDevicePositionBack) {
if([currentVideoDevice hasFlash]) {
[currentVideoDevice lockForConfiguration:nil];
[currentVideoDevice setFlashMode:AVCaptureFlashModeOn];
[currentVideoDevice unlockForConfiguration];
}
}
});
}
Its go through each line in code, and not logs any errors from this but still no luck.
- (void) toggleFlash {
AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
if ([device hasTorch] && [device hasFlash]){
[device lockForConfiguration:nil];
[device setTorchMode:!device.torchActive];
[device setFlashMode:!device.torchActive];
[device unlockForConfiguration];
}
}
P.S. In my case, torch/flash is off initially.
used below code to disable torch was working fine in ios7 ,
but in ios8 torch gets on when dark
AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
if ([device hasTorch] || [device hasFlash]){
[device lockForConfiguration:nil];
[device setTorchMode:AVCaptureTorchModeOff];
[device setFlashMode:AVCaptureFlashModeOff];
[device unlockForConfiguration];
}
Try this code it works...
- (IBAction)flashOnClicked:(id)sender
{
AVCaptureDevice *flashLight = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
if ([flashLight isTorchAvailable] && [flashLight isTorchModeSupported:AVCaptureTorchModeOn])
{
BOOL success = [flashLight lockForConfiguration:nil];
if (success)
{
if ([flashLight isTorchActive])
{
//TURN ON
[flashLight setTorchMode:AVCaptureTorchModeOff];
}
else
{
//TURN OFF
[flashLight setTorchMode:AVCaptureTorchModeOn];
}
[flashLight unlockForConfiguration];
}
}
}
Update : I know how to turn on/off the camera flash. What I want to know is if the camera flash is already lit or not.
I would like to know if camera flash is lit or not on iPhone, but I haven't found any method in UIImagePickerController which allows me to do this. I know we can get the cameraFlashMode. But I want to know if the camera flash is already lit or not.
For example, if the mode is UIImagePickerControllerCameraFlashModeAuto, the camera flash could be lit or not before I take the control, and I want to know the state of camera flash before doing some operations.
Surprising this is really unanswered the first person that answered didn't even answer the question...
func torchButtonPressed() {
//
let device = AVCaptureDevice.defaultDeviceWithMediaType(AVMediaTypeVideo)
do {
try device.lockForConfiguration()
} catch {
return
}
if device.torchMode == AVCaptureTorchMode.Off {
do {
device.torchMode = AVCaptureTorchMode.On
try device.setTorchModeOnWithLevel(AVCaptureMaxAvailableTorchLevel)
} catch {
print("no torch")
return
}
} else {
device.torchMode = AVCaptureTorchMode.Off
}
device.unlockForConfiguration()
}
You can use following code to find that
#import <AVFoundation/AVFoundation.h>
- (void) turnTorchOn: (bool) on {
Class captureDeviceClass = NSClassFromString(#"AVCaptureDevice");
if (captureDeviceClass != nil) {
AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
if ([device hasTorch] && [device hasFlash]){
[device lockForConfiguration:nil];
if (on) {
NSLog(#"Torch is ON");
} else {
NSLog(#"Torch is OFF");
}
[device unlockForConfiguration];
}
}
}
Happy Coding...!!!
I went through the same issue as yours.
iOS supports two modes - Flash Light & Torch. The code below checks if each is available & then if turns them on or off depending on which one you call. Also it checks if the light is already on/off.
Flash On -
-(void)flashOn {
Class captureDeviceClass = NSClassFromString(#"AVCaptureDevice");
if (captureDeviceClass != nil) {
AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
[device lockForConfiguration:nil];
if ([device hasFlash]) {
if ([device flashMode] == AVCaptureFlashModeOff) {
[device setFlashMode:AVCaptureFlashModeOn];
}
}
if ([device hasTorch]) {
if ([device torchMode] == AVCaptureTorchModeOff) {
[device setTorchMode:AVCaptureTorchModeOn];
}
}
[device unlockForConfiguration];
}
}
Flash Off-
-(void)flashOff {
Class captureDeviceClass = NSClassFromString(#"AVCaptureDevice");
if (captureDeviceClass != nil) {
AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
[device lockForConfiguration:nil];
if ([device hasFlash]) {
if ([device flashMode] == AVCaptureFlashModeOn) {
[device setFlashMode:AVCaptureFlashModeOff];
}
}
if ([device hasTorch]) {
if ([device torchMode] == AVCaptureTorchModeOn) {
[device setTorchMode:AVCaptureTorchModeOff];
}
}
[device unlockForConfiguration];
}
}
I know that the only way to turn on the flash and keep it on on iPhone 4 is by turning the video camera on. I'm not too sure of the code though. Here is what I am trying:
-(IBAction)turnTorchOn {
AVCaptureSession *captureSession = [[AVCaptureSession alloc] init];
AVCaptureDevice *videoCaptureDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
NSError *error = nil;
AVCaptureDeviceInput *videoInput = [AVCaptureDeviceInput deviceInputWithDevice:videoCaptureDevice error:&error];
if (videoInput) {
[captureSession addInput:videoInput];
AVCaptureVideoDataOutput* videoOutput = [[AVCaptureVideoDataOutput alloc] init];
[videoOutput setSampleBufferDelegate:self queue:dispatch_get_current_queue()];
[captureSession addOutput:videoOutput];
[captureSession startRunning];
videoCaptureDevice.torchMode = AVCaptureTorchModeOn;
}
}
Does anybody know if this would work or am I missing anything? (I don't have an iPhone 4 yet to test on -just trying out some of the new API's).
Thanks
Here's a shorter version you can now use to turn the light on or off:
AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
if ([device hasTorch]) {
[device lockForConfiguration:nil];
[device setTorchMode:AVCaptureTorchModeOn]; // use AVCaptureTorchModeOff to turn off
[device unlockForConfiguration];
}
UPDATE: (March 2015)
With iOS 6.0 and later, you can control the brightness or level of the torch using the following method:
- (void)setTorchToLevel:(float)torchLevel
{
AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
if ([device hasTorch]) {
[device lockForConfiguration:nil];
if (torchLevel <= 0.0) {
[device setTorchMode:AVCaptureTorchModeOff];
}
else {
if (torchLevel >= 1.0)
torchLevel = AVCaptureMaxAvailableTorchLevel;
BOOL success = [device setTorchModeOnWithLevel:torchLevel error:nil];
}
[device unlockForConfiguration];
}
}
You may also want to monitor the return value (success) from setTorchModeOnWithLevel:. You may get a failure if you try to set the level too high and the torch is overheating. In that case setting the level to AVCaptureMaxAvailableTorchLevel will set the level to the highest level that is allowed given the temperature of the torch.
iWasRobbed's answer is great, except there is an AVCaptureSession running in the background all the time. On my iPhone 4s it takes about 12% CPU power according to Instrument so my app took about 1% battery in a minute. In other words if the device is prepared for AV capture it's not cheap.
Using the code below my app requires 0.187% a minute so the battery life is more than 5x longer.
This code works just fine on any device (tested on both 3GS (no flash) and 4s). Tested on 4.3 in simulator as well.
#import <AVFoundation/AVFoundation.h>
- (void) turnTorchOn:(BOOL)on {
Class captureDeviceClass = NSClassFromString(#"AVCaptureDevice");
if (captureDeviceClass != nil) {
AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
if ([device hasTorch] && [device hasFlash]){
[device lockForConfiguration:nil];
if (on) {
[device setTorchMode:AVCaptureTorchModeOn];
[device setFlashMode:AVCaptureFlashModeOn];
torchIsOn = YES;
} else {
[device setTorchMode:AVCaptureTorchModeOff];
[device setFlashMode:AVCaptureFlashModeOff];
torchIsOn = NO;
}
[device unlockForConfiguration];
}
}
}
See a better answer below: https://stackoverflow.com/a/10054088/308315
Old answer:
First, in your AppDelegate .h file:
#import <AVFoundation/AVFoundation.h>
#interface AppDelegate : NSObject <UIApplicationDelegate> {
AVCaptureSession *torchSession;
}
#property (nonatomic, retain) AVCaptureSession * torchSession;
#end
Then in your AppDelegate .m file:
#implementation AppDelegate
#synthesize torchSession;
- (void)dealloc {
[torchSession release];
[super dealloc];
}
- (id) init {
if ((self = [super init])) {
// initialize flashlight
// test if this class even exists to ensure flashlight is turned on ONLY for iOS 4 and above
Class captureDeviceClass = NSClassFromString(#"AVCaptureDevice");
if (captureDeviceClass != nil) {
AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
if ([device hasTorch] && [device hasFlash]){
if (device.torchMode == AVCaptureTorchModeOff) {
NSLog(#"Setting up flashlight for later use...");
AVCaptureDeviceInput *flashInput = [AVCaptureDeviceInput deviceInputWithDevice:device error: nil];
AVCaptureVideoDataOutput *output = [[AVCaptureVideoDataOutput alloc] init];
AVCaptureSession *session = [[AVCaptureSession alloc] init];
[session beginConfiguration];
[device lockForConfiguration:nil];
[session addInput:flashInput];
[session addOutput:output];
[device unlockForConfiguration];
[output release];
[session commitConfiguration];
[session startRunning];
[self setTorchSession:session];
[session release];
}
}
}
}
return self;
}
Then anytime you want to turn it on, just do something like this:
// test if this class even exists to ensure flashlight is turned on ONLY for iOS 4 and above
Class captureDeviceClass = NSClassFromString(#"AVCaptureDevice");
if (captureDeviceClass != nil) {
AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
[device lockForConfiguration:nil];
[device setTorchMode:AVCaptureTorchModeOn];
[device setFlashMode:AVCaptureFlashModeOn];
[device unlockForConfiguration];
}
And similar for turning it off:
// test if this class even exists to ensure flashlight is turned on ONLY for iOS 4 and above
Class captureDeviceClass = NSClassFromString(#"AVCaptureDevice");
if (captureDeviceClass != nil) {
AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
[device lockForConfiguration:nil];
[device setTorchMode:AVCaptureTorchModeOff];
[device setFlashMode:AVCaptureFlashModeOff];
[device unlockForConfiguration];
}
the lockforConfiguration is set in your code, where you declare your AVCaptureDevice is a property.
[videoCaptureDevice lockForConfiguration:nil];
From iOS 6.0 and above, toggling torch flash on/off,
- (void) toggleFlash {
AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
if ([device hasTorch] && [device hasFlash]){
[device lockForConfiguration:nil];
[device setFlashMode:(device.flashActive) ? AVCaptureFlashModeOff : AVCaptureFlashModeOn];
[device setTorchMode:(device.torchActive) ? AVCaptureTorchModeOff : AVCaptureTorchModeOn];
[device unlockForConfiguration];
}
}
P.S. This approach is only suggestible if you don't have on/off function. Remember there's one more option Auto. i.e. AVCaptureFlashModeAuto and AVCaptureTorchModeAuto. To support auto mode as well, you've keep track of current mode and based on that change mode of flash & torch.
Swift 2.0 version:
func setTorchLevel(torchLevel: Float)
{
self.captureSession?.beginConfiguration()
defer {
self.captureSession?.commitConfiguration()
}
if let device = backCamera?.device where device.hasTorch && device.torchAvailable {
do {
try device.lockForConfiguration()
defer {
device.unlockForConfiguration()
}
if torchLevel <= 0.0 {
device.torchMode = .Off
}
else if torchLevel >= 1.0 {
try device.setTorchModeOnWithLevel(min(torchLevel, AVCaptureMaxAvailableTorchLevel))
}
}
catch let error {
print("Failed to set up torch level with error \(error)")
return
}
}
}
//import fremework in .h file
#import <AVFoundation/AVFoundation.h>
{
AVCaptureSession *torchSession;
}
#property(nonatomic,retain)AVCaptureSession *torchSession;
-(IBAction)onoff:(id)sender;
//implement in .m file
#synthesize torchSession;
-(IBAction)onoff:(id)sender
{
AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
if ([device hasTorch] && [device hasFlash])
{
if (device.torchMode == AVCaptureTorchModeOff)
{
[button setTitle:#"OFF" forState:UIControlStateNormal];
AVCaptureDeviceInput *flashInput = [AVCaptureDeviceInput deviceInputWithDevice:device error: nil];
AVCaptureVideoDataOutput *output = [[AVCaptureVideoDataOutput alloc] init];
AVCaptureSession *session = [[AVCaptureSession alloc] init];
[session beginConfiguration];
[device lockForConfiguration:nil];
[device setTorchMode:AVCaptureTorchModeOn];
[device setFlashMode:AVCaptureFlashModeOn];
[session addInput:flashInput];
[session addOutput:output];
[device unlockForConfiguration];
[output release];
[session commitConfiguration];
[session startRunning];
[self setTorchSession:session];
[session release];
}
else
{
[button setTitle:#"ON" forState:UIControlStateNormal];
[torchSession stopRunning];
}
}
}
- (void)dealloc
{
[torchSession release];
[super dealloc];
}
This work's very well.. hope it help's someone !
-(IBAction)flashlight:(id)sender {
AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
if ([device hasTorch] && [device hasFlash]){
if (device.torchMode == AVCaptureTorchModeOff) {
[sender setTitle:#"Torch Off" forState:UIControlStateNormal];
AVCaptureDeviceInput *flashInput = [AVCaptureDeviceInput deviceInputWithDevice:device error: nil];
AVCaptureVideoDataOutput *output = [[AVCaptureVideoDataOutput alloc] init];
AVCaptureSession *cam = [[AVCaptureSession alloc] init];
[cam beginConfiguration];
[device lockForConfiguration:nil];
[device setTorchMode:AVCaptureTorchModeOn];
[device setFlashMode:AVCaptureFlashModeOn];
[cam addInput:flashInput];
[cam addOutput:output];
[device unlockForConfiguration];
[cam commitConfiguration];
[cam startRunning];
[self setTorchSession:cam];
}
else {
[sender setTitle:#"Torch On" forState:UIControlStateNormal];
[_torchSession stopRunning];
}
}
}