Want value of variable "fileName" - ios

I have following method and code for getting image path,
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
NSURL *imageURL = [info valueForKey:UIImagePickerControllerReferenceURL];
ALAssetsLibraryAssetForURLResultBlock resultblock = ^(ALAsset *myasset)
{
ALAssetRepresentation *representation = [myasset defaultRepresentation];
fileName = [representation filename];
NSLog(#"fileName : %#",fileName);
};
ALAssetsLibrary* assetslibrary = [[ALAssetsLibrary alloc] init];
[assetslibrary assetForURL:imageURL
resultBlock:resultblock
failureBlock:nil];
UIImage *chosenImage = info[UIImagePickerControllerEditedImage];
self.profileImg.image = chosenImage;
[picker dismissViewControllerAnimated:YES completion:NULL];
profileImg.hidden = NO;
}
Now I want the value of fileName in another method that is,
- (IBAction)registerBtn:(UIButton *)sender {
NSLog(#"fileName path = %#", fileName);
}
In log result I get "null"
In my .h file I have implement the fileName variable.
So how can I get the value of this variable?

Your registerBtn method must be get called after you completely pick the image(i.e. your didFinishPickingMediaWithInfo`) get called.
Second thing if you just want to set unique name to your image then you should use time stamp.
You can get metadata of picked image in didFinishPickingMediaWithInfo like,
NSDictionary *metadata = info[UIImagePickerControllerMediaMetadata];
NSLog(#"%#", metadata);
then from meradata dictionary you can fetch value of DateTimeOriginal which will give pick date of media.

Related

Cant get start and end editing time in UIImagePickerController didFinishPickingMediaWithInfo:

I use UIImagePickerController to edit video and cut it,
I create it like this:
UIImagePickerController *imagePicker = [[UIImagePickerController alloc] init];
imagePicker.delegate = self;
[imagePicker setVideoQuality:UIImagePickerControllerQualityType640x480];
imagePicker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
imagePicker.mediaTypes = #[(__bridge NSString *)kUTTypeMovie, (__bridge NSString *)kUTTypeVideo, (__bridge NSString *)kUTTypeMPEG4];
imagePicker.allowsEditing = YES;
[self.navigationController presentViewController:imagePicker animated:YES completion:nil];
but unfortunately in delegate method that is called I cant get start and end editing time - to save edited video:
-(void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary<NSString *,id> *)info {
[picker dismissViewControllerAnimated:YES completion:^{
}];
NSString *type = [info objectForKey:UIImagePickerControllerMediaType];
if ([type isEqualToString:(NSString *)kUTTypeVideo] ||
[type isEqualToString:(NSString *)kUTTypeMovie]) { // movie != video
NSURL *videoURL = [info objectForKey:UIImagePickerControllerMediaURL];
NSNumber *start = [info objectForKey:#"_UIImagePickerControllerVideoEditingStart"];
NSNumber *end = [info objectForKey:#"_UIImagePickerControllerVideoEditingEnd"];
}
in my case start and end is nil. I have no idea how to get this information. Could you please advice how to get it?
Thank you in advance for any help.
I just check your code and run and i found that _UIImagePickerControllerVideoEditingStart and _UIImagePickerControllerVideoEditingEnd return only captured video from camera but if you are select video from your PhotoLibrary you did not get this two key in info dictionary:
If you are using imagePicker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary; then you will get following info dictionary log:
UIImagePickerControllerMediaType = "public.movie";
UIImagePickerControllerMediaURL = "file:///private/var/mobile/Containers/Data/Application/BCBE6A30-1A92-41BB-8734-BFF052E416DE/tmp/trim.59737F15-FC2A-4EB7-89AE-DF3831089657.MOV";
UIImagePickerControllerReferenceURL = "assets-library://asset/asset.MOV?id=87E3E50A-1DBF-449F-8BE3-AB36E718D82C&ext=MOV";
If you are using imagePicker.sourceType = UIImagePickerControllerSourceTypeCamera; then you will get following info dictionary log:
UIImagePickerControllerMediaType = "public.movie";
UIImagePickerControllerMediaURL = "file:///private/var/mobile/Containers/Data/Application/611D33A4-61F4-4CD0-934D-C0EFF82B75AC/tmp/capture/capturedvideo.MOV";
"_UIImagePickerControllerVideoEditingEnd" = "2.360877976190476";
"_UIImagePickerControllerVideoEditingStart" = "1.360505952380952";
So at the end with UIImagePickerControllerSourceTypePhotoLibrary UIImagePickerController wont provide a _UIImagePickerControllerVideoEditingStart and _UIImagePickerControllerVideoEditingEnd key. so you can get its duration by using AVURLAsset like following code that assume start Time is 0 and end time is full duration.
AVURLAsset *Asset = [AVURLAsset assetWithURL:videoURL];
CMTime duration = [Asset duration];
int fullduration = ceil(duration.value/duration.timescale);

Image Metadata from Action Extension

Usually when i want to read some image metadata in iOS i use imagePickerController to choose the image and Photos Framework and imagePickerController:didFinishPickingMediaWithInfo:
to get image info and extract the metadata like this
-(void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary<NSString *,id> *)info{
UIImagePickerControllerSourceType pickerType = picker.sourceType;
if(pickerType == UIImagePickerControllerSourceTypePhotoLibrary)
{
NSURL *url = [info objectForKey:UIImagePickerControllerReferenceURL];
PHFetchResult *fetchResult = [PHAsset fetchAssetsWithALAssetURLs:#[url,] options:nil];
PHAsset *asset = fetchResult.firstObject;
[self metaDataFromPhotoLibrary:asset];
[self dismissViewControllerAnimated:YES completion:NULL];
}
}
-(void)metaDataFromPhotoLibrary:(PHAsset*)asset{
// NSLog(#"Start metadata");
PHContentEditingInputRequestOptions *options = [[PHContentEditingInputRequestOptions alloc] init];
options.networkAccessAllowed = YES; //download asset metadata from iCloud if needed
[asset requestContentEditingInputWithOptions:options completionHandler:^(PHContentEditingInput *contentEditingInput, NSDictionary *info) {
CIImage *fullImage = [CIImage imageWithContentsOfURL:contentEditingInput.fullSizeImageURL];
NSDictionary *metadata = fullImage.properties;
NSMutableDictionary *imageMetadata = nil;
imageMetadata = [[NSMutableDictionary alloc] initWithDictionary:metadata];
NSString *dateString = metadata [#"{TIFF}"] [#"DateTime"];
NSString *latitude = metadata [#"{GPS}"][#"Latitude"];
NSString *longitude = metadata [#"{GPS}"][#"Longitude"];
//etc etc etc
}
But can't do the same thing from an Action Extension
in the extension code i use a code like this to get the selected image
- (void)viewDidLoad {
[super viewDidLoad];
// Get the item[s] we're handling from the extension context.
// For example, look for an image and place it into an image view.
// Replace this with something appropriate for the type[s] your extension supports.
BOOL imageFound = NO;
for (NSExtensionItem *item in self.extensionContext.inputItems) {
for (NSItemProvider *itemProvider in item.attachments) {
if ([itemProvider hasItemConformingToTypeIdentifier:(NSString *)kUTTypeImage]) {
// This is an image. We'll load it, then place it in our image view.
__weak UIImageView *immagine = self.immagine;
[itemProvider loadItemForTypeIdentifier:(NSString *)kUTTypeImage options:nil completionHandler:^(UIImage *image, NSError *error) {
if(image) {
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
[immagine setImage:image];
}];
}
}];
imageFound = YES;
break;
}
}
if (imageFound) {
// We only handle one image, so stop looking for more.
break;
}
}
}
Using UIImagePNGRepresentation or UIImageJPEGRepresentation i lost many metadata and i can read only a few data !
How can i get all image metadata from the image selected from action Extension ?
Thank you so mush
Note: i 've found some app in the AppsStore that read all metadata dictionary from extension , so there must be a solution for my problem !
Thank you again
Vanni

App is terminated due to memory pressure while taking multiple pictures

I have tried a lot of solutions provided on other questions which were same as mine but nothing could help me much.
Let me tell you what am I doing. I have a collection view. In that I will display some images which will be captured by camera. I am capturing multiple pictures at a time. All the pictures which I have taken, the address of those images will first save into database and then those images will be displayed in collection view.
Now what happens, when I click 40-50 images at a time, the app is crashed and xcode displays a message something like "app is terminating due to memory pressure". Also I am getting too many memory warnings in logs but actually I was neglecting them.
First I am writing code for taking multiple pictures-
- (void)imagePickerController:(UIImagePickerController *)picker
didFinishPickingMediaWithInfo:(NSDictionary *)info
{
if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]) {
//Get Image URL from Library
NSString *mediaType = [info objectForKey:UIImagePickerControllerMediaType];
NSURL *urlPath = [info valueForKey:UIImagePickerControllerReferenceURL];
if (segmentControl.selectedSegmentIndex != 1) {
[picker dismissViewControllerAnimated:YES completion:nil];
}
if (segmentControl.selectedSegmentIndex == 2) {
[self insertPicToDB:urlPath];
}else{
__block NSURL *url;
if ([mediaType isEqualToString:(NSString *)kUTTypeImage]) {
UIImage *image = [info objectForKey:UIImagePickerControllerOriginalImage];
ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init];
// Request to save the image to camera roll
[library writeImageToSavedPhotosAlbum:[image CGImage] orientation:(ALAssetOrientation)[image imageOrientation] completionBlock:^(NSURL *assetURL, NSError *error){
if (error) {
} else {
url = assetURL;
[self insertPicToDB:url];
}
}];
}
}
}
}
After while taking each picture, I am saving image url in db and then at the same time trying to reload the collection view as well.
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{
static NSString *identifier = #"Cell";
collectionCell = (CollectionCell *)[_collectionView dequeueReusableCellWithReuseIdentifier:identifier forIndexPath:indexPath];
collectionCell.imageView = (UIImageView*)[collectionCell viewWithTag:100];
collectionCell.imageView.image = [UIImage imageNamed:#"placeholder.png"];
NSString *fileURL = [[recipeImages[indexPath.section] objectAtIndex:indexPath.item] objectForKey:#"FileUrl"];
collectionCell.imagURL = fileURL;
if ([fileURL hasPrefix:#"assets-library"]) {
[self getImageFromURL:[NSURL URLWithString:fileURL] :indexPath];
}else{
fileURL = [NSString stringWithFormat:#"%#/uploads/thumbnail/%#",[[HttpClient sharedInstance]getBaseURLString],[[fileURL componentsSeparatedByString:#"\\"]lastObject]];
[collectionCell.imageView setImageWithURL:[NSURL URLWithString:fileURL] placeholderImage:[UIImage imageNamed:#"placeholder.png"]];
}
return collectionCell;
}
So the condition is, I will keep clicking the pictures and the pictures will be saving in background.
And the definition of method "getImageFromURL" is-
-(void)getImageFromURL:(NSURL*)yourUrl :(NSIndexPath*)indexPath{
ALAssetsLibraryAssetForURLResultBlock resultblock = ^(ALAsset *myasset)
{
ALAssetRepresentation *rep = [myasset defaultRepresentation];
#autoreleasepool {
CGImageRef iref = [rep fullScreenImage];
if (iref) {
UIImage *image = [UIImage imageWithCGImage:iref];
dispatch_async(dispatch_get_main_queue(), ^{
collectionCell = (CollectionCell*)[_collectionView cellForItemAtIndexPath:indexPath];
if (collectionCell) {
NSData *imageData = UIImageJPEGRepresentation(image, 0.1);
UIImage *compressedImage = [UIImage imageWithData:imageData];
collectionCell.imageView.image = compressedImage;
}else{
collectionCell.imageView.image = nil;
}
[collectionCell.imageView setNeedsDisplay];
[collectionCell setNeedsDisplay];
});
iref = nil;
}
}
};
ALAssetsLibraryAccessFailureBlock failureblock = ^(NSError *myerror)
{
NSLog(#"Can't get image - %#",[myerror localizedDescription]);
};
ALAssetsLibrary* assetslibrary = [[ALAssetsLibrary alloc] init];
[assetslibrary assetForURL:yourUrl
resultBlock:resultblock
failureBlock:failureblock];
}
I am also trying to compress the images while fetching in collection view. So I don't think that it is crashing because of collection view. What can be the reason? Is it because of I am using ALAssetsLibrary or something else?
I was debugging it in iPhone 4S with iOS version 7.1.1.
Thanks in advance.

upload photo from my iphone gallery

I am working on an application that needs its user to upload a photo for him, using iphone, how can i implement this : when click on the image in my personal information page, the gallery is opend to choose a photo. when the photo is chosen it must appear instead of the previous one (at first it is the default pic). Notice that, the path of this photo or the photo itself(i do not know) must be stored in the DataBase for the next login. Moreover, this photo must be transferred to the server in order to be shown on the website when the same user login on the web.
I did it using the following code, i can choose a photo but when i save the path i could not load the pic again. it is a white box !! there is no photo !!
-(void) pickPhoto
{
UIImagePickerController *picker ;
picker = [[UIImagePickerController alloc] init];
picker.delegate = self;
if([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypePhotoLibrary])
{
picker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
}
else
{
picker.sourceType = UIImagePickerControllerSourceTypeSavedPhotosAlbum;
}
[self presentViewController:picker animated:YES completion:nil];
}
-(void) imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
UIImage *img = [info objectForKey:UIImagePickerControllerEditedImage];
if(!img)
img = [info objectForKey:UIImagePickerControllerOriginalImage];
NSString *docDirPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
NSString *filePath = [docDirPath stringByAppendingPathComponent:#"myImage.png"];
NSLog (#"File Path = %#", filePath);
UIButton *btn = (UIButton *)[self.tableView viewWithTag:2013];
[btn setBackgroundImage:img forState:UIControlStateNormal];
database= [[connectToDB alloc] init];
[database setDelegate:self];
[database saveUserPic:filePath ForUser:user.userId];
[self dismissViewControllerAnimated:YES completion:nil];
}
now to load the pic :
UIImage *img;
if(pic != nil)
img=[UIImage imageWithContentsOfFile:pic];
else
img= [UIImage imageNamed:#"business_userL.png"];
Any Help will be appreciated.!
UIImagePickerControllerReferenceURL will return reference to local storage of your selected image.
NSURL* localUrl = (NSURL *)[info valueForKey:UIImagePickerControllerReferenceURL];
Now you can save this url in your database.
To retrieve the image : display image from URL retrieved from ALAsset in iPhone

Saving picture from app

I am trying to make my application open the camera app to take a save pictures.
from my application i am launching the camera application to take a picture with the following code:
-(IBAction)TakePhoto:(id)sender {
picker = [[UIImagePickerController alloc] init];
picker.delegate = self;
[picker setSourceType:UIImagePickerControllerSourceTypeCamera];
[self presentViewController:picker animated:YES completion:NULL];
[picker release];
//save image??:
//UIImageWriteToSavedPhotosAlbum(UIImage *image, id completionTarget, SEL completionSelector, void *contextInfo);
}
-(void) imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
image = [info objectForKey:UIImagePickerControllerOriginalImage];
[self dismissViewControllerAnimated:YES completion:NULL];
}
-(void)imagePickerControllerDidCancel:(UIImagePickerController *)picker {
[self dismissViewControllerAnimated:YES completion:NULL];
}
My problem is that once the button is pressed, the camera comes out and allows me to take a picture. Once the picture is take, the image is shown and i have the option to "retake" or "use". My issue is that if i click "use" the image is not saved to the camera roll. Is there a possibility to save the image and eventually change the "use" button to say "save"?
Thank you for you help!
The photo isn't being saved because you never actually added the code to save the image to the didFinishPickingMediaWithInfo: delegate method. All you have to do is add the line that you commented out in TakePhoto: to this function and you will be able to save the photo to the camera roll. E.x:
-(void) imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
image = [info objectForKey:UIImagePickerControllerOriginalImage];
UIImageWriteToSavedPhotosAlbum(image, nil, nil, NULL);
[self dismissViewControllerAnimated:YES completion:NULL];
}
static NSDateFormatter* dateFormatter;
- (NSString*) generateNameWithExtension: (NSString*) extension
{
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
dateFormatter = [[NSDateFormatter alloc] init];
dateFormatter.dateFormat = #"yyyyMMddHHmmssSSS";
});
NSDate* now = [NSDate date];
NSString* string = [dateFormatter stringFromDate:now];
string = [NSString stringWithFormat:#"%#.%#",string,extension];
return string;
}
- (NSString*) saveImage: (UIImage*) image WithExtension: (NSString*) extension
{
extension = [extension lowercaseString];
NSData* data;
if ([extension isEqualToString:#"png"])
{
data = UIImagePNGRepresentation(image);
}else if ([extension isEqualToString:#"jpg"]||[extension isEqualToString:#"jpeg"])
{
data = UIImageJPEGRepresentation(image, 1.0);
}else{
NSLog(#"Error save local image, Extension: (%#) is not recognized, use (PNG/JPG)",extension);
return nil;
}
NSString* imageName = [self generateNameWithExtension:extension];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documents = [paths objectAtIndex:0];
NSString *finalPath = [documents stringByAppendingPathComponent:imageName];
[data writeToFile:finalPath options:NSAtomicWrite error:nil];
return finalPath;
}
This code save image in folder you app. You can later use it: [UIImage imageWithContentsOfFile:finalPath]

Resources