Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Select and display an image from the filesystem with electron

I'm developing a little app in Electron from which I can upload an image to Instagram and I'm stuck at one of the first steps :/

I want to select an image from the filesystem and display it in my app.

This is the code I've got so far:

CODE:

remote.dialog.showOpenDialog((filenames) => {
    fs.readFile(filepath, 'utf-8', (err, data) => {

        if(err){
            alert("An error ocurred reading the file :" + err.message);
            return;
        }
    });
});
like image 208
4 revs Avatar asked Jun 10 '18 08:06

4 revs


3 Answers

Here is a solution with more information on separation of main process and renderer and usage of es6

main process

import { ipcMain, dialog } from "electron";
import fs from 'fs';

ipcMain.on("chooseFile", (event, arg) => {
  const result = dialog.showOpenDialog({
    properties: ["openFile"],
    filters: [{ name: "Images", extensions: ["png","jpg","jpeg"] }]
  });

  result.then(({canceled, filePaths, bookmarks}) => {
    const base64 = fs.readFileSync(filePaths[0]).toString('base64');
    event.reply("chosenFile", base64);
  });
});

renderer process

import electron from 'electron';

// trigger file prompt
electron.ipcRenderer.send('chooseFile');

// handle response
electron.ipcRenderer.on('chosenFile', (event, base64) => {
  const src = `data:image/jpg;base64,${base64}`
})
like image 106
oshell Avatar answered Oct 06 '22 01:10

oshell


A minimal example to select, read and display a png image.

Renderer process:::

var remote = require('electron').remote;
var fs = remote.require('fs');

  
remote.dialog.showOpenDialog(remote.getCurrentWindow(),
   {
    filters: [
      {name: 'Images', extensions: ['png']}
    ]
   }, 
   function(filepaths, bookmarks) {
     //read image (note: use async in production)
     var _img = fs.readFileSync(filepaths[0]).toString('base64');
     //example for .png
     var _out = '<img src="data:image/png;base64,' + _img + '" />';
     //render/display
     var _target = document.getElementById('image_container');
     _target.insertAdjacentHTML('beforeend', _out);

     return;
});
<div id="image_container"></div>
like image 28
11AND2 Avatar answered Oct 05 '22 23:10

11AND2


With electron 11 the following snippet from https://www.electronjs.org/docs/api/protocol works

app.whenReady().then(() => {
  protocol.registerFileProtocol('atom', (request, callback) => {
    console.log(request.url)
    const url = request.url.substr(7)
    callback({ path: url })
  })
})

Be careful not to use the usual file:// protocol, but the custom 'atom' or 'my_whatever' protocol instead

You can now get the image this way :

<img src="atom://C:\\Users\\my_path\\myfile.png" />

However if you wan't to keep the syntaxe of the file protocol in the render side, you can do the following :

protocol.registerFileProtocol('file', ()=>...)

Now you can get an image this way

<img src="file://C:\\Users\\my_path\\myfile.png" />

However you will have to disable webSecurity

const mainWindow = new BrowserWindow({
webPreferences: {
  nodeIntegration : true,
  webSecurity: false
}
like image 27
nicoNz Avatar answered Oct 06 '22 01:10

nicoNz