If the image is in the content source you can extract it and use media_sideload_image(); to import it into the media library.
This code sample is from my plugin Media Tools. Which has does this via a admin page via ajax. It also sets the extracted image as the featured image for the post. The post id is being passed to this function via ajax. To look at the complete code see: http://plugins.trac.wordpress.org/browser/media-tools/trunk/media-tools.php?rev=581988
function process_image( $post_id ) {
$response="";
$error = 0;
$post = get_post( $post_id );
$img = $this->extract_image( $post );
if( empty( $img ) ) {
$response .= 'No images found <br>';
die( sprintf( $response . '<br>Media tool complete (Post ID %1$s) in %2$s seconds. %3$d errors', esc_html( $post->ID ), timer_stop(), $error = $error > 0 ? $error : 'no' ) );
}
/** @var $file string or WP_Error of image attached to the post */
$file = media_sideload_image( $img, (int)$post->ID );
if ( is_wp_error( $file ) ) {
$response .= '<span style="color:red">Upload Error: Could not upload image. Check for malformed img src url</span><br>';
$error++;
} else {
$atts = $this->get_attach( $post->ID );
foreach ( $atts as $a ) {
$img = set_post_thumbnail( $post->ID, $a['ID'] );
if ( $img ) {
$thumb = wp_get_attachment_thumb_url( $a['ID'] );
$response .= '<img src="'.esc_url( $thumb ).'" /><br>';
$response .= '<a href="'.wp_nonce_url( get_edit_post_link( $a['ID'], true ) ).'" >'.get_the_title( $a['ID'] ).'</a> Set as Featured Image</p><br>';
}
}
unset( $atts );
unset( $a );
}
die( sprintf( $response.'<br>Media tool complete (Post ID %1$s) in %2$s seconds. %3$d errors', esc_html( $post->ID ), timer_stop(), $error = $error > 0 ? $error : 'no' ) );
}
/**
* Extracts the first image in the post content
* @param object $post the post object
* @return bool|string false if no images or img src
*/
function extract_image( $post ) {
$html = $post->post_content;
if ( stripos( $html, '<img' ) !== false ) {
$regex = '#<\s*img [^\>]*src\s*=\s*(["\'])(.*?)\1#im';
preg_match( $regex, $html, $matches );
unset( $regex );
unset( $html );
if ( is_array( $matches ) && ! empty( $matches ) ) {
return $matches[2];
} else {
return false;
}
} else {
return false;
}
}
/**
* Queries for attached images
* @param int $post_id The post id to check if attachments exist
* @return array|bool The 1st attached on success false if no attachments
*/
function get_attach( $post_id ) {
return get_children( array (
'post_parent' => $post_id,
'post_type' => 'attachment',
'post_mime_type' => 'image',
'posts_per_page' => (int)1
), ARRAY_A );
}