Allow users to contribute images to a post

i have got quite a good solution for you, if i get you right:
you want to display an upload box for a visitor at your site, enabling him to save images into the wordpress library, and have them labeled as useruploads or something.

first step would be to create a form on the post template:

<form action='upload.php?pid=$post->ID' method='post' enctype="multipart/form-data">
    <input type="file" name="myfile[]" multiple class="realfile">
    <div class="fakefile">
        <input class="fakefile fakefileinput"/>
        <img src="" . get_bloginfo( "template_url' ) . "/img/find.png' alt="search" />
    </div><br>
    <span class="percent"></span><br>
    <input type="submit" value="upload">
</form>

you can see a few tricks i implemented, the fakefile and realfile work for designing the boxes to look the same in every browser, style the fakefile, and hide the real file. you can just skip this part.
next comes the javascript to it (i suppose you already use jQuery on your site), in the document ready function:

var percent = $('.percent');

$('form').ajaxForm({
    beforeSend: function() {
        var percentVal="0%";
        percent.html(percentVal);
    },
    uploadProgress: function(event, position, total, percentComplete) {
        var percentVal = percentComplete + '%';
        percent.html(percentVal);
    },
    complete: function(xhr) {
        var responseJson = eval('(' + xhr.responseText + ')');
        if( responseJson.message != null )
            alert(responseJson.message);
        if ( responseJson.ids != null ) {
            alert( 'Upload successful' );
            $('.fakefileinput').val('');
            $('.realfile').val('');
            percent.html('');
        }
    }

}); 

this part handles the complete form – with a percent count of the upload. be sure to include the <div class="percent"></div>.

the last thing to do is your uploadhandler. i have this one in the rootdirectory, called upload.php, as you can see in my form, but every folder should work, as long as you include the wp-load.php.

include_once( 'wp-load.php' ); // to have the wordpress functions available
$uploaddir = wp_upload_dir(); // get the directory to store the images

if ( isset( $_FILES['myfile']['name']['0'] ) ) { // check if there are files

    $files = $_FILES['myfile'];

    $number = count( $files['name'] );

    for ( $_i = 0; $_i < $number; $_i++ ) { // loop through the uploaded images

        if ( "image/jpeg" != $files['type'][$_i] && "image/pjpeg" != $files['type'][$_i] ) {
            // just allow jpeg, be sure to include pjpeg as the IE sends pjpeg instead of jpeg.
            $_message.= 'Picture is no Jpeg: ' . $files['type'][$_i];

        } else {

            $uploadfile = $uploaddir['path'] . "https://wordpress.stackexchange.com/" . $_GET['pid'] . '-' . basename($files['name'][$_i]); // name and directory of the file. for ordering purposes in the file system, i include the postid in front of the filename.
            move_uploaded_file($files['tmp_name'][$_i], $uploadfile); //move the file from the server upload directory to the wordpress upload directory
            $filename = basename($uploadfile); // get the filename

            $wp_filetype = wp_check_filetype(basename($filename), null ); //wordpress handler for filetypes, although we handle just jpeg here.

            // data of the new attachment. you can add any values here, for example an excerpt or whatever
            $attachment = array(
                'post_mime_type' => $wp_filetype['type'],
                'post_title' => preg_replace('/\.[^.]+$/', '', $filename),
                'post_content' => '',
                'post_status' => 'inherit'
            );
            $attach_id = wp_insert_attachment( $attachment, $uploadfile ); // insert the attachment into the wordpress database - the file HAS to be in the uploaddir! the function returns the new id.
            // you must first include the image.php file
            // for the function wp_generate_attachment_metadata() to work
            require_once(ABSPATH . 'wp-admin/includes/image.php');

            $image = get_post( $attach_id ); // load the data of the new image.
            $fullsizepath = get_attached_file( $image->ID ); // get the filepath of the image in the wordpress upload directory
            $attach_data = wp_generate_attachment_metadata( $attach_id, $fullsizepath ); // generate the thumbnails and the rest of the metadata
            wp_update_attachment_metadata( $attach_id, $attach_data ); // ... and update the image
            $mypost = array(
                'ID' => $image->ID,
                'post_parent' => $_GET['pid']
            );
            wp_update_post( $mypost ); // now set the post parent to the submitted post_id, so you have the connection between the uploaded files and the corresponding posts
            wp_set_object_terms( $image->ID, 'userupload', 'category' ); // if you want to, you can also assign a category 'userupload' to the uploaded images - you can distinguish between your own and the ones from the users.
            //$_message.= var_dump( $attach_data ); - debugging
            $_id[$_i]= $attach_id; // save all the new ids into an array to return, if you want to do anything special with them afterwards.


        }



    }


} else {

    $_message.= "No Images sent."; // Errorhandler

}
$return = json_encode( array(
    'ukid' => $_GET['uid'],
    'message' => $_message,
    'ids' => $_id
) );
echo( $return ); // return the json, explaining what happenend.
die();

that should be it!
i modified my code a little, and didn’t test it afterwards, but it should work just fine 🙂 be sure to include some sort of spam detection, to be sure your server can handle all the work from the image processing 🙂
if you got any additional questions to this method, do not hesitate to ask 🙂