Cocos2d V3 can't switch scenes after using the UIImagePickerController Class - cocoa

I'm having a little trouble switching scenes (or even displaying sprites) on my CCscene UserLevelCreation, but it only happens after i use the UIImagePickerController to take/accept a picture, And then when I try to switch scenes, It crashes with the error:
"Could not attach texture to framebuffer"
this is the code I use to take a picture:
-(void)takePhoto{
AppController *appdel = (AppController*) [[UIApplication sharedApplication] delegate];
#try {
uip = [[UIImagePickerController alloc] init] ;
uip.sourceType = UIImagePickerControllerSourceTypeCamera;
uip.allowsEditing = YES;
uip.delegate = self;
}
#catch (NSException * e) {
uip = nil;
}
#finally {
if(uip) {
[appdel.navController presentModalViewController:uip animated:NO];
}
}
}
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info{
NSString * LevelImage;
LevelImage=[info objectForKey:UIImagePickerControllerOriginalImage];
AppController *appdel = (AppController*) [[UIApplication sharedApplication] delegate];
[appdel.navController dismissModalViewControllerAnimated:YES];
[NSThread detachNewThreadSelector:#selector(writeImgToPath:) toTarget:self withObject:LevelImage];
}
And the WriteImageToPath function:
-(void)writeImgToPath:(id)sender
{
UIImage *image = sender;
NSArray *pathArr = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,
NSUserDomainMask,
YES);
CGSize size;
int currentProfileIndex = 1;
NSString *path = [[pathArr objectAtIndex:0]
stringByAppendingPathComponent:[NSString stringWithFormat:#"CustomLevel_%d.png",currentProfileIndex]];
size = CGSizeMake(1136, 640);
UIGraphicsBeginImageContext(size);
[image drawInRect:CGRectMake(0, 0, 1136, 640)];
image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
NSData *data = UIImagePNGRepresentation(image);
[data writeToFile:path atomically:YES];
CCLOG(#"saved...");
CGRect r = CGRectMake(0, 0, 1136, 640);
UIGraphicsBeginImageContext(r.size);
UIImage *img1;
[image drawInRect:r];
img1 = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
UIImageWriteToSavedPhotosAlbum(img1, nil, nil, nil);
currentProfileIndex++;
[[CCDirector sharedDirector] replaceScene:[LevelEditor Scene]
withTransition:[CCTransition transitionPushWithDirection:CCTransitionDirectionLeft duration:1.0f]];
}
-UPDATE----------------------------------------------------------------------------------
I just tried switching scenes in different places in the code, and I can switch scenes freely until the Function:
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info{
I think that function might be the problem.
So far, I have tried to:
1.switch scenes before taking the picture, and that works fine
2.I read that it might be because i was resizing the image, but commenting that out made no difference.
3.I've also added breakpoints before the scene switch, and the scene isn't nil
4.Finally i tred dismissing the uip UIImagePickerController, but that made no difference either.
Sorry for the long post /: if anyone knows whats going on any help would be really great.

Ok so I found the problem to be this line:
[NSThread detachNewThreadSelector:#selector(writeImgToPath:) toTarget:self withObject:LevelImage];
}
Apparently some Parts of Uikit are not thread-friendly, so I'm now using just
[self writeImgToPath];
And it works, hope this helps anyone with the same problem.

Related

Music through Sprite Kit Scenes?

So I have a sprite kit game and I'm adding music to it. The music worked fine and worked until I decided to add a slider to control the music volume. So to do this I added another scene for the "options menu." The problem is, when I exit the scene to go to the actual game interface, the game music completely disappears. Also I'm having trouble removing the actual slider. My code for the options scene will be listed down below. (It is still in the making) I'm new to this website so I'm sorry if the code is messed up.
#interface OptionsScene ()
#property BOOL contentCreated;
#end
#implementation OptionsScene
-(id)initWithSize:(CGSize)size
{
if (self = [super initWithSize:size]) {
self.anchorPoint = CGPointMake(0.5, 0.5);
}
return self;
}
-(void)didMoveToView:(SKView *)view
{
NSString *music = [[NSBundle mainBundle] pathForResource:#"InAmberClad" ofType:#"mp3"];
backGroundMusic = [[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:music] error:NULL];
backGroundMusic.delegate = self;
backGroundMusic.numberOfLoops = -1;
[backGroundMusic play];
CGRect frame = CGRectMake(200, 300, 150, 10);
_volumeSlider = [[UISlider alloc] initWithFrame:frame];
[_volumeSlider addTarget:self action:#selector(volumeControl) forControlEvents:UIControlEventValueChanged];
_volumeSlider.maximumValue = 1;
_volumeSlider.minimumValue = 0;
_volumeSlider.continuous = YES;
[_volumeSlider setValue:0.5];
[_volumeSlider setBackgroundColor:[UIColor blackColor]];
if (!self.contentCreated) {
[self.view addSubview:_volumeSlider];
[self createContents];
self.contentCreated = YES;
}
}
-(void)createContents
{
self.scaleMode = SKSceneScaleModeAspectFill;
}
-(void)volumeControl
{
[backGroundMusic setVolume:_volumeSlider.value];
}
-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
SKScene *options = [[MyScene alloc] initWithSize:self.size];
[self.view presentScene:options];
}
#end
I think if you don't delegate the backgroundMusic to self, this problem will be solved. Also, before play the music, run a [backGroundMusic prepareToPlay]; will improve performance.
Here is a link to a tutorial, on page search for "Music" to see how he did it.
Ray Wenderlich

cocoa nsimage does not get saved

I'm new to cocoa and programming, sorry if this is something basic.
I'm using ARC. I have an NSImageView component, which is controlled by DropZone class. I drag & drop an image into it, but once I try to call in the scalling method I got, it tells me that the ": ImageIO: CGImageSourceCreateWithData data parameter is nil" I assume I'm doing something wrong, just don't know what yet.
Here's my method in DropZone.m
- (void)scaleIcons:(NSString *)outputPath{
NSImage *anImage;
NSSize imageSize;
NSString *finalPath;
anImage = [[NSImage alloc]init];
anImage = image;
imageSize = [anImage size];
imageSize.width = 512;
imageSize.height = 512;
[anImage setSize:imageSize];
finalPath = [outputPath stringByAppendingString:#"/icon_512x512.png"];
NSData *imageData = [anImage TIFFRepresentation];
NSBitmapImageRep *rep = [NSBitmapImageRep imageRepWithData:imageData];
NSData *dataToWrite = [rep representationUsingType:NSPNGFileType properties:nil];
[dataToWrite writeToFile:finalPath atomically:NO];
}
The DropZone.h
#interface DropZone : NSImageView <NSDraggingDestination>{
NSImage *image;
}
- (void)scaleIcons:(NSString *)outputPath;
#end
And here's how I call it it my AppDelegate.m
- (IBAction)createIconButtonClicked:(id)sender {
NSFileManager *filemgr;
NSString *tempDir;
filemgr = [NSFileManager defaultManager];
tempDir = [pathString stringByAppendingString:#"/icon.iconset"];
NSURL *newDir = [NSURL fileURLWithPath:tempDir];
[filemgr createDirectoryAtURL: newDir withIntermediateDirectories:YES attributes: nil error:nil];
DropZone *myZone = [[DropZone alloc] init];
[myZone scaleIcons:tempDir];
NSAlert *alert = [[NSAlert alloc] init];
[alert setMessageText:#"Done!"];
[alert runModal];
}
the image get's pulled from the pastebaord:
- (BOOL)performDragOperation:(id<NSDraggingInfo>)sender{
if ([NSImage canInitWithPasteboard:[sender draggingPasteboard]]) {
image = [[NSImage alloc]initWithPasteboard:[sender draggingPasteboard]];
[self setImage:image];
[self setImageAlignment: NSImageAlignCenter];
}
return YES;
}
For some reason my "image" gets lost. Could somebody help?
The problem is that you're creating a new instance of DropZone in your app delegate, but I'm assuming that you created the image view in IB and changed its class to DropZone. Is that correct? If so, you need to have an IBOutlet in the app delegate connected to the image view in IB, and have this:
[self.iv scaleIcons:tempDir];
where iv is my IBOutlet.
Without knowing where "image" comes from, I would say your problem is in these lines...
anImage = [[NSImage alloc]init];
anImage = image;
You should just grab the image from the imageView...
anImage = [myImageView image];

Posting images from camera roll to facebook in xcode 4.5

I've got some functionality set up. But I'm lost on where to go from here. I can probably figure out what to do with facebook once I know how to actually use the images. I tried saving the image into NSDictionary and then redirecting to a different View Controller, but it won't let me redirect from within the imagePickerController method. So anybody have any idea how to use the image selected from camera roll?
My next idea was to save it in the NSDictionary and then just have a statement checking to see if the NSdictionary value changed but that's not an efficient way of doing it at all.
EDITED below to include the answer provided, but nothing happens, no image displays or anything. What am I missing?
- (void) useCameraRoll
{
if ([UIImagePickerController isSourceTypeAvailable:
UIImagePickerControllerSourceTypeSavedPhotosAlbum])
{
UIImagePickerController *imagePicker =
[[UIImagePickerController alloc] init];
imagePicker.delegate = self;
imagePicker.sourceType =
UIImagePickerControllerSourceTypePhotoLibrary;
imagePicker.mediaTypes = [NSArray arrayWithObjects:
(NSString *) kUTTypeImage,
nil];
imagePicker.allowsEditing = NO;
[self presentModalViewController:imagePicker animated:YES];
[imagePicker release];
newMedia = NO;
}
}
-(void)imagePickerController:(UIImagePickerController *)picker
didFinishPickingMediaWithInfo:(NSDictionary *)info
{
NSString *mediaType = [info
objectForKey:UIImagePickerControllerMediaType];
[self dismissModalViewControllerAnimated:YES];
if ([mediaType isEqualToString:(NSString *)kUTTypeImage]) {
UIImage *image = [info
objectForKey:UIImagePickerControllerOriginalImage];
NSLog(#"image:%#",image);
displayPhoto.image = image;
[displayPhoto setFrame:CGRectMake(0, 0, 320, 480)];
[[self view] addSubview:displayPhoto];
}
else if ([mediaType isEqualToString:(NSString *)kUTTypeMovie])
{
// Code here to support video if enabled
}
}
Assuming you have called this from a view controller with a button that you have created, why not just add a UIImageView onto your view controller? Call it myPhotoImageView or something like that and then in the didFinishPickingMediaWithInfo method, just add the following line of code after
UIImage *image = [info objectForKey:UIImagePickerControllerOriginalImage];
as
myPhotoImageView.image = image;
To size the image view so that the aspect looks nice do this.
CGSize size = image.size;
CGRect photoFrame;
if (size.width > size.height)
{
// Landscape
CGFloat scaleFactor = 320 / size.width;
photoFrame = CGRectMake(0, 0, 320, size.height*scaleFactor);
}
else
{
// Portrait
CGFloat scaleFactor = 320 / size.height;
photoFrame = CGRectMake(0, 0, size.width*scaleFactor, 320);
}
myPhotoImageView.frame = photoFrame;

Copy partial screenshot to Pasteboard

So, the code to copy part of my screen to the pasteboard works because it was successfully coping it to my photo album. But, I want to be able to paste the partial screenshot into a new SMS message. I know it will have to be done manually (long hold on message and Paste), but it either pasted nothing, or does not have the Paste option (as it's saving it as a String). The middle portion of the code is the part I'm struggling with. Any help would be great. I've changed the forPasteboardType to "image" but that does not work either.
//Capture part of Screen Shot
UIGraphicsBeginImageContext(self.view.bounds.size);
CGContextRef c = UIGraphicsGetCurrentContext();
CGContextTranslateCTM(c, 0, 98); //
[self.view.layer renderInContext:c];
UIImage *viewImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
//Send Screenshot to Pasteboard
UIPasteboard *pasteBoard = [UIPasteboard pasteboardWithName:UIPasteboardNameGeneral create:YES];
pasteBoard.persistent = YES;
NSData *data = UIImagePNGRepresentation(viewImage);
[pasteBoard setData:data forPasteboardType:(NSString *)kUTTypePNG];
/////// Open SMS
MFMessageComposeViewController *controller = [[[MFMessageComposeViewController alloc] init] autorelease];
if([MFMessageComposeViewController canSendText])
{
controller.body = #"Hello from me, paste image here -->";
controller.recipients = [NSArray arrayWithObjects:#"123456789", nil];
controller.messageComposeDelegate = self;
[self presentModalViewController:controller animated:YES];
}
////// End SMS
}
//Capture part of Screen Shot
UIGraphicsBeginImageContext(self.view.bounds.size);
CGContextRef c = UIGraphicsGetCurrentContext();
CGContextTranslateCTM(c, 0, 98); //
[self.view.layer renderInContext:c];
UIImage *viewImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
//Send Screenshot to Pasteboard
UIPasteboard *pasteBoard = [UIPasteboard pasteboardWithName:UIPasteboardNameGeneral create:YES];
pasteBoard.persistent = YES;
NSData *data = UIImagePNGRepresentation(viewImage);
[pasteBoard setData:data forPasteboardType:(NSString *)kUTTypePNG];
NSString *stringURL = #"sms:";
NSURL *url = [NSURL URLWithString:stringURL];
[[UIApplication sharedApplication] openURL:url];

Get UIImage from the CALayer attached to AVPlayer (extract frame from video playing)

I play a video with AVPlayer. It works ok.
Now I want to get a UIImage from the video playing (when I push a button for the moment).
Attached to my AVPlayer there is a CALayer that is used to display video on my UIView.
My idea is to get an UIImage from CALayer during video is playing.
I do this with code from another question:
UIImage from CALayer - iPhone SDK
However my UIImage is empty. The resolution is good but it is but fully white !!!
It seems that video doesn't write the contents of my CALayer.
Someone can help me?
Thanks
I couldn't get Meet's solution to work for me, but it got me thinking in the right direction.
Below is the code that I ended up using in my project. The method screenshotFromPlayer:maximumSize: accepts an instance of an AVPlayer from which to take a screenshot, and a CGSize that will be the returned image's maximum size.
- (UIImage *)screenshotFromPlayer:(AVPlayer *)player maximumSize:(CGSize)maxSize {
CMTime actualTime;
NSError *error;
AVAssetImageGenerator *generator = [[AVAssetImageGenerator alloc] initWithAsset:player.currentItem.asset];
// Setting a maximum size is not necessary for this code to
// successfully get a screenshot, but it was useful for my project.
generator.maximumSize = maxSize;
CGImageRef cgIm = [generator copyCGImageAtTime:player.currentTime
actualTime:&actualTime
error:&error];
UIImage *image = [UIImage imageWithCGImage:cgIm];
CFRelease(cgIm);
if (nil != error) {
NSLog(#"Error making screenshot: %#", [error localizedDescription]);
NSLog(#"Actual screenshot time: %f Requested screenshot time: %f", CMTimeGetSeconds(actualTime),
CMTimeGetSeconds(self.recordPlayer.currentTime));
return nil;
}
return image;
}
Note also that one could use the method generateCGImagesAsynchronouslyForTimes:completionHandler: instead of copyCGImageAtTime:actualTime:error: (on the instance of AVAssetImageGenerator) to perform the image generation asynchronously.
This code sample generates a screenshot at the AVPlayer's currentTime, but any time could be used instead.
The code to get image from avplayer.
- (UIImage *)currentItemScreenShot
{
AVPlayer *abovePlayer = [abovePlayerView player];
CMTime time = [[abovePlayer currentItem] currentTime];
AVAsset *asset = [[[abovePlayerView player] currentItem] asset];
AVAssetImageGenerator *imageGenerator = [[AVAssetImageGenerator alloc] initWithAsset:asset];
if ([imageGenerator respondsToSelector:#selector(setRequestedTimeToleranceBefore:)] && [imageGenerator respondsToSelector:#selector(setRequestedTimeToleranceAfter:)]) {
[imageGenerator setRequestedTimeToleranceBefore:kCMTimeZero];
[imageGenerator setRequestedTimeToleranceAfter:kCMTimeZero];
}
CGImageRef imgRef = [imageGenerator copyCGImageAtTime:time
actualTime:NULL
error:NULL];
if (imgRef == nil) {
if ([imageGenerator respondsToSelector:#selector(setRequestedTimeToleranceBefore:)] && [imageGenerator respondsToSelector:#selector(setRequestedTimeToleranceAfter:)]) {
[imageGenerator setRequestedTimeToleranceBefore:kCMTimePositiveInfinity];
[imageGenerator setRequestedTimeToleranceAfter:kCMTimePositiveInfinity];
}
imgRef = [imageGenerator copyCGImageAtTime:time actualTime:NULL error:NULL];
}
UIImage *image = [[UIImage alloc] initWithCGImage:imgRef];
CGImageRelease(imgRef);
[imageGenerator release];
return [image autorelease];
}
set [imageGenerator setRequestedTimeToleranceBefore:kCMTimeZero] and [imageGenerator setRequestedTimeToleranceAfter:kCMTimeZero] if you need precise time.
Try to get the image from the video file at specified instance using the AVAssetImageGenerator:
AVURLAsset *asset=[[AVURLAsset alloc] initWithURL:[NSURL fileURLWithPath:[info objectForKey:#"UIImagePickerControllerReferenceURL"]] options:nil];
AVAssetImageGenerator *generator = [[AVAssetImageGenerator alloc] initWithAsset:asset];
generator.appliesPreferredTrackTransform=TRUE;
[asset release];
CMTime thumbTime = CMTimeMakeWithSeconds(0,30);
AVAssetImageGeneratorCompletionHandler handler = ^(CMTime requestedTime, CGImageRef im, CMTime actualTime, AVAssetImageGeneratorResult result, NSError *error){
if (result != AVAssetImageGeneratorSucceeded) {
}
UIImage *thumbImg = [[UIImage imageWithCGImage:im] retain];
[generator release];

Resources