Images are Getting cached in UWP application - xaml

In my UWP application I am binding the images from azure. It is getting cached when it get the response. When I change the image in the azure it's not reflecting in my UI, Instead it display the image from cache.
Is there any way to clear the cache of my UWP application or to restrict the application to cache images?.

Have you tried CreateOptions="IgnoreImageCache"?
<Image>
<Image.Source>
<BitmapImage UriSource="{Binding Url}"
CreateOptions="IgnoreImageCache"
DecodePixelWidth="120"
DecodePixelHeight="120" />
</Image.Source>
</Image>
But make sure you set the proper decode pixel width/height to avoid using unnecessary memory.
According to the documentation -
You should only use BitmapCreateOptions.IgnoreImageCache in cases
where you know that the source image file as retrieved by Uniform
Resource Identifier (URI) has the potential to change over time.
Otherwise, setting CreateOptions to use
BitmapCreateOptions.IgnoreImageCache causes all newly retrieved image
sources to be decoded again, which can negatively impact performance.
So maybe try setting None as the default value for CreateOptions, and only update it to IgnoreImageCache once you are absolutely sure that the image has been updated by the cloud. Note CreateOptions is also a dependency property, so you should be able to use data binding too.

Related

Force Image control to re-download the image

I have an Image control on Page1.xaml that is pointing at a URL: http://www.example.com/blah.jpg
I navigate to Page2.xaml and upload a new image to that url using my WebAPI. I call Frame.GoBack() to navigate back to Page1.xaml.
The old image is still displayed in the Image control. How can I make sure that Image control re-downloads the image even though its at the same URL?
The only way I found was to append a query string to the end of the image. It's a bit of a hack and it can interfere with Save operations but it is effective.
Just to be clear, I set the property with the image url with a value like this:
"http://www.example.com/blah.jpg?id=" + Guid.NewGuid()
That triggers the RaisePropertyChanged event and the Image control is tricked into thinking the image changed.
Set the BitmapImage.CreateOptions property to IgnoreImageCache.
From MSDN:
The other possible value for CreateOptions is
BitmapCreateOptions.IgnoreImageCache. You should only use
BitmapCreateOptions.IgnoreImageCache in cases where you know that the
source image file as retrieved by URI has the potential to change over
time. Otherwise, setting CreateOptions to use
BitmapCreateOptions.IgnoreImageCache causes all newly retrieved image
sources to be decoded again, which can negatively impact performance.
...

Databinding uri source of imagebrush

In my application i am binding several properties to a custom user control, and everything works fine, except the images are not showing. For binding i have used the following codes:
Categories.Add(new Models.Category { Name = "Pizza", Count= 4, ImageUri = new Uri("Images/pizza.png", UriKind.Relative) });
I have also tried with different urikinds but the images are never showing.
what could go wrong? The images are in my solutions Images folder.
Use the ms-appx URI scheme:
ImageUri = new Uri("ms-appx:///Images/pizza.png");
Take care to really write ///.
Also make sure that the Build Action of the image file is set to Content, as pointed out in the other answer. Setting Copy to Output Directory does however not seem to be necessary.
Be sure you set the properties of the image so that it is available during runtime. Sometimes if employing Design Time data in Blend, you will see the images in Design Time, but then nothing during run time. The reason is that the images were never deployed with the rest of the solution. Be sure the Build Action on each image is set to Content and I usually set the Copy to Output Directory to Copy if Newer.

Is it possible to tell a Windows 8.1 app not to scale up specific elements?

I am referencing external image urls for the source property of an image element in my app.
I have 3 versions of the image at 100, 140 and 180 scales e.g.
myimage.scale-100.jpg
myimage.scale-140.jpg
myimage.scale-180.jpg
If the images lived in the app you would normally put the source like the following and Windows works out which image to load based on the resolution scale of the device:
ms-appx:///Assets/Images/myimage.jpg
However as my 3 images live externally I am having to work out the resolution scale and then build up the correct source string so that the correct image is loaded e.g:
http://www.mywebsite.com/myimage.scale-180.jpg
This works, however, windows is taking my image e.g. the 180 scale one myimage.scale-180.jpg, and then scaling it up by a further 180%, it doesn't know that I have loaded an image at the correct 180% scale already and that it doesn't need to scale it up!
Is there a way of telling it not to scale up specific image elements?
Update (added code):
The xaml image element:
<Image Source="{Binding Image, Converter={StaticResource ImageToExternalImagePathConverter}}" HorizontalAlignment="Left" VerticalAlignment="Top" Stretch="None" />
The converter used on the image element to determine the external image path (it works out the scale and uses the binding to build up the correct string).
public object Convert(object value, Type targetType, object parameter, string language)
{
ResolutionScale resolutionScale = Windows.Graphics.Display.DisplayInformation.GetForCurrentView().ResolutionScale;
string ImageScale = ".scale-100";
switch (resolutionScale)
{
case ResolutionScale.Scale140Percent:
ImageScale = ".scale-140";
break;
case ResolutionScale.Scale180Percent:
ImageScale = ".scale-180";
break;
}
//builds up the correct string e.g. http://www.mywebsite.com/myimage.scale-180.jpg
string externalPath = "http://www.mywebsite.com/" + (string)value + ImageScale + ".jpg";
return externalPath;
}
Update(added reference):
To further explain what I am currently doing see this link:
http://msdn.microsoft.com/en-us/library/windows/apps/hh465362.aspx
Manually load images based upon scale percentage at runtime If your
app is loading images at runtime using code, for example if you use
DirectX directly, not XAML or HTML to create your UI, use the
DisplayProperties.ResolutionScale property to determine the scale and
manually load images based upon scale percentage.
So that's what I am doing, but the problem is that Windows is scaling up the UI as it should to 140% or 180%, and that includes my manually loaded image. So if I manually load in an image that is already sized at 140%, it gets scaled up by Windows anyway and it DOES get physically bigger. If the images lived in the app package this problem wouldnt exist because Windows recognises the filename identifiers and doesnt scale them up (see below)
Use resource loading for bitmap images in the app package For bitmap
images stored in the app package, provide a separate image for each
scaling factor(100%, 140%, and 180%), and name your image files using
the "scale" naming convention described below. Windows loads the right
image for the current scale automatically.
How can I replicate the same behavior from Windows for images that live in the app package but for images that are external to the app and are loaded manually? Logically at the point at which I load the image in (code), I want to say to Windows, this image is already scaled correctly, don't upscale it by the resolution factor.
Try sizing grip property to false

How to save Image Control to local file in Windows 8?

I'm writing Client-Server application, in which I get item with Image Url. This Url is binded with Image control:
<Image Source{Binding ImageUrl} x:Name="img_avatar" Stretch="UniformToFill" Width="48" Height="48"/>
I want to save the image from Image.Source to the local folder without any methods which are using download operations.
Please help m someone !!!
There is no way to do what you ask about. When you set an Image control's source to a Uri - it gets converted to a BitmapImage which doesn't expose any API that would let you save the file or even extract a bitmap. If you want to avoid multiple downloads of the image you can download it as a file once and load a BitmapImage from the file instead of Uri.
I believe with a little bit of reflection hackery, it should be doable. But a lot better solutions exist, so yeah..
Either subclass Image or write attached property to handle logic. All you have to do, is just load image yourself into MemoryStream and create BitmapImage manually(behind subclassed Image or attached proeprty).
This way you can expose new property that gives direct access to MemoryStream, and from there you can save file to HDD without wasting precious memory.
Bonus points if you can also keep the Source="{Binding}" syntax while providing this functionality.

AWS SDK PHP version 2 - retrieving image dimensions?

Is it possible to retrieve the dimensions of an image stored on Amazon S3?
If the answer is no, are there any other ways around it other than downloading the image to my server to which sounds inefficient?
I'm using version 2 of the AWS SDK for PHP.
I've been looking through what is returned from the following code but doesn't seem to give dimensions.
$result = $s3->getObject(array(
'Bucket' => 'BUCKET_NAME',
'Key' => 'KEY_NAME'
));
var_dump($result);
I'm not 100% familiar with SDK2. With 1.5 you could do this
getimagesize($s3->get_object_url($bucket,$filename));
I think this is still possible as long as you can access publicly the image (or you have to find your way around authorized urls)
Obviously, your php must be enabled to open remote files.
I agree with the db cache. I run every image filename through a class that checks mysql for a match. If it finds one, it returns width, height and a preformatted sizetag ready to go. If the image and size are not found, it uses getimagesize() to return the same info, which it stores for next time. I also built in a resize method should I want to cheat a bit and resize the sizetag (but not the file) proportionally on the fly.
I don't know if storing the info is faster than getimagesize() as it downloads. S3 is pretty fast.
Due to lack of response I'll presume it's not possible... Didn't r3ally want to do it with JavaScript but this is how I did it.
<img src="image.jpg" id="image" />
<script>
// This runs after the image has loaded
$('#image').load(function() {
// Use the below code to get the height and width
// document.getElementById('image').width
// document.getElementById('image').height
});
</script>