This code fails on iOS 8, although it would work on iOS 7
UIImage *imageTest = ...
NSString *file = #"../Documents/Test.png";
NSString *fullpath = [[[NSBundle mainBundle] bundlePath] stringByAppendingPathComponent: file];
[UIImagePNGRepresentation(imageTest) writeToFile: fullpath atomically: YES];
UIImage *image = [UIImage imageNamed: file];
On iOS 8 I need to use this instead
NSString *file = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0] stringByAppendingPathComponent:#"Test.png"];
[UIImagePNGRepresentation(imageTest) writeToFile:file atomically:YES];
UIImage *image = [[UIImage alloc] initWithContentsOfFile: file];
...but then I have to refactor my project and a third party library that works with paths relative to the main bundle.
It seems to me that paths like "/PathToMainBundle/MyApp.app/../Documents/something" are either not properly resolved, or not allowed at all by iOS 8
That path should be the same as "/PathToMainBundle/Documents/something"
In iOS8, Resource Directory(App.app), Data Directory(NSCachesDirectory, NSTemporaryDirectory,..) are managed separately as below.
iOS7 Directory Hierarchy
App UUID
Documents
Library
Caches
Preferences
tmp
App.app
iOS8 Directory Hierarchy
Resource Directory UUID
App.app
Data Directory UUID
Documents
Library
Caches
Preferences
tmp
So, you should fix code based on absolute path in iOS8.
UIImage *imageTest = ...
NSString *fullpath = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject] stringByAppendingPathComponent:#"Test.png"];
[UIImagePNGRepresentation(imageTest) writeToFile: fullpath atomically: YES];
UIImage *image = [UIImage imageNamed: fullpath];
Related
When I test my app on iOS8 beta3 and beta5, I found an bug that about [UIImage imageWithContentsOfFile:].
When image resources are stored in sub-bundle of a main bundle, it will return nil if we initialize UIImage via the following method:
NSString *testBundlePath = [[NSBundle mainBundle] pathForResource:#"test" ofType:#"bundleā€¯];
NSBundle *bundle = [NSBundle bundleWithPath:testBundlePath];
NSString *path = [bundle pathForResource:#"play.png" ofType:nil];
UIImage *image = [UIImage imageWithContentsOfFile:path]; //iOS8 image = nil, iOS7 image != nil
But when the image resources are stored in main bundle, UIImage Initialization can be succeed through the following method:
NSString *path = [[NSBundle mainBundle] pathForResource:#"play.png" ofType:nil];
UIImage *image = [UIImage imageWithContentsOfFile:path]; //iOS8 and iOS7 image != nil
We have found this problem under iOS8 beta3 and it still exists under iOS8 beta 5.
The Demo app directory structure was below:
XXX.app
|----test~ipad.bundle
|----play.png
|----test~iphone.bundle
|----play.png
|----play.png
|----play~iphone.png
|----play~ipad.png
......
Does anyone have the same problem? I think this is a bug on iOS8, Therefore, many apps have used bundle to organize resources, such as images. But now, this bug will make thousands of apps become ugly and hard to use. We really hope that Apple can fix this bug in the next version, otherwise, all of my app will have to developing an new version for this bug!
It's not actually broken, you're just sending it the wrong path.
I'm guessing that you are using the simulator, and have saved a file somewhere in your app and then made note of the full path to that file. However, when you rebuild your app the UUID for the installed app changes, and your saved path is no longer valid (even though the files are still there). You can see your current active path by checking [[NSFileManager defaultManager] currentDirectoryPath] Note that the value changes each time you rebuild and re-deploy your app.
To get to your actual file, you'll need to do something like this:
NSString *image = #"myImage.png";
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
NSString *cache = [paths objectAtIndex:0];
NSString *fullPath = [NSString stringWithFormat:#"%#/%#", cache, image];
UIImage *image = [UIImage imageWithContentsOfFile:fullPath];
pathForResource:ofType: only looks in the Resources folder (and localised folders). If you are placing files into dedicated folders in the bundle then you need to use pathForResource:ofType:inDirectory: and supply the directory name.
Apple has fixed this bug on iOS8.1,Cheers
just use
NSString *fullPath = [bundle pathForResource:name ofType:#"png"];
NSData *data = [NSData dataWithContentsOfFile:fullPath];
UIImage *image = [UIImage imageWithData:data];
I have retrieved movies file from my iPhone Photo Library, and saved them into my App`s Documents directory. When I click one movie file, I want to use MPMoviePlayerController to play it. Unfortunately, It fail to play the movie file with such error:
_itemFailedToPlayToEnd: {
kind = 1;
new = 2;
old = 0;
}
I have searched for a long time to resolve this problem. Somebody say the format maybe is unsupport. The movies file is retrieved from Photo Library, so the format should be OK. Also, I copy the file to NSBundle and MPMoviePlayerController can play it. So the file is OK. Following is my codes:
NSString *newstr = [mFilePath stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
DLog(#"the raw is %# the newstr is %#", mFilePath, newstr);
NSURL *url = [NSURL URLWithString:newstr];
DLog(#"the url is %#", url);
#if 0
NSBundle *bundle = [NSBundle mainBundle];
if (bundle) {
NSString *path = [bundle pathForResource:#"test" ofType:#"MOV"];
if (path) {
url = [NSURL fileURLWithPath:path];
DLog(#"the new url is %#", url);
}
}
#endif
mPlayer = [[MPMoviePlayerController alloc] initWithContentURL:url];
[mPlayer setMovieSourceType:MPMovieSourceTypeFile];
[mPlayer prepareToPlay];
[mPlayer.view setFrame:self.view.bounds];
[mPlayer play];
[self.view addSubview:mPlayer.view];
Changing:
NSURL *url = [NSURL URLWithString:path];
to
NSURL *url = [NSURL fileURLWithPath:path];
fixed it for me, then:
mPlayer.contentURL = url;
[mPlayer prepareToPlay];
but you already do this correctly. I create the mPlayer once and then just shift the contentURL about (instead of alloc + initWithContentURL) for different videos. Have you tried that?
I'm completely new to Xcode, obj-c etc, but I want to use Parse.com to save an image to their server, they say you have to use this line, to convert a UIImage to NSData
NSData *imageData = UIImagePNGRepresentation(image);
How would I load one of the .png's that is in my resource folder and then convert it to a UIImage? I'm also using the Sparrow Framework if that helps any.
EDIT
I've tried this code as suggested below.
NSString *imagePath = [[NSBundle mainBundle] pathForResource:#"terrainHexAtlas_v1#2x.png" ofType:#"png"];
UIImage *myImage = [UIImage imageWithContentsOfFile:imagePath];
NSData *imageData = UIImagePNGRepresentation(myImage);
PFFile *imageFile = [PFFile fileWithName:#"terrainHexAtlas_v1#2x.png" data:imageData];
[imageFile save];
But nothing seems to be happening. I tried a breakpoint at the last line and the vars imagePath, myImage, imageData are all 00000000 which I don't get.
you should follow code:
//png
NSString *imagePath = [[NSBundle mainBundle] pathForResource:#"your_image" ofType:#"png"];
UIImage *myImage = [UIImage imageWithContentsOfFile:imagePath];
NSData *pngImageData = UIImagePNGRepresentation(myImage);
//jpeg
NSString *imagePath2 = [[NSBundle mainBundle] pathForResource:#"your_image" ofType:#"jpg"];
UIImage *myImage2 = [UIImage imageWithContentsOfFile:imagePath2];
NSData *jpegImageData = [UIImageJPEGRepresentation(myImage2, 1.0f)];
Do not contain an extension in pathForResource. check following mistake case.
// not contain an extension
NSString *imagePath = [[NSBundle mainBundle] pathForResource:#"your_image.png" ofType:nil];
// contain an extension
NSString *imagePath = [[NSBundle mainBundle] pathForResource:#"your_image" ofType:#"png"];
// some people mistake case. wrong code. that return nil
NSString *imagePath = [[NSBundle mainBundle] pathForResource:#"your_image.png" ofType:#"png"];
UIImage *img = [[UIImage alloc] initWithContentsOfFile:#"contactHeader.png"];
_headersView = [[UIImageView alloc] initWithImage:img];
I have already hooked up the connections for the UIImageView (_headersView) in IB. The image I want to load is in my project tree structure as well.
Am I creating the UIImage the right way?
If the file is in your bundle you can just use
UIImage *img = [UIImage imageNamed:#"contactHeader"];
_headersView = [[UIImageView alloc] initWithImage:img];
If the image is in your documents directory you can use
// Get the path to your documents directory
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
// Add the file to the end of the documents path
NSString *filePath = [documentsDirectory stringByAppendingPathComponent:#"contactHeader.png"];
UIImage *img = [[UIImage alloc] imageWithContentsOfFile:filePath];
_headersView = [[UIImageView alloc] initWithImage:img];
[img release]; img = nil;
try this
-(NSString *)getPath:(NSString *)filename
{
self.path = [[NSBundle mainBundle]pathForResource:filename ofType:#"png"];
return path;
path = nil;
}
self.youImageView.image = [UIImage imageWithContentsOfFile:[self getPath:#"123"]];
When changing the image on an UIImageView in code, the image disappears. This only happens on an iPod Touch device, not on the iPhone emulator.
In my bundle I have an image named SomeImage.PNG
NSString *path = [[NSBundle mainBundle] pathForResource:#"SomeImage" ofType:#"png"];
[self.background setImage:[[UIImage alloc] initWithContentsOfFile:path]];
I must reiterate, this works fine on the iPhone simulator but not on an iPod Touch device.
Notice that the image file has an upper-case file extension, but in my code it is declared with lower case. This is the problem. So to fix the problem, change the code to this:
NSString *path = [[NSBundle mainBundle] pathForResource:#"SomeImage" ofType:#"PNG"];
[self.background setImage:[[UIImage alloc] initWithContentsOfFile:path]];
I am asking if there is a 'better' way to do what I am doing, so I don't come across such issues in the future.
Not really. Unfortunately the iOS file system is case sensitive.
Something like this.....?
NSString *filename = #"SomeImage";
NSString *extension = #"png";
UIImage *img = nil;
NSString *path = nil;
path = [[NSBundle mainBundle] pathForResource:filename ofType:[extension lowercaseString]];
img = [[UIImage alloc] initWithContentsOfFile:path];
if (img == nil) {
path = [[NSBundle mainBundle] pathForResource:filename ofType:[extension uppercaseString]];
img = [[UIImage alloc] initWithContentsOfFile:path];
}