diff --git a/client/css/icons/style.css b/client/css/icons/style.css
index 90f70bd022f65b24335883a7fcdd899db7d42c7a..995a6b2a6d7272a2ba770be7f7a77f7e31dae74b 100644
--- a/client/css/icons/style.css
+++ b/client/css/icons/style.css
@@ -596,6 +596,9 @@
 .icon-language1:before {
   content: "\e2a8";
 }
+.icon-vm4vmp:before {
+  content: "\e2a8";
+}
 .icon-layers:before {
   content: "\e1d3";
 }
diff --git a/client/javascript/app/directives/workspaceListDrtv.js b/client/javascript/app/directives/workspaceListDrtv.js
index 6da6cf43c6439b60c045ff651c0bbfdd1ee3b9a2..f16ccb8e9b199c234322e0cf8aae1ad166428bf4 100755
--- a/client/javascript/app/directives/workspaceListDrtv.js
+++ b/client/javascript/app/directives/workspaceListDrtv.js
@@ -187,6 +187,9 @@ vitisApp.appWorkspaceListDrtv = function ($timeout, $rootScope, $templateRequest
                                     // Rafraîchit le formulaire.
                                     scope.$broadcast('$$rebind::refresh');
                                     scope.$apply();
+                                    // Rafraîchit les listes du formulaire.
+                                    var oFormScope = angular.element($('#' + envSrvc["oFormDefinition"][envSrvc["sFormDefinitionName"]]["name"]).children()).scope();
+                                    oFormScope['ctrl'].extractFormDefinitionInfos();
                                 }
                             }
                         });
diff --git a/client/javascript/externs/formReader/component/file_picker/file_picker.css b/client/javascript/externs/formReader/component/file_picker/file_picker.css
index a759ec8a43352f0afdbb2fdd36cbc66b05a01322..14bac1a02f071760a18454cc26398d549791570d 100644
--- a/client/javascript/externs/formReader/component/file_picker/file_picker.css
+++ b/client/javascript/externs/formReader/component/file_picker/file_picker.css
@@ -81,12 +81,15 @@
     height: 90px !important;
 }
 .modal-image-zone {
+    text-align: center;
     max-height: 600px;
     overflow-y: auto;
 }
 .modal-image-zone > img {
     height: auto;
     width: 100%;
+    max-width: 350px;
+    max-height: 350px;
 }
 
 .file_picker .container {
diff --git a/client/javascript/externs/formReader/component/file_picker/file_picker.html b/client/javascript/externs/formReader/component/file_picker/file_picker.html
index 2c96555bfb9f0561207770d455d2262aefbd486e..4a3243d8b3ef881c2a5b1e69cd1309c8f4dec536 100644
--- a/client/javascript/externs/formReader/component/file_picker/file_picker.html
+++ b/client/javascript/externs/formReader/component/file_picker/file_picker.html
@@ -50,21 +50,23 @@
     <!-- Bouton caché input -->
     <div class="hide"
          ng-if="!field.displayOnly">
+        <!-- Simple -->
         <input ng-if="!field.multiple"
                type="file"
                id="{{:refresh:field.id}}_hidden"
                class="file"
                name="{{:refresh:field.name}}"
                class="form-control"
-               ng-attr-accept="{{ field.type === 'image_wsdata' ? 'image/*' : '*' }}"
+               ng-attr-accept="{{ field.type === 'image_wsdata' ? 'image/*' : (field.formats.length > 0 ? getFormatsRestrict() : '*') }}"
                ng-required="field.required">
+        <!-- Multiple -->
         <input ng-if="field.multiple"
                type="file"
                id="{{:refresh:field.id}}_hidden"
                class="file"
                name="{{:refresh:field.name}}"
                class="form-control"
-               ng-attr-accept="{{ field.type === 'image_wsdata' ? 'image/*' : '*' }}"
+               ng-attr-accept="{{ field.type === 'image_wsdata' ? 'image/*' : (field.formats.length > 0 ? getFormatsRestrict() : '*') }}"
                ng-required="field.required" multiple>
     </div>
 
diff --git a/client/javascript/externs/formReader/component/file_picker/file_picker.js b/client/javascript/externs/formReader/component/file_picker/file_picker.js
index b53261f06a1af832d28772ca6bbf1b3a92c3581b..6ae3324962dfceca6e2d9012e0c5959ed05771af 100644
--- a/client/javascript/externs/formReader/component/file_picker/file_picker.js
+++ b/client/javascript/externs/formReader/component/file_picker/file_picker.js
@@ -99,11 +99,12 @@ nsVitisComponent.FilePickerDirective = function ($timeout, $translate, propertie
 
                     // Affiche les images présentes sur le serveur
                     var aAvaliableFiles = scope["oFormValues"][scope["sFormDefinitionName"]][scope['field'].name];
-                    if (scope['field']['multiple'] !== true) {
-                        if (goog.isString(aAvaliableFiles)) {
-                            aAvaliableFiles = [aAvaliableFiles];
-                        }
+
+                    // Rétrocompatibilité API
+                    if (goog.isString(aAvaliableFiles)) {
+                        aAvaliableFiles = [aAvaliableFiles];
                     }
+
                     if (goog.isDefAndNotNull(aAvaliableFiles)) {
                         scope['addFilesFromURL'](aAvaliableFiles).then(function(){
 
@@ -546,27 +547,6 @@ nsVitisComponent.FilePickerDirective = function ($timeout, $translate, propertie
             scope['showImageModal'] = function(oImage, oBlob) {
                 $log.log("formReader.FilePickerDirective.showImageModal");
 
-                // Téléchargement image grande si thumbnail
-                if (goog.isDefAndNotNull(oImage._url) && oImage._thumbnail === true) {
-                    scope['downloadFileBlob'](oImage._url, false, 3).then(function(oBlob){
-                        var picReader = new FileReader();
-                        picReader.addEventListener('load', angular.bind(this, function (oBlob, event) {
-                            var picFile = event.target;
-                            scope.$applyAsync(function(){
-                                scope['showImageModal']({
-                                    'name': oBlob['name'],
-                                    'src': picFile['result'],
-                                    _url: oBlob._url,
-                                    _thumbnail: oBlob._thumbnail
-                                }, oBlob);
-                            });
-                        }, oBlob));
-                        picReader.readAsDataURL(oBlob);
-
-                    });
-                    return 0;
-                }
-
                 var iImageIndex;
                 for (var i = 0; i < scope['aPreviewImages'].length; i++) {
                     if(scope['aPreviewImages'][i]['name'] === oImage['name']){
@@ -590,7 +570,7 @@ nsVitisComponent.FilePickerDirective = function ($timeout, $translate, propertie
                  * Téléchargement de l'image
                  */
                 $(domDownloadButton).click(function(){
-                    scope['downloadFile'](oImage, oBlob);
+                    scope['downloadDocument'](oImage);
                 });
 
                 /**
@@ -711,6 +691,32 @@ nsVitisComponent.FilePickerDirective = function ($timeout, $translate, propertie
                 // Fichiers à envoyer
                 scope['oFormValues'][scope['sFormDefinitionName']][scope['field'].name] = scope['aFiles'];
             }
+
+            /**
+             * Retourne les restrictions de type input=file
+             */
+            scope['getFormatsRestrict'] = function() {
+
+                var sRestrictedFormats;
+                var aImgExtencions = [''];
+
+                if (goog.isString(scope.field.formats)) {
+
+                    var aRestrictedFormats = [];
+                    var aFormats = scope.field.formats.split('|');
+
+                    for (var i = 0; i < aFormats.length; i++) {
+                        aRestrictedFormats.push('.' + aFormats[i]);
+                    }
+
+                    sRestrictedFormats = aRestrictedFormats.join(', ');
+
+                } else {
+                    sRestrictedFormats = scope.field.formats;
+                }
+
+                return sRestrictedFormats;
+            }
         }
     };
 };
diff --git a/client/javascript/externs/mapJSON/MapJSON.js b/client/javascript/externs/mapJSON/MapJSON.js
index 0d98c0487f4de44920d87be6070a95f0702f16da..1f631eb3536f9f76a3bd0b8a29c2a790df270b98 100755
--- a/client/javascript/externs/mapJSON/MapJSON.js
+++ b/client/javascript/externs/mapJSON/MapJSON.js
@@ -597,8 +597,11 @@ MapJSON.prototype.getLayerFromLayerDef_ = function (oMapDefinition, oLayerDef, o
     }
     if (goog.isDefAndNotNull(oLayerDef['is_filtered'])) {
         if (goog.isDefAndNotNull(oLayerDef['filter_form'])) {
-            if (goog.isString(oLayerDef['filter_form']) && oLayerDef['filter_form'].length !== 0) {
-                oLayerDef['filter_form'] = JSON.parse(oLayerDef['filter_form']);
+            if ((goog.isString(oLayerDef['filter_form']) && oLayerDef['filter_form'].length !== 0) ||
+                goog.isObject(oLayerDef['filter_form'])) {
+                if (goog.isString(oLayerDef['filter_form'])) {
+                    oLayerDef['filter_form'] = JSON.parse(oLayerDef['filter_form']);
+                }
                 oLayerDef['filter_values'] = this.getFilterFormValues_(oLayerDef['filter_form']);
                 layer.set('filter_form', oLayerDef['filter_form']);
                 layer.set('filter_form_embedjs', oLayerDef['filter_form_embedjs']);
diff --git a/vas/rest/class/vmlib/files/Files_manager.class.inc b/vas/rest/class/vmlib/files/Files_manager.class.inc
index 46dcf6f99fd5cfe6b2e061ed5a20b1843dd63072..df8a89bcac44e25f15f3aa2dc9f91c906791b541 100644
--- a/vas/rest/class/vmlib/files/Files_manager.class.inc
+++ b/vas/rest/class/vmlib/files/Files_manager.class.inc
@@ -259,6 +259,70 @@ class Files_manager{
         return $aFileStruc;
     }
 
+    /**
+     * Upload la miniature du fichier si il s'agit l'image ou retourne false
+     *
+     * @param  {array} $aFileStruct    Structure du fichier
+     * @param  {string} $sDestPath     Répertoire de destination
+     * @param  {string} $sField        Champ en base de données
+     * @param  {string} $sMinDestPath  Répertoire de destination du fichier min
+     * @param  {integer} $iMaxSize     Taille maximale du fichier
+     * @return {boolean}               true en cas de succes
+     */
+    private function uploadImageThumbnail($aFileStruct, $sDestPath, $sField, $sMinDestPath, $iMaxSize = -1) {
+
+        $aImgSize = getimagesize($aFileStruct['tmp_name']);
+
+        // Si image
+        if(@is_array($aImgSize)){
+
+            $aThumbnailFileStruct = $aFileStruct;
+            $aThumbnailFileStruct["width"] = 200;
+            $aThumbnailFileStruct["height"] = 200;
+
+            if (is_int($this->oProperties['filesystem_thumbnails_max_width']) &&
+                is_int($this->oProperties['filesystem_thumbnails_max_height'])) {
+
+                $imgWidth = $aImgSize[0];
+                $imgHeight = $aImgSize[1];
+
+                // Redimentionne la largeur en conservant le ratio
+                if ($imgWidth > $this->oProperties['filesystem_thumbnails_max_width']) {
+                    $imgHeight = round($imgHeight * $this->oProperties['filesystem_thumbnails_max_width'] / $imgWidth);
+                    $imgWidth = $this->oProperties['filesystem_thumbnails_max_width'];
+                }
+
+                // Redimentionne la hauteur en conservant le ratio
+                if ($imgHeight > $this->oProperties['filesystem_thumbnails_max_height']) {
+                    $imgWidth = round($imgWidth * $this->oProperties['filesystem_thumbnails_max_height'] / $imgHeight);
+                    $imgHeight = $this->oProperties['filesystem_thumbnails_max_height'];
+                }
+
+                $aThumbnailFileStruct["height"] = $imgHeight;
+                $aThumbnailFileStruct["width"] = $imgWidth;
+            }
+
+            $aThumbnailFileStruct['tmp_name'] = $aThumbnailFileStruct['tmp_name'] . '.min';
+            $aDestPathExt = explode('.', $sDestPath);
+
+            $aDestPathExt = explode('.', $sDestPath);
+
+            // Ajoute .min sur la destination
+            array_splice($aDestPathExt, -1, 0, 'min');
+            $sMinDestPath = implode('.', $aDestPathExt);
+
+            // Copie le fichier dans tmp
+            copy($aFileStruct['tmp_name'], $aThumbnailFileStruct['tmp_name']);
+
+            // Upload le fichier .min.jpg
+            $this->uploadFile($sField, "image", $sMinDestPath, $iMaxSize, $aThumbnailFileStruct);
+
+            return true;
+        } else {
+            return false;
+        }
+    }
+
     /**
      *This method upload a file in ws_data.
      *@param $sModule Name of the module.
@@ -356,26 +420,7 @@ class Files_manager{
         // Image miniature
         $sMinDestPath = null;
         if ($bCreateThumbnail === true && file_exists($aFileStruct['tmp_name'])) {
-
-            // Si image
-            if(@is_array(getimagesize($aFileStruct['tmp_name']))){
-
-                $aThumbnailFileStruct = $aFileStruct;
-                $aThumbnailFileStruct["width"] = 200;
-                $aThumbnailFileStruct["height"] = 200;
-                $aThumbnailFileStruct['tmp_name'] = $aThumbnailFileStruct['tmp_name'] . '.min';
-                $aDestPathExt = explode('.', $sDestPath);
-
-                // Ajoute .min sur la destination
-                array_splice($aDestPathExt, -1, 0, 'min');
-                $sMinDestPath = implode('.', $aDestPathExt);
-
-                // Copie le fichier dans tmp
-                copy($aFileStruct['tmp_name'], $aThumbnailFileStruct['tmp_name']);
-
-                // Upload le fichier .min.jpg
-                $this->uploadFile($sField, "image", $sMinDestPath, $iMaxSize, $aThumbnailFileStruct);
-            }
+            $this->uploadImageThumbnail($aFileStruct, $sDestPath, $sField, $sMinDestPath, $iMaxSize);
         }
 
         // Upload du fichier
diff --git a/vas/rest/conf/properties_server.inc b/vas/rest/conf/properties_server.inc
index 494c13e697f984b236ba8e59c84bd894572e9cf1..9b34fdadd7ae222fac65ec5f264f1377555cd898 100644
--- a/vas/rest/conf/properties_server.inc
+++ b/vas/rest/conf/properties_server.inc
@@ -49,6 +49,8 @@ $properties["notifierAccessKeyAccount"] = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
 $properties["notifierSecretKeyAccount"] = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX";
 // utilisation de s3 pour remplacer le système de Fichier
 $properties['filesystem'] = 'fs'; // s3
+$properties['filesystem_thumbnails_max_width'] = 350; // taille maximale des images .min.jpg
+$properties['filesystem_thumbnails_max_height'] = 350; // taille maximale des images .min.jpg
 $properties['AWSCredentialsFilePath'] = ""; // .../.aws/credentials
 $properties["fileS3UploaderProfil"] = "";
 $properties["fileS3UploaderBucket"] = "";