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;
}