Bug 11069 - UIImage.Scale generates images that's twice the requested size
Summary: UIImage.Scale generates images that's twice the requested size
Alias: None
Product: iOS
Classification: Xamarin
Component: Xamarin.iOS.dll ()
Version: 6.2.x
Hardware: PC Mac OS
: --- normal
Target Milestone: Untriaged
Assignee: Bugzilla
: 12247 ()
Depends on:
Reported: 2013-03-12 09:53 UTC by Aleksander Heintz
Modified: 2013-07-23 04:51 UTC (History)
4 users (show)

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

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 Aleksander Heintz 2013-03-12 09:53:28 UTC
I'm guessing that after the introduction of the fix to bug: https://bugzilla.xamarin.com/show_bug.cgi?id=8548, a few use-cases were left out. If you run the code attached bellow you will see that the current usage is not very intuitive. If you scale an image to 240x240px, then save it to disk, and reload it, you suddenly have an image of 480x480px. I haven't tested this on non-retina devices, but this probably means that if I want the same image-size on both retina and non-retina devices, I have to check to see which one I'm currently on before I decide which size I want to scale the image to.

Test-code (ViewController):

using System;
using MonoTouch.UIKit;
using System.Drawing;
using System.Runtime.InteropServices;
using System.IO;

namespace ScaleTest
	public class ScaleTestViewController : UIViewController
		UIButton _btn;
		UIImagePickerController picker;

		public ScaleTestViewController ()
			_btn = new UIButton (UIButtonType.RoundedRect);
			_btn.SetTitle ("Take Picture", UIControlState.Normal);
			_btn.TouchUpInside += (sender, e) => {
				picker = new UIImagePickerController ();
				picker.SourceType = UIImagePickerControllerSourceType.PhotoLibrary;
				picker.FinishedPickingImage += HandlePickerFinishedPickingImage;
				picker.FinishedPickingMedia += HandlePickerFinishedPickingMedia;
				picker.Canceled += HandlePickerCanceled;
				picker.AllowsEditing = false;
				picker.SourceType = UIImagePickerControllerSourceType.Camera;
				picker.CameraCaptureMode = UIImagePickerControllerCameraCaptureMode.Photo;
				picker.ShowsCameraControls = true;
				PresentViewController(picker, true, () => {});
			_btn.Frame = new System.Drawing.RectangleF (100, 100, 100, 100);

			View.Add (_btn);

		void HandlePickerCanceled (object sender, EventArgs e)
			TearDownPicker ();

		void HandlePickerFinishedPickingImage (object sender, UIImagePickerImagePickedEventArgs e)
			SaveImage (e.Image);
			TearDownPicker ();
		void HandlePickerFinishedPickingMedia (object sender, UIImagePickerMediaPickedEventArgs e)
			SaveImage (e.EditedImage ?? e.OriginalImage);
			TearDownPicker ();

		void TearDownPicker ()
			picker.FinishedPickingImage -= HandlePickerFinishedPickingImage;
			picker.FinishedPickingMedia -= HandlePickerFinishedPickingMedia;
			picker.Canceled -= HandlePickerCanceled;
			DismissViewController (true, () => {});
			picker.Dispose ();
			picker = null;

		public static UIImage ScaleMax (UIImage img, int width, int height)
			var size = new SizeF(width, height);
			var oSize = img.Size;
			var scaleX = oSize.Width / size.Width;
			var scaleY = oSize.Height / size.Height;
			var scale = Math.Max (scaleX, scaleY);
			scale = Math.Max (scale, 1);
			size = new SizeF((float)Math.Floor(oSize.Width / scale), (float)Math.Floor(oSize.Height / scale));
			return img.Scale (size);

		void SaveImage (UIImage image)
			var img = ScaleMax(image, 640, 640);
			Console.WriteLine ("Scaled image size: " + img.Size);
			var bytes = img.AsJPEG(0.6f);
			byte[] data = new byte[bytes.Length];
			Marshal.Copy (bytes.Bytes, data, 0, data.Length);
			bytes.Dispose ();
			var ms = new MemoryStream (data);

			var file = File.Create (Path.Combine (Environment.GetFolderPath (Environment.SpecialFolder.Personal), "test.jpg"));
			ms.CopyTo (file);
			file.Flush ();
			file.Dispose ();
			ms.Dispose ();

			var i2 = UIImage.FromFile (Path.Combine (Environment.GetFolderPath (Environment.SpecialFolder.Personal), "test.jpg"));
			Console.WriteLine ("Saved image size: " + i2.Size);
Comment 1 Dean Cleaver 2013-04-26 17:23:43 UTC
I'm noticing the same issue - no code has changed in my app at all, but now my scaled images are twice as big, and the cropped images that were supposed to be centered thumbs are now top left corner thumbs because the image they are cropping is twice as big as it expects.
Comment 2 Rolf Bjarne Kvinge [MSFT] 2013-04-29 10:05:59 UTC
I have reverted the fix for bug #8548 (and fixed it differently).

master: 41763882caf915c94ff2726e729e7d803e42bc35
Comment 3 Rolf Bjarne Kvinge [MSFT] 2013-07-23 04:51:58 UTC
*** Bug 12247 has been marked as a duplicate of this bug. ***