Index: src/wp-admin/js/customize-controls.js
===================================================================
--- src/wp-admin/js/customize-controls.js	(revision 32818)
+++ src/wp-admin/js/customize-controls.js	(working copy)
@@ -1850,31 +1850,31 @@
 			this.btnNew.on( 'click', this.openMedia );
 			this.btnRemove.on( 'click', this.removeImage );
 
-			api.HeaderTool.currentHeader = this.getInitialHeaderImage();
+			api.ImageCrop.currentHeader = this.getInitialHeaderImage();
 
-			new api.HeaderTool.CurrentView({
-				model: api.HeaderTool.currentHeader,
+			new api.ImageCrop.CurrentView({
+				model: api.ImageCrop.currentHeader,
 				el: '#customize-control-header_image .current .container'
 			});
 
-			new api.HeaderTool.ChoiceListView({
-				collection: api.HeaderTool.UploadsList = new api.HeaderTool.ChoiceList(),
+			new api.ImageCrop.ChoiceListView({
+				collection: api.ImageCrop.UploadsList = new api.ImageCrop.ChoiceList(),
 				el: '#customize-control-header_image .choices .uploaded .list'
 			});
 
-			new api.HeaderTool.ChoiceListView({
-				collection: api.HeaderTool.DefaultsList = new api.HeaderTool.DefaultsList(),
+			new api.ImageCrop.ChoiceListView({
+				collection: api.ImageCrop.DefaultsList = new api.ImageCrop.DefaultsList(),
 				el: '#customize-control-header_image .choices .default .list'
 			});
 
-			api.HeaderTool.combinedList = api.HeaderTool.CombinedList = new api.HeaderTool.CombinedList([
-				api.HeaderTool.UploadsList,
-				api.HeaderTool.DefaultsList
+			api.ImageCrop.combinedList = api.ImageCrop.CombinedList = new api.ImageCrop.CombinedList([
+				api.ImageCrop.UploadsList,
+				api.ImageCrop.DefaultsList
 			]);
 		},
 
 		/**
-		 * Returns a new instance of api.HeaderTool.ImageModel based on the currently
+		 * Returns a new instance of api.ImageCrop.ImageModel based on the currently
 		 * saved header image (if any).
 		 *
 		 * @since 4.2.0
@@ -1883,7 +1883,7 @@
 		 */
 		getInitialHeaderImage: function() {
 			if ( ! api.get().header_image || ! api.get().header_image_data || _.contains( [ 'remove-header', 'random-default-image', 'random-uploaded-image' ], api.get().header_image ) ) {
-				return new api.HeaderTool.ImageModel();
+				return new api.ImageCrop.ImageModel();
 			}
 
 			// Get the matching uploaded image object.
@@ -1899,7 +1899,7 @@
 				};
 			}
 
-			return new api.HeaderTool.ImageModel({
+			return new api.ImageCrop.ImageModel({
 				header: currentHeaderObject,
 				choice: currentHeaderObject.url.split( '/' ).pop()
 			});
@@ -1925,7 +1925,7 @@
 			realWidth = attachment.get('width');
 			realHeight = attachment.get('height');
 
-			this.headerImage = new api.HeaderTool.ImageModel();
+			this.headerImage = new api.ImageCrop.ImageModel();
 			this.headerImage.set({
 				themeWidth: xInit,
 				themeHeight: yInit,
@@ -2050,7 +2050,7 @@
 		},
 
 		/**
-		 * Creates a new wp.customize.HeaderTool.ImageModel from provided
+		 * Creates a new wp.customize.ImageCrop.ImageModel from provided
 		 * header image data and inserts it into the user-uploaded headers
 		 * collection.
 		 *
@@ -2078,12 +2078,12 @@
 				data.height = height;
 			}
 
-			choice = new api.HeaderTool.ImageModel({
+			choice = new api.ImageCrop.ImageModel({
 				header: data,
 				choice: url.split('/').pop()
 			});
-			api.HeaderTool.UploadsList.add(choice);
-			api.HeaderTool.currentHeader.set(choice.toJSON());
+			api.ImageCrop.UploadsList.add(choice);
+			api.ImageCrop.currentHeader.set(choice.toJSON());
 			choice.save();
 			choice.importImage();
 		},
@@ -2093,8 +2093,8 @@
 		 * the currently selected one.
 		 */
 		removeImage: function() {
-			api.HeaderTool.currentHeader.trigger('hide');
-			api.HeaderTool.CombinedList.trigger('control:removeImage');
+			api.ImageCrop.currentHeader.trigger('hide');
+			api.ImageCrop.CombinedList.trigger('control:removeImage');
 		}
 
 	});
Index: src/wp-includes/class-wp-customize-control.php
===================================================================
--- src/wp-includes/class-wp-customize-control.php	(revision 32818)
+++ src/wp-includes/class-wp-customize-control.php	(working copy)
@@ -997,33 +997,24 @@
 }
 
 /**
- * Customize Header Image Control class.
+ * Customize Cropped Image Control class.
  *
- * @since 3.4.0
+ * @since 4.3.0
  *
  * @see WP_Customize_Image_Control
  */
-class WP_Customize_Header_Image_Control extends WP_Customize_Image_Control {
-	public $type = 'header';
-	public $uploaded_headers;
-	public $default_headers;
+class WP_Customize_Cropped_Image_Control extends WP_Customize_Image_Control {
+	public $type = 'cropped-image';
 
-	/**
-	 * @param WP_Customize_Manager $manager
-	 */
-	public function __construct( $manager ) {
-		parent::__construct( $manager, 'header_image', array(
-			'label'    => __( 'Header Image' ),
-			'settings' => array(
-				'default' => 'header_image',
-				'data'    => 'header_image_data',
-			),
-			'section'  => 'header_image',
-			'removed'  => 'remove-header',
-			'get_url'  => 'get_header_image',
-		) );
+	protected $width  = 150;
+	protected $height = 150;
+	protected $flex_width  = false;
+	protected $flex_height = false;
+	protected $localized_name;
+	protected $current_title = '';
 
-	}
+	protected $uploaded_images = array();
+	protected $default_images  = array();
 
 	/**
 	 * @access public
@@ -1034,20 +1025,19 @@
 
 		$this->prepare_control();
 
-		wp_localize_script( 'customize-views', '_wpCustomizeHeader', array(
+		wp_localize_script( 'customize-views', $this->localized_name, array(
 			'data' => array(
-				'width' => absint( get_theme_support( 'custom-header', 'width' ) ),
-				'height' => absint( get_theme_support( 'custom-header', 'height' ) ),
-				'flex-width' => absint( get_theme_support( 'custom-header', 'flex-width' ) ),
-				'flex-height' => absint( get_theme_support( 'custom-header', 'flex-height' ) ),
-				'currentImgSrc' => $this->get_current_image_src(),
+				'width' => absint( $this->width ),
+				'height' => absint( $this->height ),
+				'flex-width' => absint( $this->flex_width ),
+				'flex-height' => absint( $this->flex_height ),
 			),
 			'nonces' => array(
 				'add' => wp_create_nonce( 'header-add' ),
 				'remove' => wp_create_nonce( 'header-remove' ),
 			),
-			'uploads' => $this->uploaded_headers,
-			'defaults' => $this->default_headers
+			'uploads'  => $this->uploaded_images,
+			'defaults' => $this->default_images
 		) );
 
 		parent::enqueue();
@@ -1054,54 +1044,11 @@
 	}
 
 	/**
-	 *
-	 * @global Custom_Image_Header $custom_image_header
-	 */
-	public function prepare_control() {
-		global $custom_image_header;
-		if ( empty( $custom_image_header ) ) {
-			return;
-		}
-
-		// Process default headers and uploaded headers.
-		$custom_image_header->process_default_headers();
-		$this->default_headers = $custom_image_header->get_default_header_images();
-		$this->uploaded_headers = $custom_image_header->get_uploaded_header_images();
-	}
-
-	/**
 	 * @access public
 	 */
-	public function print_header_image_template() {
+	public function print_crop_image_template() {
 		?>
-		<script type="text/template" id="tmpl-header-choice">
-			<# if (data.random) { #>
-			<button type="button" class="button display-options random">
-				<span class="dashicons dashicons-randomize dice"></span>
-				<# if ( data.type === 'uploaded' ) { #>
-					<?php _e( 'Randomize uploaded headers' ); ?>
-				<# } else if ( data.type === 'default' ) { #>
-					<?php _e( 'Randomize suggested headers' ); ?>
-				<# } #>
-			</button>
-
-			<# } else { #>
-
-			<# if (data.type === 'uploaded') { #>
-				<button type="button" class="dashicons dashicons-no close"><span class="screen-reader-text"><?php _e( 'Remove image' ); ?></span></button>
-			<# } #>
-
-			<button type="button" class="choice thumbnail"
-				data-customize-image-value="{{{data.header.url}}}"
-				data-customize-header-image-data="{{JSON.stringify(data.header)}}">
-				<span class="screen-reader-text"><?php _e( 'Set image' ); ?></span>
-				<img src="{{{data.header.thumbnail_url}}}" alt="{{{data.header.alt_text || data.header.description}}}">
-			</button>
-
-			<# } #>
-		</script>
-
-		<script type="text/template" id="tmpl-header-current">
+		<script type="text/template" id="tmpl-cropped-current">
 			<# if (data.choice) { #>
 				<# if (data.random) { #>
 
@@ -1138,63 +1085,51 @@
 	}
 
 	/**
-	 * @return string|void
-	 */
-	public function get_current_image_src() {
-		$src = $this->value();
-		if ( isset( $this->get_url ) ) {
-			$src = call_user_func( $this->get_url, $src );
-			return $src;
-		}
-	}
-
-	/**
 	 * @access public
 	 */
 	public function render_content() {
-		$this->print_header_image_template();
-		$visibility = $this->get_current_image_src() ? '' : ' style="display:none" ';
-		$width = absint( get_theme_support( 'custom-header', 'width' ) );
-		$height = absint( get_theme_support( 'custom-header', 'height' ) );
+		$this->print_crop_image_template();
+
+		$width = absint( $this->width );
+		$height = absint( $this->height );
 		?>
 
-
 		<div class="customize-control-content">
 			<p class="customizer-section-intro">
 				<?php
 				if ( $width && $height ) {
-					printf( __( 'While you can crop images to your liking after clicking <strong>Add new image</strong>, your theme recommends a header size of <strong>%s &times; %s</strong> pixels.' ), $width, $height );
+					printf( __( 'While you can crop images to your liking after clicking <strong>Add new image</strong>, your theme recommends a size of <strong>%s &times; %s</strong> pixels.' ), $width, $height );
 				} elseif ( $width ) {
-					printf( __( 'While you can crop images to your liking after clicking <strong>Add new image</strong>, your theme recommends a header width of <strong>%s</strong> pixels.' ), $width );
+					printf( __( 'While you can crop images to your liking after clicking <strong>Add new image</strong>, your theme recommends a width of <strong>%s</strong> pixels.' ), $width );
 				} else {
-					printf( __( 'While you can crop images to your liking after clicking <strong>Add new image</strong>, your theme recommends a header height of <strong>%s</strong> pixels.' ), $height );
+					printf( __( 'While you can crop images to your liking after clicking <strong>Add new image</strong>, your theme recommends a height of <strong>%s</strong> pixels.' ), $height );
 				}
 				?>
 			</p>
 			<div class="current">
 				<span class="customize-control-title">
-					<?php _e( 'Current header' ); ?>
+					<?php echo $this->current_title; ?>
 				</span>
 				<div class="container">
 				</div>
 			</div>
 			<div class="actions">
-				<?php /* translators: Hide as in hide header image via the Customizer */ ?>
-				<button type="button"<?php echo $visibility ?> class="button remove"><?php _ex( 'Hide image', 'custom header' ); ?></button>
-				<?php /* translators: New as in add new header image via the Customizer */ ?>
-				<button type="button" class="button new"><?php _ex( 'Add new image', 'header image' ); ?></button>
+				<?php /* translators: Hide as in hide cropped image via the Customizer */ ?>
+				<button type="button" class="button remove"><?php _ex( 'Hide image', 'crop image' ); ?></button>
+				<?php /* translators: New as in add new cropped image via the Customizer */ ?>
+				<button type="button" class="button new"><?php _ex( 'Add new image', 'cropped image' ); ?></button>
 				<div style="clear:both"></div>
 			</div>
 			<div class="choices">
-				<span class="customize-control-title header-previously-uploaded">
-					<?php _ex( 'Previously uploaded', 'custom headers' ); ?>
+				<span class="customize-control-title cropped-image-previously-uploaded">
+					<?php _ex( 'Previously uploaded', 'cropped images' ); ?>
 				</span>
 				<div class="uploaded">
 					<div class="list">
 					</div>
 				</div>
-				<span class="customize-control-title header-default">
-					<?php _ex( 'Suggested', 'custom headers' ); ?>
+				<span class="customize-control-title cropped-image-default">
+					<?php _ex( 'Suggested', 'cropped images' ); ?>
 				</span>
 				<div class="default">
 					<div class="list">
@@ -1207,6 +1142,100 @@
 }
 
 /**
+ * Customize Header Image Control class.
+ *
+ * @since 3.4.0
+ *
+ * @see WP_Customize_Cropped_Image_Control
+ */
+class WP_Customize_Header_Image_Control extends WP_Customize_Cropped_Image_Control {
+	public $type = 'header';
+
+	/**
+	 * @param WP_Customize_Manager $manager
+	 */
+	public function __construct( $manager ) {
+		parent::__construct( $manager, 'header_image', array(
+			'label'    => __( 'Header Image' ),
+			'settings' => array(
+				'default' => 'header_image',
+				'data'    => 'header_image_data',
+			),
+			'section'       => 'header_image',
+			'removed'       => 'remove-header',
+			'get_url'       => 'get_header_image',
+			'current_title' => __( 'Current header' ),
+		) );
+
+		$this->width  = get_theme_support( 'custom-header', 'width' );
+		$this->height = get_theme_support( 'custom-header', 'height' );
+		$this->flex_width  = get_theme_support( 'custom-header', 'flex-width' );
+		$this->flex_height = get_theme_support( 'custom-header', 'flex-height' );
+		$this->localized_name = '_wpCustomizeHeader';
+	}
+
+	/**
+	 *
+	 * @global Custom_Image_Header $custom_image_header
+	 */
+	public function prepare_control() {
+		global $custom_image_header;
+
+		if ( empty( $custom_image_header ) ) {
+			return;
+		}
+
+		// Process default headers and uploaded headers.
+		$custom_image_header->process_default_headers();
+		$this->default_images  = $custom_image_header->get_default_header_images();
+		$this->uploaded_images = $custom_image_header->get_uploaded_header_images();
+	}
+
+	/**
+	 * @access public
+	 */
+	public function print_header_image_template() {
+		?>
+		<script type="text/template" id="tmpl-header-choice">
+			<# if (data.random) { #>
+			<button type="button" class="button display-options random">
+				<span class="dashicons dashicons-randomize dice"></span>
+				<# if ( data.type === 'uploaded' ) { #>
+					<?php _e( 'Randomize uploaded headers' ); ?>
+				<# } else if ( data.type === 'default' ) { #>
+					<?php _e( 'Randomize suggested headers' ); ?>
+				<# } #>
+			</button>
+
+			<# } else { #>
+
+			<# if (data.type === 'uploaded') { #>
+				<button type="button" class="dashicons dashicons-no close"><span class="screen-reader-text"><?php _e( 'Remove image' ); ?></span></button>
+			<# } #>
+
+			<button type="button" class="choice thumbnail"
+				data-customize-image-value="{{{data.header.url}}}"
+				data-customize-header-image-data="{{JSON.stringify(data.header)}}">
+				<span class="screen-reader-text"><?php _e( 'Set image' ); ?></span>
+				<img src="{{{data.header.thumbnail_url}}}" alt="{{{data.header.alt_text || data.header.description}}}">
+			</button>
+
+			<# } #>
+		</script>
+		<?php
+	}
+
+	/**
+	 * @access public
+	 */
+	public function render_content() {
+		$this->print_header_image_template();
+
+		parent::render_content();
+	}
+}
+
+/**
  * Customize Theme Control class.
  *
  * @since 4.2.0
Index: src/wp-includes/js/customize-models.js
===================================================================
--- src/wp-includes/js/customize-models.js	(revision 32818)
+++ src/wp-includes/js/customize-models.js	(working copy)
@@ -1,11 +1,11 @@
 /* globals _wpCustomizeHeader, _ */
 (function( $, wp ) {
 	var api = wp.customize;
-	api.HeaderTool = {};
+	api.ImageCrop = {};
 
 
 	/**
-	 * wp.customize.HeaderTool.ImageModel
+	 * wp.customize.ImageCrop.ImageModel
 	 *
 	 * A header image. This is where saves via the Customizer API are
 	 * abstracted away, plus our own AJAX calls to add images to and remove
@@ -16,7 +16,7 @@
 	 * @constructor
 	 * @augments Backbone.Model
 	 */
-	api.HeaderTool.ImageModel = Backbone.Model.extend({
+	api.ImageCrop.ImageModel = Backbone.Model.extend({
 		defaults: function() {
 			return {
 				header: {
@@ -43,12 +43,12 @@
 
 		destroy: function() {
 			var data = this.get('header'),
-				curr = api.HeaderTool.currentHeader.get('header').attachment_id;
+				curr = api.ImageCrop.currentHeader.get('header').attachment_id;
 
 			// If the image we're removing is also the current header, unset
 			// the latter
 			if (curr && data.attachment_id === curr) {
-				api.HeaderTool.currentHeader.trigger('hide');
+				api.ImageCrop.currentHeader.trigger('hide');
 			}
 
 			wp.ajax.post( 'custom-header-remove', {
@@ -75,7 +75,7 @@
 				}
 			}
 
-			api.HeaderTool.combinedList.trigger('control:setImage', this);
+			api.ImageCrop.combinedList.trigger('control:setImage', this);
 		},
 
 		importImage: function() {
@@ -123,13 +123,13 @@
 
 
 	/**
-	 * wp.customize.HeaderTool.ChoiceList
+	 * wp.customize.ImageCrop.ChoiceList
 	 *
 	 * @constructor
 	 * @augments Backbone.Collection
 	 */
-	api.HeaderTool.ChoiceList = Backbone.Collection.extend({
-		model: api.HeaderTool.ImageModel,
+	api.ImageCrop.ChoiceList = Backbone.Collection.extend({
+		model: api.ImageCrop.ImageModel,
 
 		// Ordered from most recently used to least
 		comparator: function(model) {
@@ -137,7 +137,7 @@
 		},
 
 		initialize: function() {
-			var current = api.HeaderTool.currentHeader.get('choice').replace(/^https?:\/\//, ''),
+			var current = api.ImageCrop.currentHeader.get('choice').replace(/^https?:\/\//, ''),
 				isRandom = this.isRandomChoice(api.get().header_image);
 
 			// Overridable by an extending class
@@ -230,17 +230,17 @@
 
 
 	/**
-	 * wp.customize.HeaderTool.DefaultsList
+	 * wp.customize.ImageCrop.DefaultsList
 	 *
 	 * @constructor
-	 * @augments wp.customize.HeaderTool.ChoiceList
+	 * @augments wp.customize.ImageCrop.ChoiceList
 	 * @augments Backbone.Collection
 	 */
-	api.HeaderTool.DefaultsList = api.HeaderTool.ChoiceList.extend({
+	api.ImageCrop.DefaultsList = api.ImageCrop.ChoiceList.extend({
 		initialize: function() {
 			this.type = 'default';
 			this.data = _wpCustomizeHeader.defaults;
-			api.HeaderTool.ChoiceList.prototype.initialize.apply(this);
+			api.ImageCrop.ChoiceList.prototype.initialize.apply(this);
 		}
 	});
 
Index: src/wp-includes/js/customize-views.js
===================================================================
--- src/wp-includes/js/customize-views.js	(revision 32818)
+++ src/wp-includes/js/customize-views.js	(working copy)
@@ -5,18 +5,18 @@
 
 
 	/**
-	 * wp.customize.HeaderTool.CurrentView
+	 * wp.customize.ImageCrop.CurrentView
 	 *
-	 * Displays the currently selected header image, or a placeholder in lack
+	 * Displays the currently selected image, or a placeholder in lack
 	 * thereof.
 	 *
-	 * Instantiate with model wp.customize.HeaderTool.currentHeader.
+	 * Instantiate with model wp.customize.ImageCrop.currentHeader.
 	 *
 	 * @constructor
 	 * @augments wp.Backbone.View
 	 */
-	api.HeaderTool.CurrentView = wp.Backbone.View.extend({
-		template: wp.template('header-current'),
+	api.ImageCrop.CurrentView = wp.Backbone.View.extend({
+		template: wp.template('cropped-current'),
 
 		initialize: function() {
 			this.listenTo(this.model, 'change', this.render);
@@ -81,20 +81,20 @@
 
 
 	/**
-	 * wp.customize.HeaderTool.ChoiceView
+	 * wp.customize.ImageCrop.ChoiceView
 	 *
 	 * Represents a choosable header image, be it user-uploaded,
 	 * theme-suggested or a special Randomize choice.
 	 *
-	 * Takes a wp.customize.HeaderTool.ImageModel.
+	 * Takes a wp.customize.ImageCrop.ImageModel.
 	 *
-	 * Manually changes model wp.customize.HeaderTool.currentHeader via the
+	 * Manually changes model wp.customize.ImageCrop.currentHeader via the
 	 * `select` method.
 	 *
 	 * @constructor
 	 * @augments wp.Backbone.View
 	 */
-	api.HeaderTool.ChoiceView = wp.Backbone.View.extend({
+	api.ImageCrop.ChoiceView = wp.Backbone.View.extend({
 		template: wp.template('header-choice'),
 
 		className: 'header-view',
@@ -113,7 +113,7 @@
 			this.listenTo(this.model, 'change:selected', this.toggleSelected);
 
 			if (_.contains(properties, api.get().header_image)) {
-				api.HeaderTool.currentHeader.set(this.extendedModel());
+				api.ImageCrop.currentHeader.set(this.extendedModel());
 			}
 		},
 
@@ -135,14 +135,14 @@
 			});
 		},
 
-		getHeight: api.HeaderTool.CurrentView.prototype.getHeight,
+		getHeight: api.ImageCrop.CurrentView.prototype.getHeight,
 
-		setPlaceholder: api.HeaderTool.CurrentView.prototype.setPlaceholder,
+		setPlaceholder: api.ImageCrop.CurrentView.prototype.setPlaceholder,
 
 		select: function() {
 			this.preventJump();
 			this.model.save();
-			api.HeaderTool.currentHeader.set(this.extendedModel());
+			api.ImageCrop.currentHeader.set(this.extendedModel());
 		},
 
 		preventJump: function() {
@@ -163,17 +163,17 @@
 
 
 	/**
-	 * wp.customize.HeaderTool.ChoiceListView
+	 * wp.customize.ImageCrop.ChoiceListView
 	 *
 	 * A container for ChoiceViews. These choices should be of one same type:
 	 * user-uploaded headers or theme-defined ones.
 	 *
-	 * Takes a wp.customize.HeaderTool.ChoiceList.
+	 * Takes a wp.customize.ImageCrop.ChoiceList.
 	 *
 	 * @constructor
 	 * @augments wp.Backbone.View
 	 */
-	api.HeaderTool.ChoiceListView = wp.Backbone.View.extend({
+	api.ImageCrop.ChoiceListView = wp.Backbone.View.extend({
 		initialize: function() {
 			this.listenTo(this.collection, 'add', this.addOne);
 			this.listenTo(this.collection, 'remove', this.render);
@@ -191,7 +191,7 @@
 		addOne: function(choice) {
 			var view;
 			choice.set({ collection: this.collection });
-			view = new api.HeaderTool.ChoiceView({ model: choice });
+			view = new api.ImageCrop.ChoiceView({ model: choice });
 			this.$el.append(view.render().el);
 		},
 
@@ -208,15 +208,15 @@
 
 
 	/**
-	 * wp.customize.HeaderTool.CombinedList
+	 * wp.customize.ImageCrop.CombinedList
 	 *
-	 * Aggregates wp.customize.HeaderTool.ChoiceList collections (or any
+	 * Aggregates wp.customize.ImageCrop.ChoiceList collections (or any
 	 * Backbone object, really) and acts as a bus to feed them events.
 	 *
 	 * @constructor
 	 * @augments wp.Backbone.View
 	 */
-	api.HeaderTool.CombinedList = wp.Backbone.View.extend({
+	api.ImageCrop.CombinedList = wp.Backbone.View.extend({
 		initialize: function(collections) {
 			this.collections = collections;
 			this.on('all', this.propagate, this);
