Can we have camera controls enabled with AVCaptureSession..? - iphone

I want to to use AVCaptureSession as I have to fit camera a view in a particular frame (I am not sure if I can fit the camera frame using UIImagePickerController). But I also want to show camera controls (Auto and front/back camera button), does anyone know how I can achieve this..? or will I have to use these as custom buttons.

If you want to use AVCaptureSession, you will have to do all camera controls of your own (adding some overlayview to your AVCaptureSession camera). You can use UIImagePickerController and transform your camera using cameraViewTransform, for example full screen camera transform:
#define CAMERA_TRANSFORM 1.32
camera.showsCameraControls = YES;
camera.navigationBarHidden = YES;
camera.toolbarHidden = YES;
camera.wantsFullScreenLayout = YES;
camera.cameraViewTransform = CGAffineTransformScale(camera.cameraViewTransform, CAMERA_TRANSFORM, CAMERA_TRANSFORM);
and for overlay you have property:
#property (nonatomic, retain) UIView *cameraOverlayView;
but i would recommend you to use just a addSubview to your UIImagePickerController view:
[camera.view addSubview:self.overlay.view];

Related

MPMoviePlayerController video does not fill up the entire view

I am trying to add a MPMoviePlayerController view to my app. I am trying to control the position of it in code, and then place my own buttons underneath it (just a fullscreen and play/pause button).
However, the video does not take up the entire area of the video player. Is this normal? Can I make it so the entire thing is video? (This is what I mean: http://i.imgur.com/GWHlD8V.png)
This is how I am implementing it:
in .h:
#interface ViewController : UIViewController
#property (nonatomic, strong) MPMoviePlayerController *moviePlayerController;
#end
in .m:
NSURL *url = [NSURL URLWithString:#"http://localhost:8013/prog_index.m3u8"];
_moviePlayerController = [[MPMoviePlayerController alloc] initWithContentURL:url];
_moviePlayerController.controlStyle = MPMovieControlStyleNone;
// This places the player exactly where I want it. When I want it full screen
// I can dynamically update these values?
[_moviePlayerController.view setFrame:CGRectMake(100, 181, 650, 500)];
_moviePlayerController.view.layer.borderColor = [UIColor colorWithRed:0.329 green:0.80 blue:0.227 alpha:1].CGColor;
_moviePlayerController.view.layer.borderWidth = 2.0;
_moviePlayerController.shouldAutoplay = YES;
[self.view addSubview:_moviePlayerController.view];
[_moviePlayerController play];
Everything seems to work fine, except there are those black bars above and below the video. I would like it to be just possible, and replace the bottom one with my custom controls. Any thoughts?
Also, is this the best way to position the player?

How to overlay GLKView on top of UIImagePickerController

I'm trying to overlay OpenGL ES content, using a GLKView, on top of a live video feed from the camera using a UIImagePickerController. I've read several tutorials, books, and posts but, still can't find the answer. For your reference, some of the posts I've read are here, here and here.
In viewDidLoad I'm doing the following:
// Create an OpenGL ES 2.0 context and provide it to the view
// NOTE: viewOverlay is of class GLKView and a property of the view controller
viewOverlay.context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2];
viewOverlay.opaque = NO;
viewOverlay.backgroundColor=[UIColor clearColor];
// Make the new context current
[EAGLContext setCurrentContext:viewOverlay.context];
// Create a base effect that provides standard OpenGL ES 2.0
// Shading Language programs and set constants to be used for
// all subsequent rendering
self.baseEffect = [[GLKBaseEffect alloc] init];
self.baseEffect.useConstantColor = GL_TRUE;
self.baseEffect.constantColor = GLKVector4Make(
1.0f, // Red
0.0f, // Green
0.0f, // Blue
1.0f);// Alpha
// Set the background color stored in the current context
glClearColor(0.0f, 0.0f, 0.0f, 0.0f); // background color
And in viewDidAppear I'm doing this:
UIImagePickerController *uip;
uip = [[UIImagePickerController alloc] init];
uip.sourceType = UIImagePickerControllerSourceTypeCamera;
uip.showsCameraControls = NO;
uip.toolbarHidden = YES;
uip.navigationBarHidden = YES;
uip.wantsFullScreenLayout = YES;
uip.cameraViewTransform = CGAffineTransformScale(uip.cameraViewTransform, CAMERA_TRANSFORM, CAMERA_TRANSFORM);
[viewOverlay addSubview:uip.view];
[viewOverlay sendSubviewToBack:uip.view];
[viewOverlay bringSubviewToFront:viewOverlay];
If I step through the program, I can see the OpenGL objects get rendered once. But, when UIImagePickerController is added as a sub-view, it's the only thing on screen. If I comment out the last three lines, the OpenGL objects are rendered but, of course the camera isn't visible.
I'd like the camera's video image to be rendered in back of the OpenGL objects I'm drawing. Creating an augmented reality effect. Any and all help would be greatly appreciated!
Mike
What do you want your camera to do - just display a camera view for an AR effect, or actually use/manipulate the image data too? If you need anything other than a simple AR display, use AVFoundation.
I've had loads of trouble with this before and read the same posts you have, so I offer two solutions:
1) Use a Container View
In your storyboard file, create a UIViewController with a UIView for the camera and a Container View on top with a segue connected to a GLKViewController. Link your main UIViewController to your camera code and link your GLKViewController to your OpenGL ES code. Both the UIView and the GLKView inside the container will load and run seperately when the UIViewController is visible.
2) App delegate hack
Setup your UIImagePickerController inside the app delegate, specifically the method:
(BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
Then, add the subview to your window property. This will always make sure that your camera gets loaded onto your window before any views, and ensures it is at the bottom of the layer stack.

iphone: displaying small, live camera image in window

I'd like to invoke the camera and display a live image in a small preview window (similar to below) that is embedded in a standard viewController. The code below creates the live reduced camera image, but I cannot see the other objects on the NIB file. Thoughts appreciated.
imagePicker = [[UIImagePickerController alloc] init];
//Setting the control source type as the Camera device.
imagePicker.sourceType = UIImagePickerControllerSourceTypeCamera;
//Camera display is off
imagePicker.showsCameraControls = NO;
imagePicker.navigationBarHidden = YES;
//Picking only the rear camera.
imagePicker.cameraDevice = UIImagePickerControllerCameraDeviceRear;
//Turning the camera flash off.
imagePicker.cameraFlashMode = UIImagePickerControllerCameraFlashModeOn;
// Make camera view partial screen:
imagePicker.cameraViewTransform = CGAffineTransformScale(imagePicker.cameraViewTransform, 0.5, 0.5);
// add subView
[self.view addSubview:imagePicker.view];
[imagePicker viewWillAppear:YES];
[imagePicker viewDidAppear:YES];
// Show the picker:
[self presentModalViewController:imagePicker animated:YES];
Without running the code, it looks like you are changing the live image, not the size of the view. So the original fullsize view is showing over the top of your other views.
Have you tried using camerOverlayView to overlay the viewcontrollers view on top of the live image?
cameraOverlayView
The custom view to display on top of the default image picker interface.
#property (nonatomic, retain) UIView *cameraOverlayView Discussion You
can use an overlay view to present a custom view hierarchy on top of
the default image picker interface. The image picker layers your
custom overlay view on top of the other image picker views and
positions it relative to the screen coordinates. If you have the
default camera controls set to be visible, incorporate transparency
into your view, or position it to avoid obscuring the underlying
content.

Zooming image in a scroll view

I want to zoom an image in a scroll view. I used the below code.
All are working fine, but the image is not zooming. Anyone please
help. I am a beginner in iPhone app development.
I had connected the delegate to files manager and set max zooming to 5
I can see the image. But how can I zoom it.
IBOutlet UIScrollView *scrForImg;
IBOutlet UIImageView *imgForScr;
- (void)viewDidLoad {
[super viewDidLoad];
NSString *imagePath = [NSString stringWithFormat:#"myImage.png"];
imgForScr.image = [UIImage imageNamed:imagePath];
}
- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView{
return imgForScr;
}
This is all documented here.
HTH.
The image needs to exist in an UIImageView, then you should be able to pan/zoom.
Is it visible? Or does the scroll view contain nothing at all?

Tiled Background Image: Can I do that easily with UIImageView?

I have a fullscreen background image that is tiled, i.e. it has to be reproduced a few times horizontally and vertically in order to make a big one. Like in the browsers on ugly home pages ;)
Is UIImageView my friend for this?
If I understand your question correctly you can use colorWithPatternImage: on UIColor then set the background color on a UIView.
If you must use a UIImageView you can do the same but whatever image you place in the image view will draw in front of the tiled image.
To get alpha to work with pattern image, make sure you have the following set:
view.backgroundColor = [UIColor colorWithPatternImage:aImage];
view.layer.opaque = NO;
In WWDC 2018 video session 219 - Image and Graphics Best Practices, Apple engineer explicitly recommends not to use the pattern color for tiling backgrounds:
I recommend not using patterned colors with a background color property on UIView. Instead, create a UIImageView. Assign your image to that image view. And use the functions on UIImageView to set your tiling parameters appropriately.
So the best and simplest way to create a tiled background would be like this:
imageView.image = image.resizableImage(withCapInsets: .zero, resizingMode: .tile)
Or even simpler, if you use asset catalog – select your pattern image asset and, in the Attributes inspector, enable Slicing (Horizontal/Vertical or both), set the insets to zero, and width/height to the dimensions of your image:
then simply assign this image to your image view (Interface Builder works, too), just don't forget to set the UIImageView's contentMode to .scaleToFill.
For years I used Bill Dudney's approach, but iOS 6 has a much better solution. And ... today I found a way to make this work on old versions of iOS too.
create the new class "UIImage+Tileable" (copy/paste source below)
import this in any class where you want a UIImageView with tileable image. It's a category, so it "upgrades" all your UIImage's into tileable ones, using standard Apple calls
when you want a "tiling" version of an image, call: "image = [image imageResizingModeTile]"
UIImage+Tileable.h
#import <UIKit/UIKit.h>
#interface UIImage (Tileable)
-(UIImage*) imageResizingModeTile;
#end
UIImage+Tileable.m
#import "UIImage+Tileable.h"
#implementation UIImage (Tileable)
-(UIImage*) imageResizingModeTile
{
float iOSVersion = [[[UIDevice currentDevice] systemVersion] floatValue];
if( iOSVersion >= 6.0f )
{
return [self resizableImageWithCapInsets:UIEdgeInsetsZero resizingMode:UIImageResizingModeTile];
}
else
{
return [self resizableImageWithCapInsets:UIEdgeInsetsZero];
}
}
#end
I use a variation of #Rivera's solution:
Put the following in a UIView extension:
- (void)setColorPattern:(NSString *)imageName
{
[self setBackgroundColor:[UIColor colorWithPatternImage:[UIImage imageNamed:imageName]]];
}
Then you can set the background pattern in the storyboard/xib file:
As I really like Interface Builder I created this UIImageView subclass to apply tiled backgrounds:
#interface PETiledImageView : UIImageView
#end
#implementation PETiledImageView
- (void)awakeFromNib
{
[super awakeFromNib];
UIImage * imageToTile = self.image;
self.image = nil;
UIColor * tiledColor = [UIColor colorWithPatternImage:imageToTile];
self.backgroundColor = tiledColor;
}
#end
I tried overriding setImage: but it seems IB doesn't call it when decoding a Nib file.
Swift version of Daniel T's solution. You still need to set the keyPath value in IB. Of course you could be more careful unwrapping the Optional UIImage.
extension UIView {
var colorPattern:String {
get {
return "" // Not useful here.
}
set {
self.backgroundColor = UIColor(patternImage: UIImage(named:newValue)!)
}
}
}