After selecting a video using UIImagePickerController I can get the video's file size from its
[defaultRepresentation size].
However, if I enable the picker's trimming option, [defaultRepresentation size] returns the same file size as the original untrimmed video.
Does anyone have a method for retrieving the trimmed video's file size?
Much appreciated...
Yes, I should have included some code. Me bad.
What I'm trying to achieve is have the user choose and trim an existing video, then upload the trimmed version. I would like to have the trimmed version's file size in order to populate the progress bar during the upload. I would also like the trimmed version's duration.
The calling method is:
-(IBAction)selectVideoPressed:(id)sender
{
if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypePhotoLibrary])
{
UIImagePickerController *videoPicker = [[UIImagePickerController alloc] init];
[videoPicker setDelegate: self];
[videoPicker setSourceType:UIImagePickerControllerSourceTypePhotoLibrary];
[videoPicker setMediaTypes:[NSArray arrayWithObjects:(NSString *)kUTTypeMovie, nil]];
[videoPicker setVideoQuality:vvi.videoQuality];
[videoPicker setAllowsEditing:YES];
[videoPicker setModalTransitionStyle:gTransitionStyle];
[self presentViewController:videoPicker animated:YES completion:Nil];
}
}
The delegate method which fires after the user has trimmed and pressed Choose is:
-(void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
[vvi setRawSourceVideoFileURL:[info objectForKey:UIImagePickerControllerMediaURL]];
[vvi setSourceVideoURL:[info objectForKey:UIImagePickerControllerReferenceURL]];
ALAssetsLibrary *assetLibrary = [[ALAssetsLibrary alloc] init];
ALAssetsLibraryAssetForURLResultBlock resultBlock = ^(ALAsset *myAsset)
{
// Video metrics info.
[vvi setVideoDuration:[myAsset valueForProperty:ALAssetPropertyDuration]];
[vvi setVideoOrientation:[myAsset valueForProperty:ALAssetPropertyOrientation]];
NSDate *videoDate = [myAsset valueForProperty:ALAssetPropertyDate];
[vvi setVideoDateString:[videoDate descriptionWithLocale:[NSLocale currentLocale]]];
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:gShortDateFormat];
[vvi setShortVideoDateString:[dateFormatter stringFromDate:videoDate]];
ALAssetRepresentation *myAssetRepresentation = [myAsset defaultRepresentation];
[vvi setVideoAssetSize:[NSNumber numberWithLongLong:[myAssetRepresentation size]]];
NSLog(#"Duration:%#", vvi.videoDuration);
NSLog(#"Size:%#", vvi.videoAssetSize);
};
....
vvi is just my own custom class.
The two NSLog's return the duration and size of the original untrimmed video. The video pointed to with [vvi setRawSourceVideoFileURL:[info objectForKey:UIImagePickerControllerMediaURL]]; does return the properly trimmed video.
Thanks and much!
Something like this should take care finding the file size of a selected image or video returned from the UIImagePickerController
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
NSURL *videoUrl=(NSURL*)[info objectForKey:UIImagePickerControllerMediaURL];
//Error Container
NSError *attributesError;
NSDictionary *fileAttributes = [[NSFileManager defaultManager] attributesOfItemAtPath:[videoUrl path] error:&attributesError];
NSNumber *fileSizeNumber = [fileAttributes objectForKey:NSFileSize];
long long fileSize = [fileSizeNumber longLongValue];
}
Related
I am trying to make a simple app to take a picture and save the file to both a UIImageview and to the documents folder so it can be recalled at a later time as the UIImageview. To get visibility into if the app is actually making a file, I have turned on Application supports iTunes File sharing within the .plist file.
Problem is the file generated is zero bytes. I have tried both PNG and JPG format.
- (IBAction)picImage:(id)sender {
imagePicker = [[UIImagePickerController alloc] init];
imagePicker.delegate = self;
//check to see if the device has camera capability
if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera])
{
imagePicker.sourceType = UIImagePickerControllerSourceTypeCamera;
}
else
{
imagePicker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
}
[self presentViewController:imagePicker animated:YES completion:nil];
}
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
//set the UIImageView to the selected image
playerImage.image = [info objectForKey:UIImagePickerControllerOriginalImage];
//obtaining saving path
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *imagePath = [documentsDirectory stringByAppendingPathComponent:#"player.png"];
UIImage *editedImage = [UIImage imageWithContentsOfFile:imagePath];
NSData *imageData = UIImagePNGRepresentation(editedImage);
//NSData *imageData = UIImageJPEGRepresentation(editedImage,1.0);
// This actually creates the image at the file path specified, with the image's NSData.
[[NSFileManager defaultManager] createFileAtPath:imagePath contents:imageData attributes:nil];
//dismiss the imagepicker view controller
[self dismissViewControllerAnimated:YES completion:nil];
}
- (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker
{
[self dismissViewControllerAnimated:YES completion:nil];
}
Try this code and let me know is it working or not..!!!!
- (void) imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *strimagename;
strimagename=[NSString stringWithFormat:#"Test.jpg"];
NSString *thumbFilePath = [documentsDirectory stringByAppendingPathComponent:strimagename];
UIImage *image = [info objectForKey:#"UIImagePickerControllerOriginalImage"];
NSData *thumbData = UIImageJPEGRepresentation(image, 1);
[thumbData writeToFile:thumbFilePath atomically:YES];
[imgPicker dismissModalViewControllerAnimated:YES];
This code will save image in documentory folder..
Happy Coding..!!!!!!
Ok guys, I am fairly new to objective C. I have an app that downloads a list of images from my web server and displays the appropriate ones in a UIImage view with swipe gestures to go forward or backwards for the next/previous pic to be displayed. Current naming format for the pictures is like this:
uploaded_141_admin1.png
uploaded_141_admin2.png
uploaded_141_interior1.png
uploaded_141_interior2.png
uploaded_141_exterior1.png
The current code loads every picture into the view that has 141 in the middle part of the filename (or whatever record the user in on... 141 is variable in this instance, just showing here for an example of the format). The problem is, there seems to be no rhyme or reason as to what order they are displayed in. I would like it to use the last part of the filename to sort alphabetically (or even the whole filename, as it would achieve the same result). In the example above, it would display the downloaded pics in the following order when swiping through the uiimageiew:
uploaded_141_admin1.png
uploaded_141_admin2.png
uploaded_141_exterior1.png
uploaded_141_interior1.png
uploaded_141_interior2.png
I've search and can't find what I am looking for (maybe because I'm using the wrong search criteria). Here is my existing code that downloads and displays the images in the UIImageView. I assume the "sort" code would go in here somewhere:
-(void)downloadPictures:(NSArray *)picPaths {
ELog(#"Downloading pictures: %#",picPaths);
// wait indicator
[[WaitingView sharedInstance] setMessage:LocStr(#"Loading pictures... The more pictures there are, the longer this will take. Please be patient.")];
[[WaitingView sharedInstance] showIndicator:YES];
[[WaitingView sharedInstance] displayOn:[self view]];
[[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:YES];
// queue download operation
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
NSInvocationOperation *downloadOp = [[NSInvocationOperation alloc] initWithTarget:self selector:#selector(downloadOperation:) object:picPaths];
[queue addOperation:downloadOp];
}
-(void)downloadOperation:(NSArray *)picPaths {
NSMutableArray *allPictures = [[NSMutableArray alloc] init];
for(NSString *path in picPaths) {
NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:#"http://%#%#/%#/%#",SERVER_ADDRESS,SERVER_PORT,SERVER_PHOTOS,path]];
NSData *picData = [NSData dataWithContentsOfURL:url];
if(picData!=nil) {
UIImage *img = [UIImage imageWithData:picData];
if(img!=nil) {
[allPictures addObject:img];
} else {
ELog(#"Failed to convert data to image from url %#",url);
}
} else {
ELog(#"Failed to download image from url %#",url);
}
}
[[WaitingView sharedInstance] performSelectorOnMainThread:#selector(remove) withObject:nil waitUntilDone:NO];
[[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:NO];
self.pictures=allPictures;
if([self.pictures count]==0) {
[self performSelectorOnMainThread:#selector(downloadErrorMessage) withObject:nil waitUntilDone:NO];
} else {
self.currentIndex=0;
[self performSelectorOnMainThread:#selector(showPicture) withObject:nil waitUntilDone:NO];
}
}
-(void)downloadErrorMessage {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Oooops!" message:LocStr(#"Pictures download failed") delegate:nil cancelButtonTitle:LocStr(#"Close") otherButtonTitles:nil];
[alert show];
[alert release];
[self goBack];
}
-(void)showPicture {
UIImage *image = [self.pictures objectAtIndex:self.currentIndex];
ELog(#"Now displaying image with index %d: %#",self.currentIndex,image);
self.picture.image=image;
[self.picture setNeedsLayout];
}
In your downloadPictures: method you should sort your picPaths array to be the order you want the images before you start the download operation. You can do this by creating a new sorted array using the NSArray method sortedArrayUsingSelector:. Using caseInsensitiveCompare: as the selector for the sort will order the NSStrings in the array alphabetically.
NSArray *sortedPicPaths = [picPaths sortedArrayUsingSelector:#selector(caseInsensitiveCompare:)];
Then when you init your NSInvocationOperation, pass the sorted array as the object.
Check my app if you don't really understand ( Quick Notes!) But here it goes. My app is a notes app so it allows the user to select from few different kinds of note colors and designs below. When the user selects one, it changes the note above to what ever they set it to. So i need a button that will save the picture they selected, and when the leave the view and come back they can click the load button and the same image they selected will appear. I am using Xcode 4.3. Thanks so much!
Here is my save code:
-(IBAction)save123456 {
NSBitmapImageRep *rep;
NSData *data;
NSImage *noteview;
[self lockFocus];
rep = [[NSBitmapImageRep alloc] initWithFocusedViewRect:[self frame]];
[self unlockFocus];
image = [[[NSImage alloc] initWithSize:[rep size]] autorelease];
[image addRepresentation:rep];
data = [rep representationUsingType: NSPNGFileType properties: nil];
//save as png but failed
[data writeToFile: #"asd.png" atomically: NO];
//save as pdf, succeeded but with flaw
data = [self dataWithPDFInsideRect:[self frame]];
[data writeToFile:#"asd.pdf" atomically:YES];
}
And my load:
-(IBAction)load123456 {
NSImage loadedImage = [[NSImage alloc] initWithContentsOfFile: NSString* filePath]
}
I get so many error codes in my save. My image is called noteview. Thanks!!
Try use instead
[data writeToFile: #"asd.png" atomically: NO];
a code line
[data writeToFile: #"asd.png" atomically: YES];
Some open source examples:
AGSimpleImageEditorView
image editors in iOS
projects with work with Pictures
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];
I was using UIImagePickerController without any problem.
Before when I was taking a picture in the landscape mode, the picture in the Preview (when the buttons Retake and Use Photo were present) was always automatically rotated so as to appear correctly in the portrait mode.
But now when I use the UIImagePickerController the preview mode does not rotate the picture anymore.
Where can I activate or desactivate this mode?
Here is my code:
- (IBAction)getCameraPicture{
//Create an UIImagePickerController to be able to take a picture
UIImagePickerController *picker = [[UIImagePickerController alloc] init];
picker.delegate = self;
picker.sourceType = UIImagePickerControllerSourceTypeCamera;
picker.allowsImageEditing = NO;
[self presentModalViewController:picker animated:YES];
[picker release];
- (IBAction)selectExistingPicture{
if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypePhotoLibrary]) {
UIImagePickerController *picker = [[UIImagePickerController alloc] init];
picker.delegate = self;
picker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;//Here is specified the fact that the picker source is the library
[self presentModalViewController:picker animated:YES];
[picker release];
}
else {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Error accessing photo library" message:#"Device does not support a photo library" delegate:nil cancelButtonTitle:#"Drat!" otherButtonTitles:nil];
[alert show];
[alert release];
}
}
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingImage:(UIImage *)image editingInfo:(NSDictionary *)editingInfo {
int imageCase=0;
UIImage *imageSaved=rotateImage(image);
UIImage* imageNormal =scaleImage(imageSaved,imageCase);
imageView.image = imageNormal;
[picker dismissModalViewControllerAnimated:YES];
}
- (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker {
[picker dismissModalViewControllerAnimated:YES];
}
I really need to at least understand what is happening so any help would be really appreciated even if it is not the solution!
Thanks folks!
one possibility is that you need to call
[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];