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="https://wordpress.stackexchange.com/questions/43076/$img_url" alt="" width="$this->width" height="$this->height">";

    return $img;
}