diff --git a/wp-admin/includes/image.php b/wp-admin/includes/image.php
index 2a5123e..4da6f6f 100644
--- a/wp-admin/includes/image.php
+++ b/wp-admin/includes/image.php
@@ -72,23 +72,14 @@ function wp_generate_attachment_metadata( $attachment_id, $file ) {
 		// Make the file path relative to the upload dir
 		$metadata['file'] = _wp_relative_upload_path($file);
 
-		// make thumbnails and other intermediate sizes
-		global $_wp_additional_image_sizes;
-
-		foreach ( get_intermediate_image_sizes() as $s ) {
-			$sizes[$s] = array( 'width' => '', 'height' => '', 'crop' => false );
-			if ( isset( $_wp_additional_image_sizes[$s]['width'] ) )
-				$sizes[$s]['width'] = intval( $_wp_additional_image_sizes[$s]['width'] ); // For theme-added sizes
-			else
-				$sizes[$s]['width'] = get_option( "{$s}_size_w" ); // For default sizes set in options
-			if ( isset( $_wp_additional_image_sizes[$s]['height'] ) )
-				$sizes[$s]['height'] = intval( $_wp_additional_image_sizes[$s]['height'] ); // For theme-added sizes
-			else
-				$sizes[$s]['height'] = get_option( "{$s}_size_h" ); // For default sizes set in options
-			if ( isset( $_wp_additional_image_sizes[$s]['crop'] ) )
-				$sizes[$s]['crop'] = intval( $_wp_additional_image_sizes[$s]['crop'] ); // For theme-added sizes
-			else
-				$sizes[$s]['crop'] = get_option( "{$s}_crop" ); // For default sizes set in options
+		$sizes = array();
+
+		foreach ( get_intermediate_image_sizes( array( 'pregenerate' => true ), 'objects' ) as $name => $size ) {
+			$sizes[ $name ] = array(
+				'width' => $size->width,
+				'height' => $size->height,
+				'crop' => $size->crop,
+			);
 		}
 
 		$sizes = apply_filters( 'intermediate_image_sizes_advanced', $sizes );
@@ -398,3 +389,61 @@ function _copy_image_file( $attachment_id ) {
 
 	return $dst_file;
 }
+
+/**
+ * Processes the postback to generate a specific image size
+ */
+function _admin_post_generate_image_size() {
+	ignore_user_abort(true);
+	
+	$attachment_id = isset( $_POST['post_id'] ) ? (int) $_POST['post_id'] : 0;
+	$size = isset( $_POST['size'] ) ? $_POST['size'] : '';
+	$hash = isset( $_POST['hash'] ) ? $_POST['hash'] : '';
+	
+	if ( empty( $attachment_id ) || empty( $size ) || empty( $hash ) ||
+			$hash != wp_hash( 'generate_image' . $attachment_id . $size ) )
+		wp_die( 'Invalid request.' );
+
+	$transient_key = 'gen_image_' . $attachment_id . '_' . $size;
+	
+	if(get_transient( $transient_key )) {
+		wp_die('Image already being generated');
+	}
+	
+	//create 5 minute semi-lock on action
+	set_transient($transient_key, 1, 5 * MINUTE_IN_SECONDS);
+
+	_generate_image_size($attachment_id, $size);
+
+	delete_transient($transient_key);
+	
+	wp_die('Image successfully generated.');
+}
+
+/**
+ * Generates the image in the given $size
+ * 
+ * @since 3.5
+ * @access private
+ * 
+ * @param int $attachment_id Attachment ID.
+ * @param string $size Name of the image size to be generated
+ */
+function _generate_image_size( $attachment_id, $size ) {
+	$attachment = get_post( $attachment_id );
+
+	$file = _load_image_to_edit_path( $attachment_id );
+
+	$size_data = get_image_size( $size );
+
+	$metadata = wp_get_attachment_metadata( $attachment_id );
+	if ( !is_array( $metadata ) )
+		return false;
+
+	if ( $size && $file && preg_match( '!^image/!', get_post_mime_type( $attachment ) ) && file_is_displayable_image( $file ) ) {
+		$editor = WP_Image_Editor::get_instance( $file );
+		$metadata['sizes'] = array_merge( $metadata['sizes'], $editor->multi_resize( array( $size => ( array ) $size_data ) ) );
+
+		wp_update_attachment_metadata( $attachment_id, $metadata );
+	}
+}
\ No newline at end of file
diff --git a/wp-admin/includes/meta-boxes.php b/wp-admin/includes/meta-boxes.php
index f099627..0321aff 100644
--- a/wp-admin/includes/meta-boxes.php
+++ b/wp-admin/includes/meta-boxes.php
@@ -1011,8 +1011,6 @@ function link_advanced_meta_box($link) {
  * @since 2.9.0
  */
 function post_thumbnail_meta_box( $post ) {
-	global $_wp_additional_image_sizes;
-
 	?><script type="text/javascript">
 	jQuery( function($) {
 		var $element     = $('#select-featured-image'),
@@ -1073,7 +1071,7 @@ function post_thumbnail_meta_box( $post ) {
 
 	<?php
 	$thumbnail_id   = get_post_meta( $post->ID, '_thumbnail_id', true );
-	$thumbnail_size = isset( $_wp_additional_image_sizes['post-thumbnail'] ) ? 'post-thumbnail' : 'medium';
+	$thumbnail_size = image_size_exists( 'post-thumbnail' ) ? 'post-thumbnail' : 'medium';
 	$thumbnail_html = wp_get_attachment_image( $thumbnail_id, $thumbnail_size );
 
 	$classes = empty( $thumbnail_id ) ? '' : 'has-featured-image';
@@ -1087,4 +1085,4 @@ function post_thumbnail_meta_box( $post ) {
 		<a href="#" class="remove"><?php _e( 'Remove Featured Image' ); ?></a>
 	</div>
 	<?php
-}
\ No newline at end of file
+}
diff --git a/wp-admin/includes/post.php b/wp-admin/includes/post.php
index 5ce1064..47c9316 100644
--- a/wp-admin/includes/post.php
+++ b/wp-admin/includes/post.php
@@ -1130,7 +1130,7 @@ function get_sample_permalink_html( $id, $new_title = null, $new_slug = null, $s
  * @return string html
  */
 function _wp_post_thumbnail_html( $thumbnail_id = null, $post = null ) {
-	global $content_width, $_wp_additional_image_sizes;
+	global $content_width;
 
 	$post = get_post( $post );
 
@@ -1141,7 +1141,7 @@ function _wp_post_thumbnail_html( $thumbnail_id = null, $post = null ) {
 	if ( $thumbnail_id && get_post( $thumbnail_id ) ) {
 		$old_content_width = $content_width;
 		$content_width = 266;
-		if ( !isset( $_wp_additional_image_sizes['post-thumbnail'] ) )
+		if ( !image_size_exists( 'post-thumbnail' ) )
 			$thumbnail_html = wp_get_attachment_image( $thumbnail_id, array( $content_width, $content_width ) );
 		else
 			$thumbnail_html = wp_get_attachment_image( $thumbnail_id, 'post-thumbnail' );
diff --git a/wp-includes/default-filters.php b/wp-includes/default-filters.php
index 19fdd50..c63611c 100644
--- a/wp-includes/default-filters.php
+++ b/wp-includes/default-filters.php
@@ -258,6 +258,7 @@ add_action( 'admin_init',                 'send_frame_options_header',
 add_action( 'importer_scheduled_cleanup', 'wp_delete_attachment'                           );
 add_action( 'upgrader_scheduled_cleanup', 'wp_delete_attachment'                           );
 add_action( 'welcome_panel',              'wp_welcome_panel'                               );
+add_action( 'admin_post_nopriv_generate_image_size', '_admin_post_generate_image_size', 10, 2 );
 
 // Navigation menu actions
 add_action( 'delete_post',                '_wp_delete_post_menu_item'         );
diff --git a/wp-includes/functions.php b/wp-includes/functions.php
index 8615e32..20173a6 100644
--- a/wp-includes/functions.php
+++ b/wp-includes/functions.php
@@ -2584,6 +2584,28 @@ function wp_list_pluck( $list, $field ) {
 }
 
 /**
+ * Convert a numeric array to an associative array, based on a list of keys.
+ *
+ * @since 3.5.0
+ *
+ * @param array $list Numeric array to be converted
+ * @param array $keys A list of keys
+ * @return array Resulting array
+ */
+function wp_numeric_to_assoc( $vector, $keys ) {
+	$assoc = array();
+
+	foreach ( $keys as $i => $key ) {
+		if ( isset( $vector[ $i ] ) )
+			$assoc[ $key ] = $vector[ $i ];
+		else
+			break;
+	}
+
+	return $assoc;
+}
+
+/**
  * Determines if Widgets library should be loaded.
  *
  * Checks to make sure that the widgets library hasn't already been loaded. If
@@ -3781,3 +3803,4 @@ function wp_is_stream( $path ) {
 function wp_checkdate( $month, $day, $year, $source_date ) {
 	return apply_filters( 'wp_checkdate', checkdate( $month, $day, $year ), $source_date );
 }
+
diff --git a/wp-includes/media.php b/wp-includes/media.php
index 08ebf72..9a2e33f 100644
--- a/wp-includes/media.php
+++ b/wp-includes/media.php
@@ -32,39 +32,21 @@
  * @return array Width and height of what the result image should resize to.
  */
 function image_constrain_size_for_editor($width, $height, $size = 'medium') {
-	global $content_width, $_wp_additional_image_sizes;
+	global $content_width;
+
+	if ( 'thumb' == $size )
+		$size = 'thumbnail';
 
 	if ( is_array($size) ) {
-		$max_width = $size[0];
-		$max_height = $size[1];
-	}
-	elseif ( $size == 'thumb' || $size == 'thumbnail' ) {
-		$max_width = intval(get_option('thumbnail_size_w'));
-		$max_height = intval(get_option('thumbnail_size_h'));
-		// last chance thumbnail size defaults
-		if ( !$max_width && !$max_height ) {
-			$max_width = 128;
-			$max_height = 96;
-		}
-	}
-	elseif ( $size == 'medium' ) {
-		$max_width = intval(get_option('medium_size_w'));
-		$max_height = intval(get_option('medium_size_h'));
-		// if no width is set, default to the theme content width if available
+		list( $max_width, $max_height ) = $size;
 	}
-	elseif ( $size == 'large' ) {
-		// We're inserting a large size image into the editor. If it's a really
-		// big image we'll scale it down to fit reasonably within the editor
-		// itself, and within the theme's content width if it's known. The user
-		// can resize it in the editor if they wish.
-		$max_width = intval(get_option('large_size_w'));
-		$max_height = intval(get_option('large_size_h'));
-		if ( intval($content_width) > 0 )
-			$max_width = min( intval($content_width), $max_width );
-	} elseif ( isset( $_wp_additional_image_sizes ) && count( $_wp_additional_image_sizes ) && in_array( $size, array_keys( $_wp_additional_image_sizes ) ) ) {
-		$max_width = intval( $_wp_additional_image_sizes[$size]['width'] );
-		$max_height = intval( $_wp_additional_image_sizes[$size]['height'] );
-		if ( intval($content_width) > 0 && is_admin() ) // Only in admin. Assume that theme authors know what they're doing.
+	elseif ( image_size_exists( $size ) ) {
+		$size_obj = get_image_size( $size );
+
+		$max_width = $size_obj->width;
+		$max_height = $size_obj->height;
+
+		if ( intval( $content_width ) > 0 && ( 'large' == $size || is_admin() ) )
 			$max_width = min( intval($content_width), $max_width );
 	}
 	// $size == 'full' has no constraint
@@ -176,22 +158,120 @@ function image_downsize($id, $size = 'medium') {
 }
 
 /**
- * Registers a new image size
+ * Register a new image size.
  *
  * @since 2.9.0
+ *
+ * @param string $name The new image size name
+ * @param array $args The new image size parameters
+ */
+function add_image_size( $name, $args ) {
+	if ( !is_array( $args ) ) {
+		$argv = func_get_args();
+		$name = array_shift( $argv );
+		$args = wp_numeric_to_assoc( $argv, array( 'width', 'height', 'crop' ) );
+	}
+
+	$defaults = array(
+		'width' => 0,
+		'height' => 0,
+		'crop' => false,
+		'pregenerate' => true
+	);
+
+	$args = array_merge( $defaults, $args );
+
+	$size = new stdClass;
+
+	$size->name = $name;
+	$size->width = absint( $args['width'] );
+	$size->height = absint( $args['height'] );
+	$size->crop = (bool) $args['crop'];
+	$size->pregenerate = (bool) $args['pregenerate'];
+
+	global $wp_image_sizes;
+
+	if ( !is_array( $wp_image_sizes ) )
+		$wp_image_sizes = array();
+
+	$wp_image_sizes[ $name ] = $size;
+}
+
+/**
+ * Get a registered image size object by name.
+ *
+ * @since 3.6.0
+ *
+ * @param string $image_size Image size name
+ * @return object
  */
-function add_image_size( $name, $width = 0, $height = 0, $crop = false ) {
-	global $_wp_additional_image_sizes;
-	$_wp_additional_image_sizes[$name] = array( 'width' => absint( $width ), 'height' => absint( $height ), 'crop' => (bool) $crop );
+function get_image_size( $image_size ) {
+	global $wp_image_sizes;
+
+	if ( empty( $wp_image_sizes[ $image_size ] ) )
+		return null;
+
+	return $wp_image_sizes[ $image_size ];
 }
 
 /**
+ * Checks if an image size is registered.
+ *
+ * @since 3.6.0
+ *
+ * @param string $image_size Image size name
+ * @return bool
+ */
+function image_size_exists( $image_size ) {
+	return (bool) get_image_size( $image_size );
+}
+
+/**
+ * Get the available image sizes.
+ *
+ * @since 3.0.0
+ *
+ * @return array
+ */
+function get_intermediate_image_sizes( $args = array(), $output = 'names', $operator = 'and' ) {
+	global $wp_image_sizes;
+
+	$field = ( 'names' == $output ) ? 'name' : false;
+
+	$list = wp_filter_object_list( $wp_image_sizes, $args, $operator, $field );
+
+	if ( 'names' == $output )
+		return apply_filters( 'intermediate_image_sizes', $list );
+
+	return $list;
+}
+
+function create_initial_image_sizes() {
+	foreach ( array( 'thumbnail', 'medium', 'large' ) as $s ) {
+		$args = array(
+			'width' => get_option( "{$s}_size_w" ),
+			'height' => get_option( "{$s}_size_h" ),
+			'crop' => get_option( "{$s}_crop" ),
+			'pregenerate' => true
+		);
+
+		add_image_size( $s, $args );
+	}
+}
+add_action( 'init', 'create_initial_image_sizes', 0 ); // highest priority
+
+/**
  * Registers an image size for the post thumbnail
  *
  * @since 2.9.0
  */
 function set_post_thumbnail_size( $width = 0, $height = 0, $crop = false ) {
-	add_image_size( 'post-thumbnail', $width, $height, $crop );
+	add_image_size( 'post-thumbnail', array(
+		'width' => $width,
+		'height' => $height,
+		'crop' => $crop,
+		'pregenerate' => false
+	) );
 }
 
 /**
@@ -459,8 +539,16 @@ function image_get_intermediate_size($post_id, $size='thumbnail') {
 		}
 	}
 
-	if ( is_array($size) || empty($size) || empty($imagedata['sizes'][$size]) )
+	if ( is_array($size) || empty($size) )
+		return false;
+	
+	if( empty($imagedata['sizes'][$size]) ) {
+		if ( $image_size = get_image_size( $size ) ) {
+			register_shutdown_function( 'wp_asynch_generate_image_size', $post_id, $size );
+		}
 		return false;
+	}
+	
 
 	$data = $imagedata['sizes'][$size];
 	// include the full filesystem path of the intermediate file
@@ -473,20 +561,6 @@ function image_get_intermediate_size($post_id, $size='thumbnail') {
 }
 
 /**
- * Get the available image sizes
- * @since 3.0.0
- * @return array Returns a filtered array of image size strings
- */
-function get_intermediate_image_sizes() {
-	global $_wp_additional_image_sizes;
-	$image_sizes = array('thumbnail', 'medium', 'large'); // Standard sizes
-	if ( isset( $_wp_additional_image_sizes ) && count( $_wp_additional_image_sizes ) )
-		$image_sizes = array_merge( $image_sizes, array_keys( $_wp_additional_image_sizes ) );
-
-	return apply_filters( 'intermediate_image_sizes', $image_sizes );
-}
-
-/**
  * Retrieve an image to represent an attachment.
  *
  * A mime icon for files, thumbnail or intermediate size for images.
@@ -1381,3 +1455,28 @@ function wp_print_media_templates( $attachment ) {
 	</script>
 	<?php
 }
+
+/**
+ * Sends a request to the admin to generate the given image size
+ * @param int $attachment_id Attachment ID
+ * @param string $size Image size name.
+ */
+function wp_asynch_generate_image_size($attachment_id, $size) {
+	$server_url = admin_url('admin-post.php');
+	
+	$hash = wp_hash('generate_image' . $attachment_id . $size);
+	
+	$body = array( 
+		'action' => 'generate_image_size', 
+		'post_id' => $attachment_id, 
+		'size' => $size, 
+		'hash' => $hash );
+	
+	$args = array( 
+		'body' => $body, 
+		'timeout' => 0.01, 
+		'blocking' => false, 
+		'sslverify' => apply_filters( 'https_local_ssl_verify', true ) );
+	
+	$response = wp_remote_post( $server_url, $args );
+}
