FROM : glenn andreas
DATE : Fri Jan 11 23:12:49 2008
On Jan 11, 2008, at 3:34 PM, Ricky Sharp wrote:
>
> On Jan 11, 2008, at 2:10 PM, glenn andreas wrote:
>
>> NSImage's +imageNamed: is documented as searching the named images
>> cache, the apps main bundle, and then the AppKit framework bundle.
>> Unfortunately, I've got code in a private framework that wants to
>> get the image stored that framework (which isn't thus searched).
>>
>> Is there some way to add a framework to this search path? (Which
>> would be best, because it will allow any object, such as a button,
>> that has an image name to automatically work correctly) Or at least
>> a way to explicitly pass a bundle to search (via a hypothetical
>> +imageNamed:fromBundle:). The fall back, of course, is to get all
>> the possible file extensions from NSImage and manually try each and
>> every one of them, but I'd rather not have to duplicate this logic
>> (plus this fails to support the generic button using a named image
>> that resides in the private framework)...
>
> As others have pointed out, use NSBundle's pathForImageResource. I
> created an image factory that knows how to scan multiple areas
> looking for images.
I've added code to explicitly call that, which seems to work (for a
limited use where I know that I'm going to need that image), but the
more I look at it, the more I want a global version that will update
the cache so that plain old +imageNamed: works correctly (since it
seems silly to subclass everything with an image to not only have to
look for the image in a loaded framework, but to also have to then end
up hard coding the image name, since pretty much nothing with an image
lets you access the name of the image).
>
>
>> I suppose I could also, at startup, go through all the images in
>> the framework, load them, and then do a "setName:" to get them in
>> the cache (but this seems like it could impact program launch times)
>
>
> Well, that may not be bad since load times are often very, very
> low. It's probably the case where image data is not decoded until
> you're actually drawing things.
>
> For example, all my images are PDF (to support res-ind). While my
> factory loads them on-demand (and not all at once), I did measure
> the total loading time over the lifetime of the app. This was the
> time taken to actually alloc/init NSImage images and then call
> setName:.
>
> When the images were then _drawn_, that's where the bulk of the time
> was taken. Maybe this is specific to PDF; I don't know. For PDF
> the raw data is loaded, but not "decoded" until drawn; also at the
> time of drawing, that's where you end up with cached reps (e.g. a
> cached bitmapimagerep) that will ultimately speed up drawing for the
> 2nd, etc. times the image is drawn.
Yeah, I probably shouldn't be doing the premature optimization -
there's about 70 or so images currently, so I figured it would be
better to just try to load them at start up (most of them are png or
tiff files):
@interface NSBundle(NameCacheImages)
- (void) cacheNamedImages;
@end
@implementation NSBundle(NameCacheImages)
- (void) cacheNamedImages;
{
NSArray *types = [NSImage imageFileTypes];
NSEnumerator *e = [types objectEnumerator];
NSString *type;
while ((type = [e nextObject]) != nil) {
NSArray *files = [self pathsForResourcesOfType: type inDirectory: nil];
NSEnumerator *e2 = [files objectEnumerator];
NSString *path;
while ((path = [e2 nextObject]) != nil) {
NSString *name = [[path lastPathComponent]
stringByDeletingPathExtension];
NSImage *image = [NSImage imageNamed:name];
if (!image) {
NSImage *image = [[NSImage alloc] initByReferencingFile:path];
if (image) {
[image setName: name];
}
}
}
}
}
@end
The result was that it cruised through the 74 images in 0.084809
seconds, so I think I can live with that...
Glenn Andreas <email_removed>
<http://www.gandreas.com/> wicked fun!
quadrium2 | build, mutate, evolve, animate | images, textures,
fractals, art
DATE : Fri Jan 11 23:12:49 2008
On Jan 11, 2008, at 3:34 PM, Ricky Sharp wrote:
>
> On Jan 11, 2008, at 2:10 PM, glenn andreas wrote:
>
>> NSImage's +imageNamed: is documented as searching the named images
>> cache, the apps main bundle, and then the AppKit framework bundle.
>> Unfortunately, I've got code in a private framework that wants to
>> get the image stored that framework (which isn't thus searched).
>>
>> Is there some way to add a framework to this search path? (Which
>> would be best, because it will allow any object, such as a button,
>> that has an image name to automatically work correctly) Or at least
>> a way to explicitly pass a bundle to search (via a hypothetical
>> +imageNamed:fromBundle:). The fall back, of course, is to get all
>> the possible file extensions from NSImage and manually try each and
>> every one of them, but I'd rather not have to duplicate this logic
>> (plus this fails to support the generic button using a named image
>> that resides in the private framework)...
>
> As others have pointed out, use NSBundle's pathForImageResource. I
> created an image factory that knows how to scan multiple areas
> looking for images.
I've added code to explicitly call that, which seems to work (for a
limited use where I know that I'm going to need that image), but the
more I look at it, the more I want a global version that will update
the cache so that plain old +imageNamed: works correctly (since it
seems silly to subclass everything with an image to not only have to
look for the image in a loaded framework, but to also have to then end
up hard coding the image name, since pretty much nothing with an image
lets you access the name of the image).
>
>
>> I suppose I could also, at startup, go through all the images in
>> the framework, load them, and then do a "setName:" to get them in
>> the cache (but this seems like it could impact program launch times)
>
>
> Well, that may not be bad since load times are often very, very
> low. It's probably the case where image data is not decoded until
> you're actually drawing things.
>
> For example, all my images are PDF (to support res-ind). While my
> factory loads them on-demand (and not all at once), I did measure
> the total loading time over the lifetime of the app. This was the
> time taken to actually alloc/init NSImage images and then call
> setName:.
>
> When the images were then _drawn_, that's where the bulk of the time
> was taken. Maybe this is specific to PDF; I don't know. For PDF
> the raw data is loaded, but not "decoded" until drawn; also at the
> time of drawing, that's where you end up with cached reps (e.g. a
> cached bitmapimagerep) that will ultimately speed up drawing for the
> 2nd, etc. times the image is drawn.
Yeah, I probably shouldn't be doing the premature optimization -
there's about 70 or so images currently, so I figured it would be
better to just try to load them at start up (most of them are png or
tiff files):
@interface NSBundle(NameCacheImages)
- (void) cacheNamedImages;
@end
@implementation NSBundle(NameCacheImages)
- (void) cacheNamedImages;
{
NSArray *types = [NSImage imageFileTypes];
NSEnumerator *e = [types objectEnumerator];
NSString *type;
while ((type = [e nextObject]) != nil) {
NSArray *files = [self pathsForResourcesOfType: type inDirectory: nil];
NSEnumerator *e2 = [files objectEnumerator];
NSString *path;
while ((path = [e2 nextObject]) != nil) {
NSString *name = [[path lastPathComponent]
stringByDeletingPathExtension];
NSImage *image = [NSImage imageNamed:name];
if (!image) {
NSImage *image = [[NSImage alloc] initByReferencingFile:path];
if (image) {
[image setName: name];
}
}
}
}
}
@end
The result was that it cruised through the 74 images in 0.084809
seconds, so I think I can live with that...
Glenn Andreas <email_removed>
<http://www.gandreas.com/> wicked fun!
quadrium2 | build, mutate, evolve, animate | images, textures,
fractals, art
| Related mails | Author | Date |
|---|---|---|
| glenn andreas | Jan 11, 21:10 | |
| David Spooner | Jan 11, 22:08 | |
| Ricky Sharp | Jan 11, 22:34 | |
| glenn andreas | Jan 11, 23:12 |






Cocoa mail archive

