I followed the iOS video processing tutorial on the OpenCV site and managed to compile and install it on the device. However when I click on the "Start" button, nothing visible happens. Apparently neither my - (void)processImage:(Mat&)image callback is never called. Could you give me some hints what could be the problem?
Some things I checked:
actionStart is called, and both log lines prints YES
the self object is valid when assigned to self.videoCamera.delegate
imageView is valid and visible on the screen
videoCamera is initialized when its start method is called
I use a iPhone 3GS for testing.
Here is the full source of my ViewController.h:
#import <UIKit/UIKit.h>
#import <opencv2/highgui/cap_ios.h>
#interface ViewController : UIViewController <CvVideoCameraDelegate>
{
IBOutlet UIImageView* imageView;
IBOutlet UIButton* button;
CvVideoCamera* videoCamera;
}
- (IBAction)actionStart:(id)sender;
#property (nonatomic, strong) CvVideoCamera* videoCamera;
#end
and ViewController.mm:
#implementation ViewController
#synthesize videoCamera;
- (void)viewDidLoad
{
[super viewDidLoad];
self.videoCamera = [[CvVideoCamera alloc] initWithParentView:imageView];
self.videoCamera.delegate = self;
self.videoCamera.defaultAVCaptureDevicePosition = AVCaptureDevicePositionFront;
self.videoCamera.defaultAVCaptureSessionPreset = AVCaptureSessionPreset352x288;
self.videoCamera.defaultAVCaptureVideoOrientation = AVCaptureVideoOrientationPortrait;
self.videoCamera.defaultFPS = 30;
self.videoCamera.grayscaleMode = NO;
}
#pragma mark - UI Actions
- (IBAction)actionStart:(id)sender;
{
[self.videoCamera start];
NSLog(#"video camera running: %d", [self.videoCamera running]);
NSLog(#"capture session loaded: %d", [self.videoCamera captureSessionLoaded]);
}
#pragma mark - Protocol CvVideoCameraDelegate
- (void)processImage:(cv::Mat&)image
{
// Do some OpenCV stuff with the image
cv::Mat image_copy;
cvtColor(image, image_copy, CV_BGRA2BGR);
// invert image
bitwise_not(image_copy, image_copy);
cvtColor(image_copy, image, CV_BGR2BGRA);
}
#end
I tested on an iPhone 4 and it works well. Maybe the iPhone 3GS doesn't have a front facing camera? Then you have to change this line: self.videoCamera.defaultAVCaptureDevicePosition = AVCaptureDevicePositionFront to self.videoCamera.defaultAVCaptureDevicePosition = AVCaptureDevicePositionBack
Related
Am a newbie to iOS programming and to Core Plot. Am using XCode 4.2 and iOS 5, and testing the iPhone App using iOS Simulator.
I know am overlooking something here (breaking my head on this for more than a day & tried google'ing a lot & tried out various possible solutions, all in vain). Can someone please help or any pointers?
Am trying to do something very simple -> adding a pie chart (done using Core Plot) as a subview. Initially, I was displaying the pie chart as a modal view & it worked fine. Now, in the same view I want to add few buttons and so I created a view (which will get displayed on pressing a button) in which I added the 2 buttons and also tried to add this pie chart too. The buttons display fine but the pie chart is not to be seen!
This is the XIB file of the view called 'GraphView' which gets displayed when a button's pressed:
In the above screenshot, the highlighted view 'View' is a UIView object within which I want to display the piechart. The entire view 'GraphView' gets displayed fine; the two buttons appear, but the piechart that I added to the subview doesn't. The UIView object that I added as subview in the above figure also gets displayed fine (I checked it by setting a background color for it). This is the code:
GRAPHVIEW.H
#import <UIKit/UIKit.h>
#import "PieChartView.h"
#interface GraphView : UIViewController
#property (strong, nonatomic) PieChartView *pieChartView;
// gView is the view which is linked to the 'UIView' subview in IB
// in the above figure
#property (strong, nonatomic) IBOutlet UIView *gView;
#property (strong, nonatomic) IBOutlet UIButton *buttonBack;
#property (strong, nonatomic) IBOutlet UIButton *buttonMail;
-(void) setHistoryData:(NSArray *)history;
...
...
#end
GRAPHVIEW.M
...
...
#synthesize gView;
#synthesize buttonBack;
#synthesize buttonMail;
...
...
-(void) setHistoryData:(NSArray *)history {
NSLog(#"GraphView: setHistoryData");
[pieChartView setHistoryData:history];
[gView addSubview:pieChartView];
}
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
pieChartView = [[PieChartView alloc] init];
return self;
}
...
...
#pragma mark - View lifecycle
- (void)viewDidLoad
{
NSLog(#"GraphView: viewDidLoad");
[super viewDidLoad];
[pieChartView initializeGraph];
}
- (void)viewDidUnload
{
[super viewDidUnload];
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
// Return YES for supported orientations
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
#end
PIECHARTVIEW.H
This is the one that draws (that which is 'supposed to' draw) the pie chart!
#import <UIKit/UIKit.h>
#import "CorePlot-CocoaTouch.h"
// I tied subclassing 'UIViewController' or just 'UIView'...all in vain
#interface PieChartView : CPTGraphHostingView <CPTPlotDataSource> {
CPTXYGraph *graph;
CPTPieChart *pieChart;
}
#property (nonatomic, retain) CPTXYGraph *graph;
-(void) initializeGraph;
-(void) initializePieChart;
-(void) setHistoryData:(NSArray *)history;
#end
PIECHARTVIEW.m
...
#implementation PieChartView
#synthesize graph;
NSArray *historyData;
// I added the NSLog to see if these get called, but they don't seem to get called!
// So, this means that the pie chart is not being drawn actually!
-(NSUInteger)numberOfRecordsForPlot:(CPTPlot *)plot {
NSLog(#"numberOfRecordsForPlot: History count: %d", (int)[historyData count]);
return [historyData count];
}
// This too isn't getting called
-(NSNumber *) numberForPlot:(CPTPlot *)plot field:(NSUInteger)fieldEnum recordIndex:(NSUInteger)index {
NSLog(#"historyView: numberForPlot");
return [historyData objectAtIndex:index];
}
// This too is not getting called! OMG!
-(CPTLayer *)dataLabelForPlot:(CPTPlot *)plot recordIndex:(NSUInteger)index {
NSLog(#"HistoryView: dataLabelForPlot");
...
}
// This method is getting called. Am seeing the log messages
-(void) initializeGraph {
NSLog(#"HistoryView: initializeGraph");
graph = [[CPTXYGraph alloc] init];
CPTTheme *theme = [CPTTheme themeNamed:kCPTDarkGradientTheme];
[graph applyTheme:theme];
CPTGraphHostingView *hostingView = (CPTGraphHostingView *) self;
hostingView.hostedGraph = graph;
//hostingView.bounds = CGRectMake(5, 5, 70, 70);
[self initializePieChart];
}
// This method is also getting called. I see the log messages from this method too
/**
* Initialize the pie chart for display
*/
-(void) initializePieChart {
NSLog(#"HistoryView: initializePieChart");
pieChart = [[CPTPieChart alloc] init];
pieChart.dataSource = self;
pieChart.pieRadius = 100.0;
pieChart.opaque = FALSE;
//pieChart.pieRadius = 60;
pieChart.shadowOffset = CGSizeMake(-1, 1);
pieChart.identifier = #"PieChart";
pieChart.startAngle = M_PI_4;
pieChart.sliceDirection = CPTPieDirectionCounterClockwise;
pieChart.labelOffset = -0.6;
[graph addPlot:pieChart];
NSLog(#"added pie chart to the graph view");
}
// This also is getting called
-(void) setHistoryData:(NSArray *)history {
NSLog(#"HistoryView: setHistoryData");
historyData = history;
}
...
...
#end
You don't need the gView property. Remove it and change the pieChartView declaration to:
#property (strong, nonatomic) IBOutlet PieChartView *pieChartView;
Link the custom view to this property instead of gView and change the class in IB to PieChartView. Also remove the initialization of this property from -initWithNibName:bundle:—the view will be initialized automatically when the nib is loaded.
I'm using xcode 4.2 and building an iphone app, and have a view that when opened plays an audio stream.
What i try to achieve is have the app continue playing even if it enters the background.
I've tried any possible solution that i found in stackoverflow or elsewhere (and there are many available), but can't get it work. When the application enters background the audio stops, when i open the app again the audio continues.
In my Info.plist ia have set 2 rows:
Required Background Modes -> App plays audio &
Application does not run in background -> NO
What am i missing? what else is needed to keep playing the audio in the background?
Thank you in advance.
EDIT:
I see many answers on the issue, suggestiong the use of AVAudio Framework. Is there any chance that MPMoviePlayerController is not able to play the stream in the background? Should i change to AVAudio?
EDIT 2:
Ok, seems it's too complex for me to achieve. I'm giving the exact code, hope this will help.
RadioStreamer.h
#import <UIKit/UIKit.h>
#import "MediaPlayer/MediaPlayer.h"
#interface RadioStreamer : UIViewController {
MPMoviePlayerController *player;
IBOutlet UIButton *playButton;
IBOutlet UIButton *pauseButton;
}
#property (nonatomic, retain) MPMoviePlayerController *player;
#property (nonatomic, retain) IBOutlet UIButton *playButton;
#property (nonatomic, retain) IBOutlet UIButton *pauseButton;
- (IBAction)playButtonPressed:(id)button;
- (IBAction)pauseButtonPressed:(id)button;
- (void) playAudio;
- (void) pauseAudio;
#end
RadioStreamer.m
#import "RadioStreamer.h"
#import "tabbartestAppDelegate.h"
#implementation RadioStreamer
#synthesize player;
#synthesize playButton;
#synthesize pauseButton;
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
return self;
}
#pragma mark - View lifecycle
- (void)viewDidLoad
{
[super viewDidLoad];
self.navigationItem.title=#"";
// Do any additional setup after loading the view from its nib.
if (!self.player) {
player = [[MPMoviePlayerController alloc] initWithContentURL:[NSURL URLWithString:#"http://s6.onweb.gr:8006/listen.pls"]];
player.movieSourceType = MPMovieSourceTypeStreaming;
player.view.frame = CGRectMake(55, 180, 200, 30);
player.backgroundView.backgroundColor = [UIColor clearColor];
player.view.backgroundColor = [UIColor clearColor];
[self.view addSubview:player.view];
[player play];
}
}
- (void) playAudio {
if (player.playbackState != MPMoviePlaybackStatePlaying){
[player play];
}
}
- (void) pauseAudio {
if (player.playbackState == MPMoviePlaybackStatePlaying) {
[player pause];
}
}
- (IBAction)playButtonPressed:(id)button {
[self playAudio];
}
- (IBAction)pauseButtonPressed:(id)button {
[self pauseAudio];
}
- (void)viewDidUnload
{
[super viewDidUnload];
}
- (void)dealloc {
[self.player release];
[self.playButton release];
[self.pauseButton release];
self.player = nil;
self.playButton = nil;
self.pauseButton = nil;
}
#end
Check your audio session setup as that might need some extra attention.
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback
error:nil];
[[AVAudioSession sharedInstance] setActive:YES
error:nil];
[[UIApplication sharedApplication] beginReceivingRemoteControlEvents];
How stumbled upon the programming tutorial in details at this place.
http://mobisoftinfotech.com/integrate-music-player-in-iphone/
This should play the music within the app and also continue to play if you take your app in background.
I have a custom UIWebView written like this :
.h
#interface MiniWebViewController : UIViewController {
NSString* destinationURL;
UIWebView* webView;
UIActivityIndicatorView* activityIndicatorView;
}
#property (nonatomic, retain) NSString* destinationURL;
#property (nonatomic, retain) IBOutlet UIWebView* webView;
#property (nonatomic, retain) IBOutlet UIActivityIndicatorView* activityIndicatorView;
- (void) run;
#end
.m
#synthesize destinationURL;
#synthesize webView;
#synthesize activityIndicatorView;
- (id) initWithFrame:(CGRect)frame {
if (self = [super initWithNibName:#"MiniWebView" bundle:nil]) {
self.destinationURL = #"";
self.view.frame = frame;
self.activityIndicatorView.center = self.webView.center;
}
return self;
}
- (void) run {
[self.webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:self.destinationURL]]];
}
It is called an initied from another ViewController :
- (void) aFunction {
MiniWebViewController* oneViewController = [[MiniWebViewController alloc] initWithFrame:CGRectMake(/*Some Rect*/];
oneViewController.webView.tag = i;
oneViewController.destinationURL = /*SomeURL*/;
oneViewController.webView.delegate = self;
[self.view addSubview:oneViewController.view]; /* the Web view is inside this one */
[oneViewController run];
}
- (void) webViewDidFinishLoad:(UIWebView *)webView {
int webViewID = webView.tag;
MiniWebViewController* webViewController = [self.webViews objectAtIndex:webViewID];
[webViewController.activityIndicatorView stopAnimating];
}
- (void)webViewDidStartLoad:(UIWebView *)webView {
int webViewID = webView.tag;
MiniWebViewController* webViewController = [self.webViews objectAtIndex:webViewID];
[webViewController.activityIndicatorView startAnimating];
}
Into IB hidesWhenStopped is also checked. Everything is linked. The style of the indicator is set to "Large White" into IB.
When running, the indicator is not large, but small.
It is successfully started and stopped (delegate calls are triggered), but it doesn't hide when stopped.
What's the problem ? I don't see...
After a careful look in your code, you are modifying the UIActivityView in your init method. Change those so that they are in your viewDidLoad. At init, you view is not yet loaded, therefore, there is not an instance of those objects yet created in your controller.
These are the statement that need to be moved:
self.activityIndicatorView.hidesWhenStopped = YES;
self.view.frame = frame;
self.activityIndicatorView.center = self.webView.center;
This goes back to a fundamental of Objective-C: Sending a message to a nil object...returns nil. This is an annoying feature at times because there is no compile time warning, nor is there any runtime exception--a feature of the language.
Stupid I am, and XCode/cocoa really doesn't help.
I had loaded a wrong XIB name that DOES NOT exist.
So I ask to load something that does not exist, and the app stil works, even showing and using objects that does not exist. Untill one call does not work as expected. No crash...
It's nonsense.
Im trying to add an animation of a monkey using a NSMutablAarray of UIImageViews. Im following a tutorial on youtube but when i compile i get a strange error: "stray '\357' in program." on the line "UIImage *img = [UIImage imageName: pictureName];"
Here are my h and m files..
#import "WinGameView.h"
#implementation WinGameView
#synthesize monkeyAnimation;
#synthesize monkeyImages;
-(IBAction)pushBack{
[self dismissModalViewControllerAnimated:YES];
}
// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad {
monkeyImages = [[NSMutableArray alloc] init];
for(int i = 1; i < 10; i++)
{
NSString *pictureName = [NSString stringWithFormat:#"monkey%d.gif",i];
UIImage *img = [UIImage imageName: pictureName];
if (img) [monkeyImages addObject:img];
}
[monkeyAnimation setAnimationImages:monkeyImages];
[monkeyAnimation setAnimationDuration:1.2f];
[monkeyAnimation startAnimating];
[super viewDidLoad];
}
and
#import <UIKit/UIKit.h>
#interface WinGameView : UIViewController {
IBOutlet UILabel *labelWin;
IBOutlet UILabel *labelWin2;
IBOutlet UIButton *buttonBack;
IBOutlet UIImageView *monkeyAnimation;
NSMutableArray *monkeyImages;
}
#property(nonatomic,retain)UIImageView *monkeyAnimation;
#property(nonatomic, retain)NSMutableArray *monkeyImages;
-(IBAction)pushBack;
#end
Does anyone know what i am doing wrong or why i am getting these wierd message. I have tried to look it up online but to no avail.
There is a stray "byte order mark" on that line (or even the line above or below). Retype the inside of the for loop by hand.
Special Thanks in advance......
I m the beggininer in iphone software development.
Just looking for how to programmatically add real time a watermark image to camera view using cocoa. Not looking for a step by step ( although that would awesome ), but more or less looking for where I should start looking to learn how. Are there frameworks developed to work for this. Would like something native to objective-C using XCode framework because I would like to eventually give this a go on the iPhone. Any help would be great.
UPDATE: here's my other answer about how this overlay view can be put under the camera animations: camera overlay view - just for preview?
Helo Rajendra!
I've created a simple Window-based iPhone OS Application to give you a very simple example on what and how should be done to capture photos with camera, overlay views in camera mode, resize and merge images. This project is actually has only AppDelegate header and implementation files and can be easily reproduced in XCode.
Here's the header file:
//
// CameraWatermarkAppDelegate.h
// CameraWatermark
//
// Created by Ivan Karpan on 1/16/10.
// Copyright __MyCompanyName__ 2010. All rights reserved.
//
#import <UIKit/UIKit.h>
#interface CameraWatermarkAppDelegate : NSObject < UIApplicationDelegate, UIImagePickerControllerDelegate, UINavigationControllerDelegate > {
UIImageView *imageView;
UIViewController *viewController;
UIWindow *window;
}
#property (nonatomic, retain) UIImageView *imageView;
#property (nonatomic, retain) UIViewController *viewController;
#property (nonatomic, retain) IBOutlet UIWindow *window;
#end
And here's the implementation file:
//
// CameraWatermarkAppDelegate.m
// CameraWatermark
//
// Created by Ivan Karpan on 1/16/10.
// Copyright __MyCompanyName__ 2010. All rights reserved.
//
#import "CameraWatermarkAppDelegate.h"
const float WATERMARK_ALPHA = 0.5;
#implementation CameraWatermarkAppDelegate
#synthesize imageView, viewController, window;
- (void)applicationDidFinishLaunching:(UIApplication *)application {
self.viewController = [[UIViewController new] autorelease];
viewController.view.backgroundColor = [UIColor blackColor];
// An image view to save to (and therefore display) the captured image
self.imageView = [[UIImageView new] autorelease];
imageView.frame = viewController.view.frame;
[viewController.view addSubview:imageView];
[window addSubview:viewController.view];
UIImagePickerController *anImagePickerController = [UIImagePickerController new];
anImagePickerController.delegate = self;
anImagePickerController.sourceType = UIImagePickerControllerSourceTypeCamera;
{// This block of code is only needed in case you want your watermark to be displayed also during the shooting process
UIImageView *anImageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"Watermark.png"]];
anImageView.alpha = WATERMARK_ALPHA;
anImageView.contentMode = UIViewContentModeTopLeft;
anImageView.frame = viewController.view.frame;
anImagePickerController.cameraOverlayView = anImageView;
[anImageView release];
}
// From the very beginning we simply present the image picker controller
[viewController presentModalViewController:anImagePickerController animated:NO];
[anImagePickerController release];
}
- (void)dealloc {
[imageView release];
[viewController release];
[window release];
[super dealloc];
}
#pragma mark UIImagePickerControllerDelegate
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
UIGraphicsBeginImageContext(CGSizeMake(320, 480));
// This is where we resize captured image
[(UIImage *)[info objectForKey:UIImagePickerControllerOriginalImage] drawInRect:CGRectMake(0, 0, 320, 480)];
// And add the watermark on top of it
[[UIImage imageNamed:#"Watermark.png"] drawAtPoint:CGPointMake(0, 0) blendMode:kCGBlendModeNormal alpha:WATERMARK_ALPHA];
// Save the results directly to the image view property
imageView.image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
// Dismiss the image picker controller and look at the results
[picker dismissModalViewControllerAnimated:YES];
}
#end
I hope this will serve you as a starting point.