diff --git modules/system/image.gd.inc modules/system/image.gd.inc
index d8f893d..f550dcb 100644
--- modules/system/image.gd.inc
+++ modules/system/image.gd.inc
@@ -244,7 +244,7 @@ function image_gd_load(stdClass $image) {
  * @param $image
  *   An image object.
  * @param $destination
- *   A string file path where the image should be saved.
+ *   A string file URI where the image should be saved.
  * @param $extension
  *   A string containing one of the following extensions: gif, jpg, jpeg, png.
  * @return
@@ -253,11 +253,20 @@ function image_gd_load(stdClass $image) {
  * @see image_save()
  */
 function image_gd_save(stdClass $image, $destination) {
-  // Convert URI to a normal path because PHP apparently has some gaps in stream wrapper support.
+  $tempnam = '';
   if ($wrapper = file_stream_wrapper_get_instance_by_uri($destination)) {
-    $destination = $wrapper->realpath();
+    $parents = class_parents($wrapper);
+    if (empty($parents['DrupalLocalStreamWrapper'])) {
+      // Use a temp file as an intermediate step for a remote URI.
+      $tempwrapper = file_stream_wrapper_get_instance_by_scheme('temporary');
+      $tempnam = tempnam($tempwrapper->getDirectoryPath(), 'gd_');
+    }
+    else {
+      // Convert URI to a normal path because PHP apparently has some gaps in stream wrapper support.
+      $destination = $wrapper->realpath();
+    }
   }
-  
+
   $extension = str_replace('jpg', 'jpeg', $image->info['extension']);
   $function = 'image' . $extension;
   if (!function_exists($function)) {
@@ -272,6 +281,13 @@ function image_gd_save(stdClass $image, $destination) {
       imagealphablending($image->resource, FALSE);
       imagesavealpha($image->resource, TRUE);
     }
+    if ($tempnam) {
+      // Use a temp file as an intermediate step.
+      if ($function($image->resource, $tempnam)) {
+        return (bool) file_unmanaged_move($tempnam, $destination, FILE_EXISTS_REPLACE);
+      }
+      return FALSE;
+    }
     return $function($image->resource, $destination);
   }
 }
