Index: wp-includes/js/tinymce/plugins/wpeditimage/css/editimage.css
===================================================================
--- wp-includes/js/tinymce/plugins/wpeditimage/css/editimage.css	(revision 18924)
+++ wp-includes/js/tinymce/plugins/wpeditimage/css/editimage.css	(working copy)
@@ -344,6 +344,14 @@
 	font-weight: bold;
 }
 
+img.link-align {
+        height:22px;
+	vertical-align:middle;
+	margin-bottom:2px;
+	margin-left:-5px;
+	cursor:pointer;
+}
+
 * html #sidemenu li {
 	zoom: 100%;
 }
Index: wp-includes/js/tinymce/plugins/wpeditimage/editimage.html
===================================================================
--- wp-includes/js/tinymce/plugins/wpeditimage/editimage.html	(revision 18924)
+++ wp-includes/js/tinymce/plugins/wpeditimage/editimage.html	(working copy)
@@ -4,7 +4,7 @@
 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
 <title></title>
 
-<script type="text/javascript" src="js/editimage.js?ver=327"></script>
+<script type="text/javascript" src="js/editimage.dev.js"></script>
 <script type="text/javascript" src="../../utils/form_utils.js?ver=3223"></script>
 
 <link rel="stylesheet" href="css/editimage.css?ver=327" type="text/css" media="all" />
@@ -148,12 +148,13 @@
 			</th>
 			<td class="field">
 				<label for="width">{#wpeditimage.width}</label>
-				<input type="text" maxlength="5" id="width" name="width"  value="" />
+				<input type="text" maxlength="5" onkeyup="wpImage.possiblyConstrain(this);" id="width" name="width"  value="" />
 
 				<label for="height">{#wpeditimage.height}</label>
-				<input type="text" maxlength="5" id="height" name="height" value="" />
+				<input type="text" maxlength="5" onkeyup="wpImage.possiblyConstrain(this);" id="height" name="height" value="" />
+				<img id="constrain_proportions" class="link-align" title="Constraining Proportions" src="img/link.png" name="constrain_proportions" onclick="wpImage.toggleConstrain();" />
+				<input type="button" class="button" id="orig_size" name="orig_size" value="{#wpeditimage.orig_size}" onclick="wpImage.origSize();" />
 
-				<input type="button" class="button" id="orig_size" name="orig_size" value="{#wpeditimage.orig_size}" onclick="wpImage.origSize();" />
 			</td>
 		</tr>
 
Index: wp-includes/js/tinymce/plugins/wpeditimage/js/editimage.dev.js
===================================================================
--- wp-includes/js/tinymce/plugins/wpeditimage/js/editimage.dev.js	(revision 18924)
+++ wp-includes/js/tinymce/plugins/wpeditimage/js/editimage.dev.js	(working copy)
@@ -222,6 +222,55 @@
 		}
 	},
 
+    setConstrainedProportions: function() {
+	var f = document.forms[0], t = this;
+
+	if (t.I('img_classes').value.indexOf('constrained ') != -1 || t.I('img_classes').value.indexOf(' constrained') != -1) {
+	    f.constrain_proportions.className += (f.constrain_proportions.className == '') ? 'constrained' : ' constrained';
+    	    f.constrain_proportions.title = 'Constraining Proportions';
+	    f.constrain_proportions.src = 'img/link.png';
+	} else {
+	    f.constrain_proportions.className = f.constrain_proportions.className.replace(/(\sconstrained|constrained\s|constrained)/, '');
+	    f.constrain_proportions.src = 'img/broken_link.png';
+	    f.constrain_proportions.title = 'Not Constraining';
+	}
+    },
+
+    toggleConstrain: function() {
+	var f = document.forms[0], t = this;
+	
+	if (f.constrain_proportions.className.indexOf('constrained') != -1) {
+	    f.constrain_proportions.className = f.constrain_proportions.className.replace(/(\sconstrained|constrained\s|constrained)/, '');
+	    f.constrain_proportions.src = 'img/broken_link.png';
+	    f.constrain_proportions.title = 'Not Constraining';
+    	    t.I('img_classes').value = t.I('img_classes').value.replace(/(\sconstrained|constrained\s)/, '');
+	} else {
+	    f.constrain_proportions.title = 'Constraining Proportions';
+	    f.constrain_proportions.src = 'img/link.png';
+	    f.constrain_proportions.className += (f.constrain_proportions.className == '') ? 'constrained' : ' constrained';
+    	    t.I('img_classes').value += ' constrained';
+	}
+    },
+
+    possiblyConstrain : function(el) {
+	var f = document.forms[0], t = this;
+
+	if (f.constrain_proportions.className.indexOf('constrained') == -1) {
+	    return;
+        }
+
+	var newOriginalImage = new Image();
+	newOriginalImage.src = t.I('img_demo').src;
+
+	var widthToHeightRatio = (newOriginalImage.width  / newOriginalImage.height);
+	var heightToWidthRatio = (newOriginalImage.height / newOriginalImage.width);
+
+	if (el.id == 'width') {
+	    f.height.value = (isNaN(el.value * heightToWidthRatio)) ? '' : Math.round(el.value * heightToWidthRatio);
+	} else if (el.id == 'height') {
+	    f.width.value  = (isNaN(el.value * widthToHeightRatio)) ? '' : Math.round(el.value * widthToHeightRatio);
+	}
+    },
 	origSize : function() {
 		var t = this, f = document.forms[0], el = t.I('s100');
 
@@ -287,6 +336,8 @@
 		f.img_classes.value = c;
 		f.img_style.value = ed.dom.getAttrib(el, 'style');
 
+                t.setConstrainedProportions();
+
 		// Move attribs to styles
 		if ( dom.getAttrib(el, 'hspace') )
 			t.updateStyle('hspace');
