When I tried to copy a video from album to app using UIImagePickerController, the video is compressed.
When the video imported via Photos app on Mac, the ten-second long video is:
1920x1280 ~22MB
After the video is imported into app, then copied via iTunes Sharing, the compressed video is:
1280x720 ~6.3MB
How can I import video into app in original resolution and quality?
Code:
- (void)importVideo:(id)sender {
UIImagePickerController *imagePickerController = [[UIImagePickerController alloc] init];
imagePickerController.sourceType = UIImagePickerControllerSourceTypeSavedPhotosAlbum;
imagePickerController.mediaTypes = [[NSArray alloc] initWithObjects: (NSString *) kUTTypeMovie, nil];
imagePickerController.allowsEditing = YES;
imagePickerController.delegate = self;
[self presentViewController:imagePickerController animated:YES completion:nil];
}
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
NSString *mediaType = [info objectForKey: UIImagePickerControllerMediaType];
[self dismissViewControllerAnimated:YES completion:nil];
if (CFStringCompare((__bridge_retained CFStringRef)mediaType, kUTTypeMovie, 0) == kCFCompareEqualTo) {
NSURL *videoURL = [info objectForKey:UIImagePickerControllerMediaURL];
NSData *videoData = [NSData dataWithContentsOfURL:videoURL];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *folder = [paths firstObject];
NSString *filename = [folder stringByAppendingPathComponent:self.uniqueFilename];
BOOL success = [videoData writeToFile:filename atomically:NO];
NSLog(#"Write to file %#", success ? #"OK" : #"Error");
}
}
Once a PHAsset is obtained via GMImagePicker, it can be saved by:
for (PHAsset *asset in assetArray) {
PHVideoRequestOptions *options = [[PHVideoRequestOptions alloc] init];
options.version = PHVideoRequestOptionsVersionOriginal;
[[PHImageManager defaultManager] requestAVAssetForVideo:asset
options:options
resultHandler:^(AVAsset *avAsset, AVAudioMix *audioMix, NSDictionary *info) {
if ([avAsset isKindOfClass:[AVURLAsset class]]) {
NSURL *videoURL = [(AVURLAsset *) avAsset URL];
NSData *videoData = [NSData dataWithContentsOfURL:videoURL];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *folder = [paths firstObject];
NSString *filename = [folder stringByAppendingPathComponent:#"foo.mp4"];
[videoData writeToFile:filename atomically:NO];
}
}];
}
Related
I am currently working IOS application which can be used to upload multiple image to ftp server. I am using GoldRaccoon class file. I have selected 5 images, but it only uploads the last image.
- (void)zcImagePickerController:(ZCImagePickerController *)imagePickerController didFinishPickingMediaWithInfo:(NSArray *)info {
[self dismissPickerView];
NSString *fullPath;
for (NSDictionary *imageDic in info) {
UIImageView *imageView = [[UIImageView alloc] initWithImage:[imageDic objectForKey:UIImagePickerControllerOriginalImage]];
imageView.contentMode = UIViewContentModeScaleAspectFit;
[arrImageView addObject:imageView];
UIImage *image1 = [imageDic objectForKey:#"UIImagePickerControllerOriginalImage"];
NSData * imageData1 = UIImageJPEGRepresentation(image1,100); //convert image into .png format.
NSFileManager * fileManager = [NSFileManager defaultManager];//create instance of NSFileManager
NSArray * paths1 = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); //create an array and store result of our search for the documents directory in it
NSString * documentsDirectory = [paths1 objectAtIndex:0]; //create NSString object, that holds our exact path to the documents directory
fullPath = [documentsDirectory stringByAppendingPathComponent:[NSString stringWithFormat:#"%#.jpg",image1]]; //add our image to the path
// NSString *str=[NSString stringWithFormat:#"%#.jpg",image1];
[fileManager createFileAtPath:fullPath contents:imageData1 attributes:nil]; //finally save the image
[arrvalue addObject:fullPath];
NSURL *imageURL = [imageDic valueForKey:UIImagePickerControllerReferenceURL];
ALAssetsLibraryAssetForURLResultBlock resultblock =^(ALAsset *myasset)
{
ALAssetRepresentation *representation = [myasset defaultRepresentation];
NSString *fileName = [representation filename];
// Send WebService
// [arrName addObject:fileName];
[self sendImage:fileName :fullPath];
};
ALAssetsLibrary* assetslibrary = [[ALAssetsLibrary alloc] init] ;
[assetslibrary assetForURL:imageURL resultBlock:resultblock failureBlock:nil];
}
}
I've a question in mind that driving me crazy. I've searched a lot to solve it, but all the answers that I found were old and not helped.
I'm currently working on application with that uses UIImagePickerControllerDelegate and with didFinishPickingMediaWithInfo I want to save the selected image to application folder.
Until now I'm able to select the image with this;
- (IBAction)btnPressed:(UIButton *)sender
{
if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeSavedPhotosAlbum])
{
UIImagePickerController *imgPicker = [[UIImagePickerController alloc] init];
imgPicker.delegate = self;
imgPicker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
imgPicker.mediaTypes = [NSArray arrayWithObject:(NSString *)kUTTypeImage];
imgPicker.allowsEditing = NO;
[self presentViewController:imgPicker animated:YES completion:nil];
}
}
but couldn't save it to application using didFinishPickingMediaWithInfo;
-(void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
NSString *mediaType = [info objectForKey:UIImagePickerControllerMediaType];
[self dismissViewControllerAnimated:YES completion:nil];
if ([mediaType isEqualToString:(NSString *) kUTTypeImage])
{
UIImage *image = [info objectForKey:UIImagePickerControllerOriginalImage];
//Assigning the selected image to imageView to see on UI side.
imageViewerImage.image = image;
}
}
I wonder what should be the part after this point.
I appreciate any help that you can provide.
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
[self dismissViewControllerAnimated:YES completion:NULL];
UIImage* image;
if([[info valueForKey:#"UIImagePickerControllerMediaType"] isEqualToString:#"public.image"])
{
image = [info valueForKey:#"UIImagePickerControllerOriginalImage"];
NSString *stringPath = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)objectAtIndex:0]stringByAppendingPathComponent:#"New Folder"];
// New Folder is your folder name
NSError *error = nil;
if (![[NSFileManager defaultManager] fileExistsAtPath:stringPath])
[[NSFileManager defaultManager] createDirectoryAtPath:stringPath withIntermediateDirectories:NO attributes:nil error:&error];
NSString *fileName = [stringPath stringByAppendingFormat:#"/image.jpg"];
NSData *data = UIImageJPEGRepresentation(image, 1.0);
[data writeToFile:fileName atomically:YES];
}
}
Try this code. It may helps you. :)
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
imgViewProfile.image = info[UIImagePickerControllerEditedImage];
[picker dismissViewControllerAnimated:YES completion:^{ }];
// ------ Now save this image to document directory by getting its path
}
Save an UIImage to the to Documentsfolder like this:
UIImage* myUIImage = ...
NSData *pngData = UIImagePNGRepresentation(myUIImage);
//NSData *pngData = UIImageJPEGRepresentation(myUIImage,0.5); //alternative comressed jpg instead of png
NSString *filePath = [[self buildDocumentsPath] stringByAppendingPathComponent:#"pictureName.png"]; //Add the file name
[pngData writeToFile:filePath atomically:YES]; //Write the file
Get the path of the documents as a string:
- (NSString *)buildDocumentsPath{
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask, YES);
NSString *documentsPath = [paths objectAtIndex:0];
return documentsPath;
}
Just save the image in your app document directory :
// first find the path in which to save the image :
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *baseDir = [paths objectAtIndex:0];
// then save image as JPEG
NSString* filename = [baseDir stringByAppendingPathComponent:#"filename.jpg"];
[UIImageJPEGRepresentation(image, 1.0) writeToFile:jpgPath atomically:YES];
// or PNG
NSString* filename = [baseDir stringByAppendingPathComponent:#"filename.png"];
[UIImagePNGRepresentation(image) writeToFile:pngPath atomically:YES];
//In Your - (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingImage (UIImage *)image editingInfo:(NSDictionary *)editingInfo . Write this code
NSData *pngData = UIImagePNGRepresentation(image);
//This pulls out PNG data of the image you've captured. From here, you can write it to a file:
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsPath = [paths objectAtIndex:0]; //Get the docs directory
NSString *filePath = [documentsPath stringByAppendingPathComponent:#"image.png"]; //Add the file name
[pngData writeToFile:filePath atomically:YES]; //Write the file
I did that in my project:
-(void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info{
UIImage * imageDone = [info objectForKey:#"UIImagePickerControllerEditedImage"];
[self saveImage:imageDone];
[self.popover dismissPopoverAnimated:YES];
}
-(void)saveImage:(UIImage*)image{
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString * imgpath = [documentsDirectory stringByAppendingFormat:#"/media/img/"];
long x = arc4random() % 10000;
NSString * namePic = [NSString stringWithFormat:#"%lld%ld-photo.jpg", self.idToLoad.longLongValue, x];
NSString * stringName = [NSString stringWithFormat:#"%#%#", imgpath, namePic];
[UIImageJPEGRepresentation(image, 0.3) writeToFile:stringName atomically:YES];
}
I am using UIImagePickerController to record video, the problem is its recording the video in mov format for android compatibility.
I need to convert the video into mp4 format using below code the issue is its taking hell of a time for a 6 sec video it takes around 30 to 35 seconds.
Any solution that I can directly record the video in mp4 format or faster method would be of great help. Thanks in Advance
-(void)movToMp4:(NSURL *)videoURL{ // method for mov to mp4 conversion
AVURLAsset *avAsset = [AVURLAsset URLAssetWithURL:videoURL options:nil];
NSArray *compatiblePresets = [AVAssetExportSession exportPresetsCompatibleWithAsset:avAsset];
if ([compatiblePresets containsObject:AVAssetExportPresetLowQuality])
{
AVAssetExportSession *exportSession = [[AVAssetExportSession alloc]initWithAsset:avAsset presetName:AVAssetExportPresetPassthrough];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString* videoPath = [NSString stringWithFormat:#"%#/xyz.mp4", [paths objectAtIndex:0]];
exportSession.outputURL = [NSURL fileURLWithPath:videoPath];
exportSession.outputFileType = AVFileTypeMPEG4;
[exportSession exportAsynchronouslyWithCompletionHandler:^{
switch ([exportSession status]) { // switch case to get completion case where i put my delegate
return;
break;
case AVAssetExportSessionStatusCompleted: {
[self.delegate mp4Response:videoPath];
break;
}
}
}
}];
}
}
Yes because it takes time when you load video from library / album using AVURLAsset.
So you need to use block here to load video from library.
Also line
[self.delegate mp4Response:videoPath];
Which in a completion block - It should be on main thread.
Follow this approach:
UIImagePickerController delegate method to get videos from library.
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
NSURL *localUrl = (NSURL *)[info valueForKey:UIImagePickerControllerMediaURL];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString* videoPath = [NSString stringWithFormat:#"%#/xyz.mp4", [paths objectAtIndex:0]];
NSURL *outputURL = [NSURL fileURLWithPath:videoPath];
[self convertVideoToLowQuailtyWithInputURL:localUrl outputURL:outputURL handler:^(AVAssetExportSession *exportSession)
{
if (exportSession.status == AVAssetExportSessionStatusCompleted) {
NSLog(#"Capture video complete");
[self performSelectorOnMainThread:#selector(doneCompressing) withObject:nil waitUntilDone:YES];
}
}];
[self dismissViewControllerAnimated:YES completion:nil];
}
- (void)convertVideoToLowQuailtyWithInputURL:(NSURL*)inputURL outputURL:(NSURL*)outputURL handler:(void (^)(AVAssetExportSession*))handler {
[[NSFileManager defaultManager] removeItemAtURL:outputURL error:nil];
AVURLAsset *asset = [AVURLAsset URLAssetWithURL:inputURL options:nil];
AVAssetExportSession *exportSession = [[AVAssetExportSession alloc] initWithAsset:asset presetName:AVAssetExportPresetPassthrough];
exportSession.outputURL = outputURL;
exportSession.outputFileType = AVFileTypeMPEG4;
[exportSession exportAsynchronouslyWithCompletionHandler:^(void) {
handler(exportSession);
}];
}
In didFinishPickingMediaWithInfo method observed this line:
[self performSelectorOnMainThread:#selector(doneCompressing) withObject:nil waitUntilDone:YES];
It will call a one more method doneCompressing in main thread (in foreground). So that you can call delegate method in doneCompressing. And this will reduce time.
- (void) doneCompressing {
[self.delegate mp4Response:videoPath];
}
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
NSLog(#"file info = %#", info);
NSString *pickedType = [info objectForKey:#"UIImagePickerControllerMediaType"];
NSData *videoData;
if ([pickedType isEqualToString:#"public.movie"]){
NSURL *videoUrl=(NSURL*)[info objectForKey:UIImagePickerControllerMediaURL];
videoData = [NSData dataWithContentsOfURL:videoUrl];
}
[self dismissViewControllerAnimated:YES completion:^{
//
[self writeFileData:videoData];
}];
}
// to get path of document directory
- (NSString *)applicationDocumentsDirectory
{
// return [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
return documentsDirectory;
}
- (void) writeFileData:(NSData *)fileData{
float size = fileData.length / (1024 * 1024);
NSString *fileName = nil;
NSString *strPath = nil;
NSString *documentsDirectory = [self applicationDocumentsDirectory];
double CurrentTime = CACurrentMediaTime();
fileName = [NSString stringWithFormat:#"%d.mp4",(int)CurrentTime];
strPath = [documentsDirectory stringByAppendingPathComponent:fileName];
NSFileManager *filemanager=[[NSFileManager alloc] init];
NSError *er;
if (![filemanager fileExistsAtPath:documentsDirectory]) {
[filemanager createDirectoryAtPath:documentsDirectory withIntermediateDirectories:YES attributes:nil error:&er];
NSLog(#"error in folder creation = %#", er);
}
NSLog(#"size of data = %lu", (unsigned long)[fileData length]);
BOOL saved = [fileData writeToFile:strPath atomically:YES];
if (saved) {
NSURL *videoURL = [NSURL URLWithString:strPath];
// now u can handle mp4 video from videoURL
}
else
return;
}
when i NSLog BOOL success = [videoDataDecrypted writeToFile:videopath atomically:NO];
this statement it always diplays No
- (void) imagePickerController: (UIImagePickerController *) picker
didFinishPickingMediaWithInfo: (NSDictionary *) info {
NSString *mediaType = [info objectForKey: UIImagePickerControllerMediaType];
picker.allowsEditing = NO;
[self dismissModalViewControllerAnimated:NO];
// Handle a movie capture
if (CFStringCompare ((__bridge_retained CFStringRef)mediaType, kUTTypeMovie, 0)
== kCFCompareEqualTo)
{
NSString *moviePath = [[info objectForKey:
UIImagePickerControllerMediaURL] path];
NSURL *movieURL1 = [NSURL URLWithString:moviePath];
NSLog(#"moviePath %#",moviePath);
NSData *videoDataEncrypted = [NSData dataWithContentsOfURL:movieURL1];
[videoDataEncrypted AES256EncryptWithKey:#"123"];
NSData *videoDataDecrypted = [videoDataDecrypted AES256DecryptWithKey:#"123"];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,
NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init];
[dateFormat setDateFormat:#"dd-MM-yyyy HH:mm:SS"];
NSDate *now = [[NSDate alloc] init];
NSString *theDate = [dateFormat stringFromDate:now];
NSString *dataPath = [documentsDirectory stringByAppendingPathComponent:#"Default Album"];
if (![[NSFileManager defaultManager] fileExistsAtPath:dataPath])
[[NSFileManager defaultManager] createDirectoryAtPath:dataPath
withIntermediateDirectories:NO
attributes:nil
error:nil];
NSString *videopath= [[NSString alloc] initWithString:[NSString
stringWithFormat:#"%#/%#.mov",documentsDirectory,theDate]];
BOOL success = [videoDataDecrypted writeToFile:videopath atomically:NO];
NSLog(#"Successs:::: %#", success ? #"YES" : #"NO");
NSLog(#"video path --> %#",videopath);
NSString* urlTextEscaped = [videopath
stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSURL *movieUrl2 = [NSURL fileURLWithPath:urlTextEscaped];
UIGraphicsBeginImageContext(CGSizeMake(1,1));
MPMoviePlayerViewController* theMovie =
[[MPMoviePlayerViewController alloc] initWithContentURL: movieUrl2];
UIGraphicsEndImageContext();
[self presentMoviePlayerViewControllerAnimated:theMovie];
// Register for the playback finished notification
[[NSNotificationCenter defaultCenter]
addObserver: self
selector: #selector(myMovieFinishedCallback:)
name: MPMoviePlayerPlaybackDidFinishNotification
object: theMovie];
}
}
Try this for store video,
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *dataPath = [documentsDirectory stringByAppendingPathComponent:#"Default Album"];
if (![[NSFileManager defaultManager] fileExistsAtPath:dataPath])
[[NSFileManager defaultManager] createDirectoryAtPath:dataPath withIntermediateDirectories:NO attributes:nil error:nil];
NSString *videopath = [NSString stringWithFormat:#"%#/%#.mov",dataPath,theDate];
[videoDataDecrypted writeToFile:videopath atomically:YES];
try this way...
#define DOCUMENTS_FOLDER [NSHomeDirectory() stringByAppendingPathComponent:#"Documents"]
//Open Camera
if ([UIImagePickerController isSourceTypeAvailable:
UIImagePickerControllerSourceTypeCamera])
{
UIImagePickerController *imagePicker = [[UIImagePickerController alloc] init];
imagePicker.delegate = self;
imagePicker.sourceType =UIImagePickerControllerSourceTypeCamera;
imagePicker.mediaTypes = [NSArray arrayWithObjects:(NSString *) kUTTypeMovie,nil];
imagePicker.allowsEditing = NO;
[self presentViewController:imagePicker animated:YES completion:nil];
}
#pragma mark - ImagePicker Controller Delegate
-(void)imagePickerController:(UIImagePickerController *)picker
didFinishPickingMediaWithInfo:(NSDictionary *)info
{
[self.popoverController dismissPopoverAnimated:true];
NSString *mediaType = [info objectForKey:UIImagePickerControllerMediaType];
[self dismissViewControllerAnimated:YES completion:nil];
NSString *f_name=[NSString stringWithFormat:#"%#/video1.mp4",DOCUMENTS_FOLDER];
NSURL *videoURL = [info objectForKey:UIImagePickerControllerMediaURL];
// self.movieURL=info[UIImagePickerControllerMediaURL];
NSData *videoData = [NSData dataWithContentsOfURL:videoURL];
//NSString* imagePath = [documentsDirectory stringByAppendingPathComponent:imageName];
////NSLog(#"image path-%#",imagePath);
[videoData writeToFile:f_name atomically:YES];
}
I have written code to capture image from camera and i want to save that image in document directory. I have done the code but i think the image is not storing document directory. Because when i retrieve the images the camera images is not in documents directory,my code:
- (IBAction)takePhoto {
UIImagePickerController *picker = [[UIImagePickerController alloc] init];
picker.delegate = self;
picker.allowsEditing = YES;
picker.sourceType = UIImagePickerControllerSourceTypeCamera;
[self presentViewController:picker animated:YES completion:NULL];
}
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
UIImage *cameraImage = info[UIImagePickerControllerEditedImage];
self.tempView.image = cameraImage;
[_chosenImages addObject:_tempView.image];
[picker dismissViewControllerAnimated:YES completion:NULL];
}
id n = [array3 lastObject];
NSLog(#"The id is=%#",n);
NSError *error;
NSString *aDocumentsDirectory = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
NSString *dataPath = [aDocumentsDirectory stringByAppendingPathComponent:[NSString stringWithFormat:#"%#",n]];
[[NSFileManager defaultManager] createDirectoryAtPath:dataPath withIntermediateDirectories:NO attributes:nil error:&error];
NSInteger anIndex = 0;
for (UIImage *anImage in _chosenImages) {
NSString *anImageName = [NSString stringWithFormat:#"%d.png", anIndex++];
NSString *anImagePath = [NSString stringWithFormat:#"%#/%#", dataPath, anImageName];
NSLog(#"the path is=%#",anImagePath);
NSData *anImageData = UIImagePNGRepresentation(anImage);
[anImageData writeToFile:anImagePath atomically:YES];
// While fetching NSDocumentDirectory Path it will give in the array format. So instead of giving NSString you need to give NSArray.. check below code
// Try this
NSArray * aDocumentsDirectory = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *docPath = [aDocumentsDirectory objectAtIndex:0];
NSString *finaldocPath = [docPath stringByAppendingPathComponent:fileName];