diff --git a/file_entity.file.inc b/file_entity.file.inc
index d5cfadc..53cb4ea 100644
--- a/file_entity.file.inc
+++ b/file_entity.file.inc
@@ -182,24 +182,10 @@ function file_entity_file_mimetype_mapping_alter(&$mapping) {
  * Implements hook_file_load().
  */
 function file_entity_file_load($files) {
-  $alt = variable_get('file_entity_alt', '[file:field_file_image_alt_text]');
-  $title = variable_get('file_entity_title', '[file:field_file_image_title_text]');
-
-  $replace_options = array(
-    'clear' => TRUE,
-    'sanitize' => FALSE,
-  );
-
   foreach ($files as $file) {
     $file->metadata = array();
-
-    // Load alt and title text from fields.
-    if (!empty($alt)) {
-      $file->alt = token_replace($alt, array('file' => $file), $replace_options);
-    }
-    if (!empty($title)) {
-      $file->title = token_replace($title, array('file' => $file), $replace_options);
-    }
+    $file->title = file_entity_replace_title($file);
+    $file->alt = file_entity_replace_alt($file);
   }
 
   // Load and unserialize metadata.
diff --git a/file_entity.file_api.inc b/file_entity.file_api.inc
index 9baa1a4..1e8dfc0 100644
--- a/file_entity.file_api.inc
+++ b/file_entity.file_api.inc
@@ -231,6 +231,23 @@ function file_view_file($file, $displays = 'full', $langcode = NULL) {
   drupal_alter('file_displays', $displays, $file, $view_mode);
   _file_sort_array_by_weight($displays);
 
+  // Since $file->alt and $file->title were set in file_entity_file_load()
+  // (which is a language-agnostic hook) they will not be in the correct
+  // language if the file is being displayed in a language other than the
+  // default one. Set them again here, using the correct language. This must
+  // run after hook_file_displays_alter() since the Media module sets
+  // $file->alt and $file->title again during that hook.
+  if ($langcode != $GLOBALS['language_content']->language) {
+    $languages = language_list();
+    if (isset($languages[$langcode])) {
+      $replace_options = array(
+        'language' => $languages[$langcode],
+      );
+      $file->title = file_entity_replace_title($file, $replace_options);
+      $file->alt = file_entity_replace_alt($file, $replace_options);
+    }
+  }
+
   // Attempt to display the file with each of the possible displays. Stop after
   // the first successful one. See file_displays() for details.
   $element = NULL;
diff --git a/file_entity.module b/file_entity.module
index 488d1de..7b0f227 100644
--- a/file_entity.module
+++ b/file_entity.module
@@ -1187,6 +1187,79 @@ function file_entity_file_formatter_file_field_settings($form, &$form_state, $se
 }
 
 /**
+ * Replace file entity title text.
+ *
+ * @param $file
+ *   The file entity.
+ * @param $replace_options
+ *   (Optional) Options to pass to token_replace().
+ * @param $title
+ *   (Optional) The title text to use.
+ *
+ * @return string
+ *   Returns the replaced title text.
+ */
+function file_entity_replace_title($file, $replace_options = array(), $title = NULL) {
+  $replace_options += array(
+    'clear' => TRUE,
+    'sanitize' => FALSE,
+  );
+
+  $title_default = '[file:field_file_image_title_text]';
+  if (!isset($title)) {
+    $title = variable_get('file_entity_title', $title_default);
+  }
+  // If the defaults are not changed then inlining replacement is much faster
+  // than dealing with the token system.
+  if ($title === $title_default) {
+    $title_items = field_get_items('file', $file, 'field_file_image_title_text');
+    return $title_items ? $title_items[0]['value'] : '';
+  }
+  elseif (!empty($title)) {
+    return token_replace($title, array('file' => $file), $replace_options);
+  }
+
+  return '';
+}
+
+/**
+ * Replace file entity alt.
+ *
+ * @param $file
+ *   The file entity.
+ * @param $replace_options
+ *   (Optional) Options to pass to token_replace().
+ * @param $alt
+ *   (Optional) The alt text to use.
+ *
+ * @return string
+ *   Returns the replaced alt text.
+ */
+function file_entity_replace_alt($file, $replace_options = array(), $alt = NULL) {
+  $replace_options += array(
+    'clear' => TRUE,
+    'sanitize' => FALSE,
+  );
+
+  $alt_default = '[file:field_file_image_alt_text]';
+
+  if (!isset($alt)) {
+    $alt = variable_get('file_entity_alt', $alt_default);
+  }
+
+  // If the defaults are not changed then inlining replacement is much faster
+  // than dealing with the token system.
+  if ($alt === $alt_default) {
+    $alt_items = field_get_items('file', $file, 'field_file_image_alt_text');
+    return $alt_items ? $alt_items[0]['value'] : '';
+  }
+  elseif (!empty($alt)) {
+    return token_replace($alt, array('file' => $file), $replace_options);
+  }
+}
+
+
+/**
  * Implements hook_file_formatter_FORMATTER_view().
  *
  * Returns a drupal_render() array to display an image of the chosen style.
@@ -1226,8 +1299,8 @@ function file_entity_file_formatter_file_image_view($file, $display, $langcode)
         '#path' => $file->uri,
         '#width' => isset($file->override['attributes']['width']) ? $file->override['attributes']['width'] : $file->metadata['width'],
         '#height' => isset($file->override['attributes']['height']) ? $file->override['attributes']['height'] : $file->metadata['height'],
-        '#alt' => token_replace($display['settings']['alt'], array('file' => $file), $replace_options),
-        '#title' => token_replace($display['settings']['title'], array('file' => $file), $replace_options),
+        '#alt' => file_entity_replace_alt($file, $replace_options, $display['settings']['alt']),
+        '#title' => file_entity_replace_title($file, $replace_options, $display['settings']['title']),
       );
     }
     else {
@@ -1236,8 +1309,8 @@ function file_entity_file_formatter_file_image_view($file, $display, $langcode)
         '#path' => $file->uri,
         '#width' => isset($file->override['attributes']['width']) ? $file->override['attributes']['width'] : $file->metadata['width'],
         '#height' => isset($file->override['attributes']['height']) ? $file->override['attributes']['height'] : $file->metadata['height'],
-        '#alt' => token_replace($display['settings']['alt'], array('file' => $file), $replace_options),
-        '#title' => token_replace($display['settings']['title'], array('file' => $file), $replace_options),
+        '#alt' => file_entity_replace_alt($file, $replace_options, $display['settings']['alt']),
+        '#title' => file_entity_replace_title($file, $replace_options, $display['settings']['title']),
       );
     }
     return $element;
