I am using uiimagepicker to save video to my application bundle. But after saving that, the created date of the video is changed. My requirement is just to copy that video to my folder without changing its created date.
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
[[picker parentViewController] dismissModalViewControllerAnimated:YES];
NSURL *url = [info objectForKey:UIImagePickerControllerReferenceURL];
NSData *imageData = [NSData dataWithContentsOfURL:url];
NSString *path = NSHomeDirectory();
NSString *img_temp_name=[[NSString stringWithFormat:#"test"] stringByAppendingString:#".mov"];
NSString *full_path=[path stringByAppendingPathComponent:img_temp_name];
if([imageData writeToFile:full_path atomically:YES]) {
}
Can you use NSFileManager to help you?
I assume that you're not going to be allowed just to move the movie but if you copy it, does it preserve some file information?
NSURL *url = [info objectForKey:UIImagePickerControllerReferenceURL];
NSString *path = NSHomeDirectory();
NSString *img_temp_name=[[NSString stringWithFormat:#"test"] stringByAppendingString:#".mov"];
NSString *full_path=[path stringByAppendingPathComponent:img_temp_name];
NSURL *dst = [NSURL fileURLWithString:full_path];
NSError *error = nil;
NSFileManager *manager = [[[NSFileManager alloc] init] autorelease];
BOOL success = [manager copyItemAtURL:url toURL:dst error:&error];
if (NO == success || error) {
NSLog(#"Could not copy : %#", error);
}
Your issue is that as part of the picking process the video is reencoded. This changes the creation date. I would also like to know if it is possible to getbthis info.
Here is a way to get videos as NSData.
It uses the Photos framework as ALAssetLibrary is deprecated as of iOS9:
IMPORTANT
The Assets Library framework is deprecated as of iOS 9.0. Instead, use the Photos framework instead, which in iOS 8.0 and later provides more features and better performance for working with a user’s photo library. For more information, see Photos Framework Reference.
import Photos
func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : AnyObject]) {
self.dismissViewControllerAnimated(true, completion: nil)
if let referenceURL = info[UIImagePickerControllerReferenceURL] as? NSURL {
let fetchResult = PHAsset.fetchAssetsWithALAssetURLs([referenceURL], options: nil)
if let phAsset = fetchResult.firstObject as? PHAsset {
PHImageManager.defaultManager().requestAVAssetForVideo(phAsset, options: PHVideoRequestOptions(), resultHandler: { (asset, audioMix, info) -> Void in
if let asset = asset as? AVURLAsset {
let videoData = NSData(contentsOfURL: asset.URL)
// optionally, write the video to the temp directory
let videoPath = NSTemporaryDirectory() + "tmpMovie.MOV"
let videoURL = NSURL(fileURLWithPath: videoPath)
let writeResult = videoData?.writeToURL(videoURL, atomically: true)
if let writeResult = writeResult where writeResult {
print("success")
}
else {
print("failure")
}
}
})
}
}
}
Related
I am very new to iphone development and i am trying to get a web view to cache onto the device so that it will sty there even when the application is closed and then reload the data when the application starts again. I would also like it to reload the data in the cache every 2 weeks.
Many Thanks,
Thomas
through a lot of searching around and asking friends i managed to find the code and though that i would share it with everyone
Objective-C
- (void) cacheFile
{
//Create the file/directory pointer for the storage of the cache.
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
self.dataPath = [[paths objectAtIndex:0] stringByAppendingPathComponent:#"cache.html"];
//Check to see if a file exists a the location
if ([[NSFileManager defaultManager] fileExistsAtPath:dataPath]) {
//Code for customising when the cache reloads would go here.
}
else
{
//If no file exists write the html cache to it
//Download and write to file
NSURL *cacheUrl = [NSURL URLWithString:#"INSERT WEB URL HERE"];
NSData *cacheUrlData = [NSData dataWithContentsOfURL:cacheUrl];
[cacheUrlData writeToFile:dataPath atomically:YES];
}
//Run the load web view function.
[self loadWebView];
}
- (void) loadWebView
{
//Load up the web view from the cache.
[WebView loadRequest:[NSURLRequest requestWithURL:[NSURL fileURLWithPath:dataPath]]];
}
Swift 3
func cacheFile() {
//Create the file/directory pointer for the storage of the cache.
let paths = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)
guard let dataPath = paths.first?.appending("cache.html") else {
return
}
//Check to see if a file exists a the location
if FileManager.default.fileExists(atPath: dataPath) {
//Code for customising when the cache reloads would go here.
} else if let cacheUrl = URL(string: "INSERT WEB URL HERE") {
//If no file exists write the html cache to it
//Download and write to file
do {
let cacheUrlData = try Data(contentsOf: cacheUrl)
try cacheUrlData.write(to: URL(fileURLWithPath: dataPath), options: Data.WritingOptions.atomic)
} catch {
print("Problem with cacheUrlData")
}
}
//Run the load web view function.
loadWebView(dataPath: dataPath)
}
func loadWebView(dataPath: String) {
webView.loadRequest(URLRequest(url: URL(fileURLWithPath: dataPath)))
}
I have implemented an overlay view when calling camera view before recording the video.
pickerController.cameraOverlayView =myOverlay;
Video recording and saving the video into Album after recording the video and sharing via email etc. all works fine.
If i use video quality as "High quality", then the recorded video has become huge size. For example, if i record video for 30 seconds with high quality, recorded video has become around 30 - 40 mb.
pickerController.videoQuality = UIImagePickerControllerQualityTypeHigh;
How do i program to compress the high quality recorded video before sharing it, like how Apple does with built-in Video recorder?
Please guide me to resolve this.
Thanks!
UPDATED:
This is what i'm trying recently, but still no success: I want to compress the recorded video taken which comes to didFinishPickingMediaWithInfo and store in same photo album actual video path itself, not anywhere else. I tested the same video is compressed to very small size when i pick from photo library, but the same video taken from camera and came via didFinishPickingMediaWithInfo is not compressed, though i used the AVAssetExportSession code below.
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info{
NSString *mediaType = [info objectForKey:UIImagePickerControllerMediaType];
if ([mediaType isEqualToString:(NSString *)kUTTypeMovie])
{
NSURL *videoURL = [info objectForKey:UIImagePickerControllerMediaURL];
NSString *urlPath = [videoURL path];
if ([[urlPath lastPathComponent] isEqualToString:#"capturedvideo.MOV"])
{
if (UIVideoAtPathIsCompatibleWithSavedPhotosAlbum (urlPath))
{
[self copyTempVideoToMediaLibrary :urlPath];
}
else
{
NSLog(#"Video Capture Error: Captured video cannot be saved...didFinishPickingMediaWithInfo()");
}
}
else
{
NSLog(#"Processing soon to saved photos album...else loop of lastPathComponent..didFinishPickingMediaWithInfo()");
}
}
[self dismissModalViewControllerAnimated:YES];
}
- (void)copyTempVideoToMediaLibrary :(NSString *)videoURL {
dispatch_queue_t mainQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_async(mainQueue, ^{
ALAssetsLibrary *library = [[[ALAssetsLibrary alloc] init] autorelease];
ALAssetsLibraryWriteVideoCompletionBlock completionBlock = ^(NSURL *assetURL, NSError *error) {
NSLog(#"Saved URL: %#", assetURL);
NSLog(#"Error: %#", error);
if (assetURL != nil) {
AVURLAsset *theAsset = [AVURLAsset URLAssetWithURL:[NSURL URLWithString:videoURL] options:nil];
NSArray *compatiblePresets = [AVAssetExportSession exportPresetsCompatibleWithAsset:theAsset];
AVAssetExportSession *exportSession = [[AVAssetExportSession alloc] initWithAsset:theAsset presetName:AVAssetExportPresetLowQuality];
[exportSession setOutputURL:[NSURL URLWithString:videoURL]];
[exportSession setOutputFileType:AVFileTypeQuickTimeMovie];
[exportSession exportAsynchronouslyWithCompletionHandler:^ {
switch ([exportSession status]) {
case AVAssetExportSessionStatusFailed:
NSLog(#"Export session faied with error: %#", [exportSession error]);
break;
default:
//[self mediaIsReady];
break;
}
}];
}
};
[library writeVideoAtPathToSavedPhotosAlbum:[NSURL URLWithString:videoURL] completionBlock:completionBlock];
});
}
If you want to compress the video for remote sharing and keep the original quality for local storage on the iPhone, you should look into AVAssetExportSession or AVAssetWriter.
Also read up on how iOS manages Assets.
- (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:AVAssetExportPresetLowQuality];
exportSession.outputURL = outputURL;
exportSession.outputFileType = AVFileTypeQuickTimeMovie;
[exportSession exportAsynchronouslyWithCompletionHandler:^(void)
{
handler(exportSession);
[exportSession release];
}];
}
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
NSURL *videoURL = [info objectForKey:UIImagePickerControllerMediaURL];
NSURL *outputURL = [NSURL fileURLWithPath:#"/Users/josh/Desktop/output.mov"];
[self convertVideoToLowQuailtyWithInputURL:videoURL outputURL:outputURL handler:^(AVAssetExportSession *exportSession)
{
if (exportSession.status == AVAssetExportSessionStatusCompleted)
{
printf("completed\n");
}
else
{
printf("error\n");
}
}];
}
I guess the video is already compressed by the h264 codec. But you can try to use AVFoundation to capture the video files from camera. But I suspect you'll end up with the same file sizes.
Here is some statistics for the 10 seconds video file recorded on the iPhone 4 with different quality pressets.
high (1280х720) = ~14MB = ~11Mbit/s
640 (640х480) = ~4MB = ~3.2Mbit/s
medium (360х480) = ~1MB = ~820Kbit/s
low (144х192) = ~208KB = ~170Kbit/s
pickerController.videoQuality = UIImagePickerControllerQualityTypeMedium;
These are all the values you can pick from.
UIImagePickerControllerQualityTypeHigh = 0,
UIImagePickerControllerQualityType640x480 = 3,
UIImagePickerControllerQualityTypeMedium = 1, // default value
UIImagePickerControllerQualityTypeLow = 2
Programmatically compressing video with using swift
And don't forgot to add - import AssetsLibrary
func convertVideoWithMediumQuality(inputURL : NSURL){
let VideoFilePath = NSURL(fileURLWithPath: NSTemporaryDirectory()).URLByAppendingPathComponent("mergeVideo\(arc4random()%1000)d").URLByAppendingPathExtension("mp4").absoluteString
if NSFileManager.defaultManager().fileExistsAtPath(VideoFilePath) {
do {
try NSFileManager.defaultManager().removeItemAtPath(VideoFilePath)
} catch { }
}
let savePathUrl = NSURL(string: VideoFilePath)!
let sourceAsset = AVURLAsset(URL: inputURL, options: nil)
let assetExport: AVAssetExportSession = AVAssetExportSession(asset: sourceAsset, presetName: AVAssetExportPresetMediumQuality)!
assetExport.outputFileType = AVFileTypeQuickTimeMovie
assetExport.outputURL = savePathUrl
assetExport.exportAsynchronouslyWithCompletionHandler { () -> Void in
switch assetExport.status {
case AVAssetExportSessionStatus.Completed:
dispatch_async(dispatch_get_main_queue(), {
do {
let videoData = try NSData(contentsOfURL: savePathUrl, options: NSDataReadingOptions())
print("MB - \(videoData.length / (1024 * 1024))")
} catch {
print(error)
}
})
case AVAssetExportSessionStatus.Failed:
self.hideActivityIndicator(self.view)
print("failed \(assetExport.error)")
case AVAssetExportSessionStatus.Cancelled:
self.hideActivityIndicator(self.view)
print("cancelled \(assetExport.error)")
default:
self.hideActivityIndicator(self.view)
print("complete")
}
}
}
Try this few lines :
[[NSFileManager defaultManager] removeItemAtURL:outputURL error:nil];
AVURLAsset *urlAsset = [AVURLAsset URLAssetWithURL:inputURL options:nil];
AVAssetExportSession *session = [[AVAssetExportSession alloc] initWithAsset: urlAsset presetName:AVAssetExportPresetLowQuality];
session.outputURL = outputURL;
session.outputFileType = AVFileTypeQuickTimeMovie;
[session exportAsynchronouslyWithCompletionHandler:^(void)
{
handler(session);
}];
I found an excellent custom class(SDAVAssetExportSession) to do the video compression. You can download it from this link.
After downloading add SDAVAssetExportSession.h and SDAVAssetExportSession.m files into your project, Then the below code will help to do the compression. In below code you can compress video by specifying resolution and bitrate
#import "SDAVAssetExportSession.h"
- (void)compressVideoWithInputVideoUrl:(NSURL *) inputVideoUrl
{
/* Create Output File Url */
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSFileManager *fileManager = [NSFileManager defaultManager];
NSString *finalVideoURLString = [documentsDirectory stringByAppendingPathComponent:#"compressedVideo.mp4"];
NSURL *outputVideoUrl = ([[NSURL URLWithString:finalVideoURLString] isFileURL] == 1)?([NSURL URLWithString:finalVideoURLString]):([NSURL fileURLWithPath:finalVideoURLString]); // Url Should be a file Url, so here we check and convert it into a file Url
SDAVAssetExportSession *compressionEncoder = [SDAVAssetExportSession.alloc initWithAsset:[AVAsset assetWithURL:inputVideoUrl]]; // provide inputVideo Url Here
compressionEncoder.outputFileType = AVFileTypeMPEG4;
compressionEncoder.outputURL = outputVideoUrl; //Provide output video Url here
compressionEncoder.videoSettings = #
{
AVVideoCodecKey: AVVideoCodecH264,
AVVideoWidthKey: #800, //Set your resolution width here
AVVideoHeightKey: #600, //set your resolution height here
AVVideoCompressionPropertiesKey: #
{
AVVideoAverageBitRateKey: #45000, // Give your bitrate here for lower size give low values
AVVideoProfileLevelKey: AVVideoProfileLevelH264High40,
},
};
compressionEncoder.audioSettings = #
{
AVFormatIDKey: #(kAudioFormatMPEG4AAC),
AVNumberOfChannelsKey: #2,
AVSampleRateKey: #44100,
AVEncoderBitRateKey: #128000,
};
[compressionEncoder exportAsynchronouslyWithCompletionHandler:^
{
if (compressionEncoder.status == AVAssetExportSessionStatusCompleted)
{
NSLog(#"Compression Export Completed Successfully");
}
else if (compressionEncoder.status == AVAssetExportSessionStatusCancelled)
{
NSLog(#"Compression Export Canceled");
}
else
{
NSLog(#"Compression Failed");
}
}];
}
To Cancel Compression Use Below Line Of code
[compressionEncoder cancelExport]; //Video compression cancel
I cracked this.
Use exportSession.fileLengthLimit = 1048576 * 10 //10 MB
10MB is hard coded number. Use according to your required bitrate.
What's currently working in my code:
I select a JPG or PNG from the Photo Library (using standard ImagePicker methods), and convert that image to NSData using:
self.myImageData = UIImageJPEGRepresentation(myImage, 0.9);
which I then post to a server using multipart/form-data.
I now want to do the same for a GIF, while retaining the original GIF data (so that an animated GIF going into the library, comes back out still animating).
In didFinishPickingMediaWithInfo, I am able to get the URL of the original GIF using
self.myGIFURL = [info objectForKey:UIImagePickerControllerReferenceURL].
Here's one example of what that might get me:
assets-library://asset/asset.GIF?id=1000000034&ext=GIF
Here are two ways I've tried now to push this GIF into NSData, and each time I myImageData shows (null).
I've tried to use initWithContentsOfURL:
NSData *dataFromGIFURL = [[NSData alloc] initWithContentsOfURL: myGIFURL];
self.myImageData = dataFromGIFURL;
[dataFromGIFURL release];
Then I tried converting the NSURL to a string for initWithContentsOfFile:
NSString *stringFromURL = [NSString stringWithFormat:#"%#", myGIFURL];
NSData *dataFromGIFURL = [[NSData alloc] initWithContentsOfFile: stringFromURL];
self.myImageData = dataFromGIFURL;
[dataFromGIFURL release];
Any suggestions? Thanks.
The UIImagePickerControllerReferenceURL key doesn't appear until iOS 4.1. I therefore take it as implicit in your question that it's fine to use the AssetsLibrary framework, which appeared in iOS only at 4.0. In which case, you can use the following:
- (void)imagePickerController:(UIImagePickerController *)picker
didFinishPickingMediaWithInfo:(NSDictionary *)info
{
ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init];
[library assetForURL:[info objectForKey:UIImagePickerControllerReferenceURL]
resultBlock:^(ALAsset *asset)
{
ALAssetRepresentation *representation = [asset defaultRepresentation];
NSLog(#"size of asset in bytes: %d", [representation size]);
unsigned char bytes[4];
[representation getBytes:bytes fromOffset:0 length:4 error:nil];
NSLog(#"first four bytes: %02x (%c) %02x (%c) %02x (%c) %02x (%c)",
bytes[0], bytes[0],
bytes[1], bytes[1],
bytes[2], bytes[2],
bytes[3], bytes[3]);
[library autorelease];
}
failureBlock:^(NSError *error)
{
NSLog(#"couldn't get asset: %#", error);
[library autorelease];
}
];
}
So, you create an ALAssetsLibrary, ask it to find you the asset with the URL specified (it understands the assets-library:// URL scheme), then when you get the asset you grab its default representation and use that to feed you the bytes. They'll be the actual on-disk bytes, the default representation for an asset from the library being its on-disk form.
For example, selecting a particular GIF I grabbed at random from Google images, from an image picker wired up to a delegate with that method in it gives me the output:
2011-03-03 23:17:37.451
IPTest[1199:307] size of asset in
bytes: 174960
2011-03-03 23:17:37.459
IPTest[1199:307] first four bytes: 47
(G) 49 (I) 46 (F) 38 (8)
So that's the beginning of the standard GIF header. Picking PNGs or JPGs gives the recognisable first four bytes of the PNG and JPG headers.
EDIT: to finish the thought, obviously you can use ALAssetRepresentation to read all of the bytes describing the file into a suitably malloc'd C array, then use NSData +(id)dataWithBytes:length: (or, more likely, +dataWithBytesNoCopy:length:freeWhenDone:) to wrap that into an NSData.
Here's a version that uses the newer Photos framework:
- (void) imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
NSURL * refUrl = [info objectForKey:UIImagePickerControllerReferenceURL];
if (refUrl) {
PHAsset * asset = [[PHAsset fetchAssetsWithALAssetURLs:#[refUrl] options:nil] lastObject];
if (asset) {
PHImageRequestOptions *options = [[PHImageRequestOptions alloc] init];
options.synchronous = YES;
options.networkAccessAllowed = NO;
options.deliveryMode = PHImageRequestOptionsDeliveryModeHighQualityFormat;
[[PHImageManager defaultManager] requestImageDataForAsset:asset options:options resultHandler:^(NSData * _Nullable imageData, NSString * _Nullable dataUTI, UIImageOrientation orientation, NSDictionary * _Nullable info) {
NSNumber * isError = [info objectForKey:PHImageErrorKey];
NSNumber * isCloud = [info objectForKey:PHImageResultIsInCloudKey];
if ([isError boolValue] || [isCloud boolValue] || ! imageData) {
// fail
} else {
// success, data is in imageData
}
}];
}
}
}
Here's Eli's version using Swift 3:
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String: Any]) {
guard let imageURL = info[UIImagePickerControllerReferenceURL] as? URL else { return }
guard let asset = PHAsset.fetchAssets(withALAssetURLs: [imageURL], options: nil).lastObject else { return }
if picker.sourceType == .photoLibrary || picker.sourceType == .savedPhotosAlbum {
let options = PHImageRequestOptions()
options.isSynchronous = true
options.isNetworkAccessAllowed = false
options.deliveryMode = .highQualityFormat
PHImageManager.default().requestImageData(for: asset, options: options) { data, uti, orientation, info in
guard let info = info else { return }
if let error = info[PHImageErrorKey] as? Error {
log.error("Cannot fetch data for GIF image: \(error)")
return
}
if let isInCould = info[PHImageResultIsInCloudKey] as? Bool, isInCould {
log.error("Cannot fetch data from cloud. Option for network access not set.")
return
}
// do something with data (it is a Data object)
}
} else {
// do something with media taken via camera
}
}
I have an iPhone application using a UIImagePickerController. As sourceType I have
UIImagePickerControllerSourceTypePhotoLibrary
UIImagePickerControllerSourceTypeCamera
UIImagePickerControllerSourceTypeSavedPhotosAlbum
so the user can make a photo or select one from the photo library from the photos or camera photos.
The image will be displayed in a UIImageView. The image should be saved if the user closes the app. So for text fields, I use NSUserDefaults. I know, it is not a good way to save the image inside the NSUSerDefaults with NSData, so I want to save / copy the image to a folder which is controlled by my application similar to the NSUserDefaults.
How can I do this? I want to save it, and then I can write the path to the file into my NSUserDefaults and read it on startup of the application.
Thank you in advance & Best Regards.
You can use the following code in UIImagePickerControllerDelegate delegate implementation
- (void) imagePickerController:(UIImagePickerController *)picker
didFinishPickingMediaWithInfo:(NSDictionary *)info {
//obtaining saving path
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *imagePath = [documentsDirectory stringByAppendingPathComponent:#"latest_photo.png"];
//extracting image from the picker and saving it
NSString *mediaType = [info objectForKey:UIImagePickerControllerMediaType];
if ([mediaType isEqualToString:#"public.image"]){
UIImage *editedImage = [info objectForKey:UIImagePickerControllerEditedImage];
NSData *webData = UIImagePNGRepresentation(editedImage);
[webData writeToFile:imagePath atomically:YES];
}
}
UPD
Swift 3.0 code by XueYu
here the image is saved as jpeg but you can also save it as png. the
0.0 parameter stands for compression and it's the lowest quality, if you want to get the best use 1.0.
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
//obtaining saving path
let fileManager = FileManager.default
let documentsPath = fileManager.urls(for: .documentDirectory, in: .userDomainMask).first
let imagePath = documentsPath?.appendingPathComponent("image.jpg")
// extract image from the picker and save it
if let pickedImage = info[UIImagePickerControllerOriginalImage] as? UIImage {
try! UIImageJPEGRepresentation(pickedImage, 0.0)?.write(to: imagePath!)
}
self.dismiss(animated: true, completion: nil)
}
Depending on the file format you want to save, you can use
[UIImagePNGRepresentation(image) writeToFile:path atomically:YES];
OR
[UIImageJPEGRepresentation(image) writeToFile:path atomically:YES];
This is the code to save the UIImage into the document directory. You can use this code in didFinishPickingImage delegate method:
// Create paths to output images
NSString *pngPath = [NSHomeDirectory();
stringByAppendingPathComponent:#"Documents/Test.png"];
NSString *jpgPath = [NSHomeDirectory();
stringByAppendingPathComponent:#"Documents/Test.jpg"];
// Write a UIImage to JPEG with minimum compression (best quality)
// The value 'image' must be a UIImage object
// The value '1.0' represents image compression quality as value from 0.0 to 1.0
[UIImageJPEGRepresentation(image, 1.0) writeToFile:jpgPath atomically:YES];
// Write image to PNG
[UIImagePNGRepresentation(image) writeToFile:pngPath atomically:YES];
// Let's check to see if files were successfully written...
// Create file manager
NSError *error;
NSFileManager *fileMgr = [NSFileManager defaultManager];
// Point to Document directory
NSString *documentsDirectory = [NSHomeDirectory();
stringByAppendingPathComponent:#"Documents"];
// Write out the contents of home directory to console
NSLog(#"Documents directory: %#", [fileMgr contentsOfDirectoryAtPath:documentsDirectory error:&error]);
EDIT
You can also use:
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
to find the path to your application document directory, instead of NSHomeDierctory.
Update knuku's answer for Swift 3.0
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
//obtaining saving path
let fileManager = FileManager.default
let documentsPath = fileManager.urls(for: .documentDirectory, in: .userDomainMask).first
let imagePath = documentsPath?.appendingPathComponent("image.jpg")
// extract image from the picker and save it
if let pickedImage = info[UIImagePickerControllerOriginalImage] as? UIImage {
try! UIImageJPEGRepresentation(pickedImage, 0.0)?.write(to: imagePath!)
}
self.dismiss(animated: true, completion: nil)
}
here the image is saved as jpeg but you can also save it as png. the 0.0 parameter stands for compression and it's the lowest quality, if you want to get the best use 1.0.
I have a NSURL object which gives me the path of a local file (in documents folder). I want to populate an NSData object with the contents of this file. Tried using dataWithContentsOfURL: but this fails. I know the file exists because the iPhone SDK returns the path.
Can someone please tell me how I can get an NSData object from the URL of a local file?
Thanks.
// Given some file path URL: NSURL *pathURL
// Note: [pathURL isFileURL] must return YES
NSString *path = [pathURL path];
NSData *data = [[NSFileManager defaultManager] contentsAtPath:path];
Swift code:
let data = FileManager.default.contents(atPath: path)
To get this work you just need to do:
NSURL *imgPath = [[NSBundle mainBundle] URLForResource:#"search" withExtension:#"png"];
NSString*stringPath = [imgPath absoluteString]; //this is correct
//you can again use it in NSURL eg if you have async loading images and your mechanism
//uses only url like mine (but sometimes i need local files to load)
NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:stringPath]];
UIImage *ready = [[[UIImage alloc] initWithData:data] autorelease];
Make sure your local URL starts with "file://"
then you would just have to do this:
NSData *fileData = [NSData dataWithContentsOfFile:fileURL.path];
For swift3 I found answer from following URL helpful
( I was getting following path , after capturing image using phonegap plugin
file:///var/mobile/Containers/Data/Application/B64B06DE-7976-45CF-9BE2-661F0F309A06/tmp/abcded.jpg )
https://stackoverflow.com/a/41043447/6383908
if let videoURL = URL(string: urlString), let videodata = try? Data(contentsOf: videoURL) {
//Add code of Alamofire here
}
guard let data = FileManager.default.contents(atPath: path) else
{ ...