Electron JS Images from Local File System
Asked Answered
A

3

30

I am new to electron and trying to load images from the local file system to display it on screen. So for images from the remote URLs are working just fine when I do

<img src='https://example.com/image.jpg' />

But when I try to load the same image from the local file system in my render process it does not work

<img src='file:///C:/tmp/image.jpg' />

is not rendered.

This is the error I got:

> Not allowed to load local resource:
> file:///C:/tmp/nW4jY0CHsepy08J9CkF1u3CJVfi4Yvzl_screenshot.png
> dashboard:1 Not allowed to load local resource:
> file:///C:/tmp/TOyUYWnJK7VS9wWeyABhdgCNmp38FyHt_screenshot.png

enter image description here

Is there any configuration that needs to be made to allow the electron to render images from the local file system Or I am doing it entirely wrong?

Amabel answered 10/5, 2018 at 11:58 Comment(6)
And do you get an error about the image not being found? What if you switch / for `\`Saltwater
Sorry, I just updated my question to include the error and the screenshot.Amabel
if you wanna load local resource in renderrer process, I think you need to disable websecurity, as mentioned here github.com/electron/electron/issues/5107.Ebeneser
@RohnJohn Yes I did follow that document, but disabling websecurity may pose a huge security risk. I did it through readFileSync base64 but it just kills the performance for large resolution files. I wonder how other people do it?Amabel
I think the best choice is to put your images to cloud, or serve it by yourselfEbeneser
How would you load images from local filesystem and render it?Amabel
A
24

Electron by default allows local resources to be accessed by render processes only when their html files are loaded from local sources with the file:// protocol for security reasons.

If you are loading the html from any http:// or https:// protocol even from a local server like webpack-dev-server, access to local resources is disabled.

If you loading html pages from a local server only during development and switching to local html files in production, you can disable websecurity during development, taking care to enable it in production.

If you are loading html from remote sources even in production, the best and secure way is to upload it somewhere on your server and load it.

Achorn answered 13/5, 2018 at 18:22 Comment(1)
This makes sense and now I am using the relative paths to avoid the issue in development. Thankyou.Amabel
G
4

Method 1. Implement protocol.interceptFileProtocol with scheme 'file'.

Call callback with the file's directory path

Method 2. Implement session.defaultSession.webRequest.onBeforeRequest with a filter on 'file:///'.

In the callback load the file via node, convert to Base64 and return that.

Elaborating on Method 1:

protocol.interceptFileProtocol('resource', (req: ProtocolRequest, callback: (filePath: string) => void) => {

            if (someCondition) {

                const url = GetSomeFilePath(req.url);
                callback(url);

            }
            else {                

                callback(req.url);

            }            

        }); 
Gwenny answered 9/6, 2020 at 8:19 Comment(3)
I am interested in method 2 but is this valid in the context of large files as well i.e. loading a local video from disk?Aerator
Tried to read around for method 1, but not many good recent examples.Aerator
@joeyj Method 2 is probably not good for video as it converts the whole file to base64 and video needs to be streamed.Gwenny
K
0

I am working with an electron-react

"react": "^18.2.0", "electron": "^29.2.0"

app and I wanted to render images from my local drive. Because of security rules with electron, this is not an easy job. After the depreciation of electron protocol.registerFileProtocol(...), I spend hours trying to figure out how to work with protocol.handle(....).

// Deprecated in Electron 25
protocol.registerFileProtocol('some-protocol', () => {
  callback({ filePath: '/path/to/my/file' })
})

// Replace with
protocol.handle('some-protocol', () => {
  return net.fetch('file:///path/to/my/file')
})

electron docs

I managed to work it out like this:

main.js

app.whenReady().then(() => {
  protocol.handle('my-protocol', async (request, callback) => {
    const filePath = request.url.replace(`my-protocol://`, 'file://');
    return net.fetch(filePath);
  });

  createWindow();
});

MyReactComponent.jsx

...
<div>
  <img
     src={`my-protocol://${imageLocalPath}`}
     alt='my-alt'
     className='my-classname'
  />
</div>
...

Everything worked. I hope I helped!

Kary answered 11/5, 2024 at 8:7 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.