Get uploaded image url

wp_upload_dir() is perfect. It is the only place where you can expect write permissions.

Store the attachment ID, not a path. Then you get the image with:

wp_get_attachment_url( $attach_id )

Sometimes a user may have deleted the image per media library. To avoid problems with missing files check the return value from wp_get_attachment_url() first. Excerpt from one of my plugins:

 * Returns image markup.
 * Empty string if there is no image.
 * @param  int    $attach_id
 * @return string
protected function get_image_tag( $attach_id )

    $img_url = (string) wp_get_attachment_url( $attach_id );

    if ( '' == $img_url )
        return '';

    $img = "<img src="$img_url" alt="" width="$this->width" height="$this->height">";

    return $img;