I don’t quite understand how this is supposed to work…
I have an App Logo image in the upper corner of my app; I want to create the image one time, and then just get it from the ImageCache when it needs to be redrawn
int dataSize = 0;
const char* resourceName = "kmoLogo_png";
auto hashCode = (juce::String(resourceName) + "_iconCacheSalt").hashCode64();
auto appIcon = juce::ImageCache::getFromHashCode(hashCode);
if (appIcon.isNull())
{
const char* imageData = BinaryData::getNamedResource(resourceName, dataSize);
appIcon = ImageFileFormat::loadFrom(imageData, (size_t) dataSize);
ImageCache::addImageToCache(appIcon, hashCode);
DBG(“create new image”);
}
g.drawImageWithin(appIcon, iconRect.getX(), iconRect.getY(), iconRect.getWidth(), iconRect.getHeight(), RectanglePlacement::centred );
The problem is, the image is apparently released from the cache after a certain period (by the Timer in ImageCache), and debugging shows it is constantly being recreated
Am I misunderstanding the concept? Why does the timeout default to removing an image after about 5 seconds? I suppose I could just call ImageCache::setCacheTimeout() with some really large integer, but why does it work like this?
The image data is already in memory (BinaryData), so the normal pattern would be to use the higher level ImageCache::getFromMemory vs. interacting directly with the cache, I think. But it’s a good question about the timeout. Is it 5 seconds after the last juce::Image goes out of scope?
Actually, I didn’t show it, but the main reason I do it that way is because on Windows I’m using the gin module to resize the image before adding it to the cache, for better results.
auto iconRect = getLocalBounds();
int dataSize = 0;
const char* resourceName = "kmoLogo_png";
// since we are using gin (on WINDOWS), we must add and retrieve the image
// from/to the cache manually with a hashcode, which makes this whole thing more complicated
auto hashCode = (juce::String(resourceName) + "_iconCacheSalt").hashCode64();
auto appIcon = juce::ImageCache::getFromHashCode(hashCode);
if (appIcon.isNull())
{
const char* imageData = BinaryData::getNamedResource(resourceName, dataSize);
#if WIN_VERSION // - use gin
auto ginScaleFactor = 2;
auto image = ImageFileFormat::loadFrom(imageData, (size_t) dataSize);
appIcon = gin::applyResize(image, iconWidth * ginScaleFactor, iconWidth * ginScaleFactor); // double-size
#else
appIcon = ImageFileFormat::loadFrom(imageData, (size_t) dataSize);
#endif //WIN_VERSION
ImageCache::addImageToCache(appIcon, hashCode);
}
g.drawImageWithin(appIcon, iconRect.getX(), iconRect.getY(), iconRect.getWidth(), iconRect.getHeight(), RectanglePlacement::centred );
But yes, for some reason the default timeout is 5 seconds and I don’t understand what use case this is for, then… I assumed it was so you don’t have to keep recreating images…
I’m also curious. To me the short timeout and the history going back 17+ years indicates that the existence of ImageCache is to resolve a specific internal need (e.g. sharing an underlying image vs. allocating new memory when image is used in more than one place) vs. being a good generalized solution. But I don’t have experience with it directly.
Unless appIcon is being used in multiple places, could you keep things simple and persist it as a member variable of the component?