diff --git a/file_entity/file_entity.admin.inc b/file_entity/file_entity.admin.inc
index 18ff8b5..3ee0743 100644
--- a/file_entity/file_entity.admin.inc
+++ b/file_entity/file_entity.admin.inc
@@ -56,8 +56,10 @@ function file_entity_file_display_form($form, &$form_state, $file_type, $view_mo
       unset ($formatters[$name]);
     }
   }
-  $current_displays = variable_get('file_displays');
-  $current_displays = isset($current_displays[$file_type][$view_mode]) ? $current_displays[$file_type][$view_mode] : array();
+  $current_displays = file_displays_load($file_type, $view_mode, TRUE);
+  foreach ($current_displays as $name => $display) {
+    $current_displays[$name] = (array) $display;
+  }
 
   // Formatter status.
   $form['displays']['status'] = array(
@@ -138,10 +140,15 @@ function file_entity_file_display_form($form, &$form_state, $file_type, $view_mo
  * Process file display settings form submissions.
  */
 function file_entity_file_display_form_submit($form, &$form_state) {
+  $file_type = $form['#file_type'];
+  $view_mode = $form['#view_mode'];
   $displays = isset($form_state['values']['displays']) ? $form_state['values']['displays'] : array();
-  $file_displays = variable_get('file_displays');
-  $file_displays[$form['#file_type']][$form['#view_mode']] = $displays;
-  variable_set('file_displays', $file_displays);
+  $displays_original = file_displays_load($file_type, $view_mode, TRUE);
+  foreach ($displays as $formatter_name => $display) {
+    $display_original = isset($displays_original[$formatter_name]) ? $displays_original[$formatter_name] : file_display_new($file_type, $view_mode, $formatter_name);
+    $display += (array) $display_original;
+    file_display_save((object) $display);
+  }
   drupal_set_message(t('Your settings have been saved.'));
 }
 
diff --git a/file_entity/file_entity.file_api.inc b/file_entity/file_entity.file_api.inc
index d83cdc4..55b8bc6 100644
--- a/file_entity/file_entity.file_api.inc
+++ b/file_entity/file_entity.file_api.inc
@@ -271,21 +271,65 @@ function file_displays($file_type, $view_mode = 'default') {
     $view_mode = 'default';
   }
 
-  $displays_info = variable_get('file_displays');
-  if ($view_mode !== 'default' && isset($displays_info[$file_type][$view_mode])) {
-    $displays = $displays_info[$file_type][$view_mode];
+  // Load the display configurations for the file type and view mode. If none
+  // exist for the view mode, use the default view mode.
+  if ($view_mode != 'default') {
+    $displays = file_displays_load($file_type, $view_mode, TRUE);
   }
-  elseif (isset($displays_info[$file_type]['default'])) {
-    $displays = $displays_info[$file_type]['default'];
+  if (empty($displays)) {
+    $displays = file_displays_load($file_type, 'default', TRUE);
   }
-  else {
-    $displays = array();
+
+  // Convert the display objects to arrays and remove unnecessary keys.
+  foreach ($displays as $formatter_name => $display) {
+    $displays[$formatter_name] = array_intersect_key((array) $display, drupal_map_assoc(array('status', 'weight', 'settings')));
   }
 
   return $displays;
 }
 
 /**
+ * Returns an array of {file_display} objects for the file type and view mode.
+ */
+function file_displays_load($file_type, $view_mode, $key_by_formatter_name = FALSE) {
+  ctools_include('export');
+
+  $display_names = array();
+  $prefix = $file_type . '__' . $view_mode . '__';
+  foreach (array_keys(file_info_formatter_types()) as $formatter_name) {
+    $display_names[] = $prefix . $formatter_name;
+  }
+  $displays = ctools_export_load_object('file_display', 'names', $display_names);
+
+  if ($key_by_formatter_name) {
+    $prefix_length = strlen($prefix);
+    $rekeyed_displays = array();
+    foreach ($displays as $name => $display) {
+      $rekeyed_displays[substr($name, $prefix_length)] = $display;
+    }
+    $displays = $rekeyed_displays;
+  }
+
+  return $displays;
+}
+
+/**
+ * Saves a {file_display} object to the database.
+ */
+function file_display_save($display) {
+  ctools_export_crud_save('file_display', $display);
+}
+
+/**
+ * Creates a new {file_display} object.
+ */
+function file_display_new($file_type, $view_mode, $formatter_name) {
+  $display = ctools_export_crud_new('file_display');
+  $display->name = implode('__', array($file_type, $view_mode, $formatter_name));
+  return $display;
+}
+
+/**
  * Helper function to sort an array by the value of each item's 'weight' key, while preserving relative order of items that have equal weight.
  */
 function _file_sort_array_by_weight(&$a) {
diff --git a/file_entity/file_entity.info b/file_entity/file_entity.info
index 67be8cc..2d2f6b7 100644
--- a/file_entity/file_entity.info
+++ b/file_entity/file_entity.info
@@ -3,3 +3,4 @@ description = "Extends Drupal file entities to be fieldable and viewable."
 package = Media
 core = 7.x
 dependencies[] = field
+dependencies[] = ctools
diff --git a/file_entity/file_entity.install b/file_entity/file_entity.install
index 3aac9b1..6c6e79d 100644
--- a/file_entity/file_entity.install
+++ b/file_entity/file_entity.install
@@ -2,8 +2,7 @@
 
 /**
  * @file
- *
- * Extends the {file_managed} table with a 'type' column.
+ * Install, update and uninstall functions for the file_entity module.
  */
 
 /**
@@ -21,6 +20,81 @@ function file_entity_schema_alter(&$schema) {
 }
 
 /**
+ * Implement hook_schema().
+ */
+function file_entity_schema() {
+  $schema['file_display'] = _file_entity_schema_file_display_7000();
+
+  // Integrate {file_display} with CTools Exportables.
+  // @see help/export.html documentation bundled with the CTools project.
+  $schema['file_display']['export'] = array(
+    'key' => 'name',
+    'key name' => 'Name',
+    'primary key' => 'name',
+    // The {file_display}.status field is used to control whether the display
+    // is active in the display chain. CTools-level disabling is something
+    // different, and it's not yet clear how to interpret it for file displays.
+    // Until that's figured out, prevent CTools-level disabling.
+    'can disable' => FALSE,
+    'default hook' => 'file_default_displays',
+    'identifier' => 'file_display',
+    'api' => array(
+      'owner' => 'file_entity',
+      'api' => 'file_default_displays',
+      'minimum_version' => 1,
+      'current_version' => 1,
+    ),
+  );
+
+  return $schema;
+}
+
+/**
+ * {file_display} schema used by file_entity_update_7000().
+ *
+ * Do not change this schema. When the {file_display} schema changes, create a
+ * new one that corresponds to the appropriate update function, and ensure that
+ * file_entity_schema() uses the latest one.
+ */
+function _file_entity_schema_file_display_7000() {
+  return array(
+    'description' => 'Stores configuration options for file displays.',
+    'fields' => array(
+      // @todo Can be refactored as a compond primary key after
+      //   http://drupal.org/node/924236 is implemented.
+      'name' => array(
+        'description' => 'A combined string (FILE_TYPE__VIEW_MODE__FILE_FORMATTER) identifying a file display configuration. For integration with CTools Exportables, stored as a single string rather than as a compound primary key.',
+        'type' => 'varchar',
+        'length' => '255',
+        'not null' => TRUE,
+      ),
+      'weight' => array(
+        'type' => 'int',
+        'not null' => TRUE,
+        'default' => 0,
+        'description' => 'Weight of formatter within the display chain for the associated file type and view mode. A file is rendered using the lowest weighted enabled display configuration that matches the file type and view mode and that is capable of displaying the file.',
+      ),
+      'status' => array(
+        'type' => 'int',
+        'unsigned' => TRUE,
+        'not null' => TRUE,
+        'default' => 0,
+        'size' => 'tiny',
+        'description' => 'The status of the display. (1 = enabled, 0 = disabled)',
+      ),
+      'settings' => array(
+        'type' => 'blob',
+        'not null' => FALSE,
+        'size' => 'big',
+        'serialize' => TRUE,
+        'description' => 'A serialized array of name value pairs that store the formatter settings for the display.',
+      ),
+    ),
+    'primary key' => array('name'),
+  );
+}
+
+/**
  * Implements hook_install().
  */
 function file_entity_install() {
@@ -49,6 +123,46 @@ function file_entity_install() {
 }
 
 /**
+ * Create the {file_display} database table.
+ */
+function file_entity_update_7000() {
+  db_create_table('file_display', _file_entity_schema_file_display_7000());
+}
+
+/**
+ * Move file display configurations from the 'file_displays' variable to the
+ * {file_display} database table.
+ */
+function file_entity_update_7001() {
+  $file_displays = variable_get('file_displays');
+  if (!empty($file_displays)) {
+    foreach ($file_displays as $file_type => $file_type_displays) {
+      if (!empty($file_type_displays)) {
+        foreach ($file_type_displays as $view_mode => $view_mode_displays) {
+          if (!empty($view_mode_displays)) {
+            foreach ($view_mode_displays as $formatter_name => $display) {
+              if (!empty($display)) {
+                db_merge('file_display')
+                  ->key(array(
+                    'name' => implode('__', array($file_type, $view_mode, $formatter_name)),
+                  ))
+                  ->fields(array(
+                    'status' => isset($display['status']) ? $display['status'] : 0,
+                    'weight' => isset($display['weight']) ? $display['weight'] : 0,
+                    'settings' => isset($display['settings']) ? serialize($display['settings']) : NULL,
+                  ))
+                  ->execute();
+              }
+            }
+          }
+        }
+      }
+    }
+  }
+  variable_del('file_displays');
+}
+
+/**
  * Implement hook_uninstall().
  */
 function file_entity_uninstall() {
diff --git a/includes/media.types.inc b/includes/media.types.inc
index 65a99d6..160c52b 100644
--- a/includes/media.types.inc
+++ b/includes/media.types.inc
@@ -43,32 +43,6 @@ function media_file_type_media_claim($file, $type) {
  * display.
  */
 function media_file_type_media_default_view($file, $view_mode, $langcode) {
-  // If the file is an image, attempt to display it using the File Entity
-  // module's image formatter.
-  if ($file->type == 'image') {
-    if ($view_mode == 'media_preview') {
-      $image_style = 'square_thumbnail';
-    }
-    elseif ($view_mode == 'media_large') {
-      $image_style = 'large';
-    }
-    elseif ($view_mode == 'media_original') {
-      $image_style = '';
-    }
-    if (isset($image_style)) {
-      $display = array(
-        'type' => 'file_image',
-        'settings' => array(
-          'image_style' => $image_style,
-        ),
-      );
-      $element = file_entity_file_formatter_file_image_view($file, $display, $langcode);
-      if (isset($element)) {
-        return $element;
-      }
-    }
-  }
-
   // During preview, or when custom attribute values are needed on the displayed
   // element, use a media icon.
   if ($view_mode == 'media_preview' || isset($file->override)) {
@@ -315,3 +289,33 @@ function media_type_batch_update($update_existing = FALSE, $no_to_update = NULL,
 
   return $results;
 }
+
+/**
+ * Implements hook_file_default_displays().
+ *
+ * Provides default display configurations for media types.
+ *
+ * @see file_entity_schema()
+ */
+function media_file_default_displays() {
+  $default_displays = array();
+
+  $default_image_styles = array(
+    'media_preview' => 'square_thumbnail',
+    'media_large' => 'large',
+    'media_original' => ''
+  );
+
+  foreach ($default_image_styles as $view_mode => $image_style) {
+    $display_name = 'image__' . $view_mode . '__file_image';
+    $default_displays[$display_name] = (object) array(
+      'api_version' => 1,
+      'name' => $display_name,
+      'status' => 1,
+      'weight' => 5,
+      'settings' => array('image_style' => $image_style),
+    );
+  }
+
+  return $default_displays;
+}
diff --git a/media.install b/media.install
index c322242..ff963b7 100644
--- a/media.install
+++ b/media.install
@@ -557,3 +557,18 @@ function media_update_7016() {
 
   field_cache_clear();
 }
+
+/**
+ * Move file display configurations from the 'file_displays' variable to the
+ * {file_display} table.
+ */
+function media_update_7017() {
+  // If the {file_display} table doesn't exist, then the File Entity module's
+  // update functions will automatically take care of migrating the
+  // configurations. However, if file_entity_update_7001() has already run
+  // prior to media_update_7016(), run it again in order to capture those
+  // configurations too.
+  if (db_table_exists('file_display')) {
+    file_entity_update_7001();
+  }
+}
diff --git a/media.module b/media.module
index f4715fb..2425954 100644
--- a/media.module
+++ b/media.module
@@ -1093,3 +1093,19 @@ function media_flush_caches() {
   // even if the post that references them is edited or deleted.
   db_delete('media_filter_usage')->condition('timestamp', REQUEST_TIME - 86400 * 120, '<')->execute();
 }
+
+/**
+ * Implements hook_ctools_plugin_api().
+ *
+ * Lets CTools know which plugin APIs are implemented by Media module.
+ */
+function media_ctools_plugin_api($owner, $api) {
+  static $api_versions = array(
+    'file_entity' => array(
+      'file_default_displays' => 1,
+    ),
+  );
+  if (isset($api_versions[$owner][$api])) {
+    return array('version' => $api_versions[$owner][$api]);
+  }
+}
