Index: src/wp-admin/includes/ajax-actions.php
===================================================================
--- src/wp-admin/includes/ajax-actions.php	(revision 33278)
+++ src/wp-admin/includes/ajax-actions.php	(working copy)
@@ -3095,18 +3095,57 @@
 		default:
 
 			/**
-			 * Filter the attachment ID for a cropped image.
+			 * Fires before a cropped image is saved.
+			 *
+			 * Allows to add filters to modify the way a cropped image is saved.
+			 *
+			 * @since 4.3.0
+			 *
+			 * @param string $context The Customizer control requesting the cropped image.
+			 */
+			do_action( 'pre_wp_ajax_crop_image', $context );
+
+			/** This filter is documented in wp-admin/custom-header.php */
+			$cropped = apply_filters( 'wp_create_file_in_uploads', $cropped, $attachment_id ); // For replication.
+
+			$parent_url = get_post( $attachment_id )->guid;
+			$url        = str_replace( basename( $parent_url ), basename( $cropped ), $parent_url );
+
+			$size       = @getimagesize( $cropped );
+			$image_type = ( $size ) ? $size['mime'] : 'image/jpeg';
+
+			$object = array(
+				'post_title'     => basename( $cropped ),
+				'post_content'   => $url,
+				'post_mime_type' => $image_type,
+				'guid'           => $url,
+				'context'        => $context,
+			);
+
+			$attachment_id = wp_insert_attachment( $object, $cropped );
+			$metadata = wp_generate_attachment_metadata( $attachment_id, $cropped );
+
+			/**
+			 * Filter the cropped image attachment metadata.
 			 *
 			 * @since 4.3.0
 			 *
-			 * @param int    $attachment_id The ID of the cropped image.
-			 * @param string $context       The feature requesting the cropped image.
+			 * @see wp_generate_attachment_metadata()
+			 *
+			 * @param array $metadata Attachment metadata.
 			 */
-			$attachment_id = apply_filters( 'wp_ajax_cropped_attachment_id', 0, $context );
+			$metadata = apply_filters( 'wp_ajax_cropped_attachment_metadata', $metadata );
+			wp_update_attachment_metadata( $attachment_id, $metadata );
 
-			if ( ! $attachment_id ) {
-				wp_send_json_error();
-			}
+			/**
+			 * Filter the attachment ID for a cropped image.
+			 *
+			 * @since 4.3.0
+			 *
+			 * @param int    $attachment_id The attachment ID of the cropped image.
+			 * @param string $context       The Customizer control requesting the cropped image.
+			 */
+			$attachment_id = apply_filters( 'wp_ajax_cropped_attachment_id', $attachment_id, $context );
 	}
 
 	wp_send_json_success( wp_prepare_attachment_for_js( $attachment_id ) );
Index: src/wp-includes/class-wp-customize-control.php
===================================================================
--- src/wp-includes/class-wp-customize-control.php	(revision 33278)
+++ src/wp-includes/class-wp-customize-control.php	(working copy)
@@ -1005,9 +1005,9 @@
  *
  * @since 4.3.0
  *
- * @see WP_Customize_Image_Control
+ * @see WP_Customize_Media_Control
  */
-class WP_Customize_Cropped_Image_Control extends WP_Customize_Image_Control {
+class WP_Customize_Cropped_Image_Control extends WP_Customize_Media_Control {
 
 	/**
 	 * Control type.
Index: src/wp-includes/script-loader.php
===================================================================
--- src/wp-includes/script-loader.php	(revision 33278)
+++ src/wp-includes/script-loader.php	(working copy)
@@ -410,7 +410,7 @@
 	$scripts->add( 'customize-loader',   "/wp-includes/js/customize-loader$suffix.js",   array( 'customize-base' ), false, 1 );
 	$scripts->add( 'customize-preview',  "/wp-includes/js/customize-preview$suffix.js",  array( 'customize-base' ), false, 1 );
 	$scripts->add( 'customize-models',   "/wp-includes/js/customize-models.js", array( 'underscore', 'backbone' ), false, 1 );
-	$scripts->add( 'customize-views',    "/wp-includes/js/customize-views.js",  array( 'jquery', 'underscore', 'imgareaselect', 'customize-models' ), false, 1 );
+	$scripts->add( 'customize-views',    "/wp-includes/js/customize-views.js",  array( 'jquery', 'underscore', 'imgareaselect', 'customize-models', 'media-editor', 'media-views' ), false, 1 );
 	$scripts->add( 'customize-controls', "/wp-admin/js/customize-controls$suffix.js", array( 'customize-base' ), false, 1 );
 	did_action( 'init' ) && $scripts->localize( 'customize-controls', '_wpCustomizeControlsL10n', array(
 		'activate'           => __( 'Save &amp; Activate' ),
