Bug 8548 - UIImage.Scale isn't using the @2x image for retina displays
Summary: UIImage.Scale isn't using the @2x image for retina displays
Alias: None
Product: iOS
Classification: Xamarin
Component: General ()
Version: 6.1.x
Hardware: Macintosh Mac OS
: --- normal
Target Milestone: Untriaged
Assignee: Bugzilla
Depends on:
Reported: 2012-11-21 15:11 UTC by Shawn Baker
Modified: 2013-04-29 10:05 UTC (History)
2 users (show)

Is this bug a regression?: ---
Last known good build:

Source code that demonstrates the problem. (9.15 KB, application/zip)
2012-11-21 15:11 UTC, Shawn Baker

Notice (2018-05-24): bugzilla.xamarin.com is now in read-only mode.

Please join us on Visual Studio Developer Community and in the Xamarin and Mono organizations on GitHub to continue tracking issues. Bugzilla will remain available for reference in read-only mode. We will continue to work on open Bugzilla bugs, copy them to the new locations as needed for follow-up, and add the new items under Related Links.

Our sincere thanks to everyone who has contributed on this bug tracker over the years. Thanks also for your understanding as we make these adjustments and improvements for the future.

Please create a new report on Developer Community or GitHub with your current version information, steps to reproduce, and relevant error messages or log files if you are hitting an issue that looks similar to this resolved bug and you do not yet see a matching new report.

Related Links:

Description Shawn Baker 2012-11-21 15:11:31 UTC
Created attachment 2992 [details]
Source code that demonstrates the problem.

I have two images in my app, blue_button.png and blue_button@2x.png, and I use the following code to create the background image for a button:

    UIImage image = UIImage.FromBundle("button_blue");
    image = image.CreateResizableImage(new UIEdgeInsets(10, 10, 10, 10));
    image = image.Scale(new SizeF(100, image.Size.Height));
    button.SetBackgroundImage(image, UIControlState.Normal);

On a retina display device, this code creates a button that uses blue_button.png instead of blue_button@2x.png. On the other hand, if I replace the call to UIImage.Scale with the following code, it uses blue_button@2x.png:

    image = ScaleImage(image, new SizeF(100, image.Size.Height));
    private UIImage ScaleImage(UIImage image, SizeF size)
        UIGraphics.BeginImageContextWithOptions(size, false, 0);
        image.Draw(new RectangleF(PointF.Empty, size));
        image = UIGraphics.GetImageFromCurrentImageContext();
        return image;

I suspect that the Scale method is using BeginImageContext instead of BeginImageContextWithOptions.

I've attached the program I used to figure this out. It creates two buttons using the two scaling methods described above. The easiest way to see the difference is to zoom in on a screenshot of the running program.
Comment 1 Rolf Bjarne Kvinge [MSFT] 2012-11-21 18:10:53 UTC
Thank you for tracking it down and providing a solution. This has now been fixed.

The next release with this fix will likely be 6.0.8.

master: 481c344e91fb3703f251b424f51540464f72ed60
ios6: 67a672028470c916d80506e844224f40113f6e11
Comment 2 Rolf Bjarne Kvinge [MSFT] 2013-04-29 10:05:00 UTC
The fix had to be reverted, because it broke existing code (see bug #11069).

I've added a new Scale overload, which does what you want:

UIImage.Scale (SizeF size, float scaleFactor); 

this mimics BeginImageContextWithOptions' scale factor, where you can use the scale factor of the device if you pass in 0. In other words your code will look like this once fixed:

image = image.Scale(new SizeF(100, image.Size.Height), 0);

master: 190bc39ee7708b092a9a636ac45f9494b46accf0