diff --git a/electron/index.js b/electron/index.js
index f49eeb6aa..8dea1e234 100644
--- a/electron/index.js
+++ b/electron/index.js
@@ -299,6 +299,32 @@ app.on('before-quit', () => {
   appState.isQuitting = true;
 });
 
+// Get the content of a file as a raw buffer of bytes.
+// Useful to convert a file path to a File instance.
+// Example:
+// const result = await ipcMain.invoke('get-file-from-path', 'path/to/file');
+// const file = new File([result.buffer], result.name);
+ipcMain.handle('get-file-from-path', (event, path) => {
+  return new Promise((resolve, reject) => {
+    // Encoding null ensures data results in a Buffer.
+    fs.readFile(path, { encoding: null }, (err, data) => {
+      if (err) {
+        reject(err);
+        return;
+      }
+      // Separate folders considering "\" and "/"
+      // as separators (cross platform)
+      const folders = path.split(/[\\/]/);
+      const fileName = folders[folders.length - 1];
+      resolve({
+        name: fileName,
+        path: path,
+        buffer: data,
+      });
+    });
+  });
+});
+
 ipcMain.on('get-disk-space', async (event) => {
   try {
     const { data_dir } = await Lbry.settings_get();
diff --git a/ui/component/common/file-selector.jsx b/ui/component/common/file-selector.jsx
index bd1729d31..a74b5cb27 100644
--- a/ui/component/common/file-selector.jsx
+++ b/ui/component/common/file-selector.jsx
@@ -1,6 +1,7 @@
 // @flow
 import * as React from 'react';
 import * as remote from '@electron/remote';
+import { ipcRenderer } from 'electron';
 import Button from 'component/button';
 import { FormField } from 'component/common/form';
 
@@ -14,6 +15,7 @@ type Props = {
   error?: string,
   disabled?: boolean,
   autoFocus?: boolean,
+  filters?: Array<{ name: string, extension: string[] }>,
 };
 
 class FileSelector extends React.PureComponent<Props> {
@@ -64,13 +66,26 @@ class FileSelector extends React.PureComponent<Props> {
       properties = ['openDirectory'];
     }
 
-    remote.dialog.showOpenDialog({ properties, defaultPath }).then((result) => {
-      const path = result && result.filePaths[0];
-      if (path) {
-        // $FlowFixMe
-        this.props.onFileChosen({ path });
-      }
-    });
+    remote.dialog
+      .showOpenDialog({
+        properties,
+        defaultPath,
+        filters: this.props.filters,
+      })
+      .then((result) => {
+        const path = result && result.filePaths[0];
+        if (path) {
+          return ipcRenderer.invoke('get-file-from-path', path);
+        }
+        return undefined;
+      })
+      .then((result) => {
+        if (!result) {
+          return;
+        }
+        const file = new File([result.buffer], result.name);
+        this.props.onFileChosen(file);
+      });
   };
 
   fileInputButton = () => {
diff --git a/ui/component/selectAsset/view.jsx b/ui/component/selectAsset/view.jsx
index 13fe2c324..05b9d92bb 100644
--- a/ui/component/selectAsset/view.jsx
+++ b/ui/component/selectAsset/view.jsx
@@ -27,6 +27,14 @@ type Props = {
   // passed to the onUpdate function after the
   // upload service returns success.
   buildImagePreview?: boolean,
+  // File extension filtering. Files can be filtered
+  // but the "All Files" options always shows up. To
+  // avoid that, you can use the filters property.
+  // For example, to only accept images pass the
+  // following filter:
+  // { name: 'Images', extensions: ['jpg', 'png', 'gif'] },
+  filters?: Array<{ name: string, extension: string[] }>,
+  type?: string,
 };
 
 function filePreview(file) {
@@ -43,7 +51,8 @@ function filePreview(file) {
 }
 
 function SelectAsset(props: Props) {
-  const { onUpdate, onDone, assetName, currentValue, recommended, title, inline, buildImagePreview } = props;
+  const { onUpdate, onDone, assetName, currentValue, recommended, title, inline, buildImagePreview, filters, type } =
+    props;
   const [pathSelected, setPathSelected] = React.useState('');
   const [fileSelected, setFileSelected] = React.useState<any>(null);
   const [uploadStatus, setUploadStatus] = React.useState(SPEECH_READY);
@@ -121,6 +130,8 @@ function SelectAsset(props: Props) {
           />
         ) : (
           <FileSelector
+            filters={filters}
+            type={type}
             autoFocus
             disabled={uploadStatus === SPEECH_UPLOADING}
             label={fileSelectorLabel}
diff --git a/ui/modal/modalImageUpload/view.jsx b/ui/modal/modalImageUpload/view.jsx
index b76fe10db..9bbc0e8ce 100644
--- a/ui/modal/modalImageUpload/view.jsx
+++ b/ui/modal/modalImageUpload/view.jsx
@@ -14,10 +14,13 @@ type Props = {
 
 function ModalImageUpload(props: Props) {
   const { closeModal, currentValue, title, assetName, helpText, onUpdate } = props;
+  const filters = React.useMemo(() => [{ name: 'Images', extensions: ['jpg', 'png', 'gif'] }]);
 
   return (
     <Modal isOpen type="card" onAborted={closeModal} contentLabel={title}>
       <SelectAsset
+        filters={filters}
+        type="openFile"
         onUpdate={onUpdate}
         currentValue={currentValue}
         assetName={assetName}