1

In a program I'm writing, I'd like to have the user select an image on the local machine via a file-selection dialog and then be able to insert the path of that image as the src attribute of an img tag.

<img src="file:/path/to/selected/image.png">

I'm using GWT right now and tried the FileUpload class but the getFilename() method doesn't return a real path under most browsers -- Windows Chrome returns it as C:\fakepath\image.png.

Is there a way, either under GWT or native Javascript, that will get the real path of a locally selected file?

Brian White
  • 7,745
  • 2
  • 37
  • 63

3 Answers3

2

I think you are interested in showing the image on client before upload on server in GWT.

Please have a look at below post:

Community
  • 1
  • 1
Braj
  • 44,339
  • 5
  • 51
  • 69
  • I don't actually want to upload the image. I want to be able to display it as an overlay, make some simple adjustments on it (css) and output some numbers once it looks the way the user wants. – Brian White May 08 '14 at 02:16
1

There's no way to get the real path of a locally selected file from a browser with javascript. It' a question of security. With HTML5 you could get the image itself and achieve what you want to achieve. THere's a nice lib for this: lib-gwt-file.jar

Spiff
  • 3,234
  • 4
  • 17
  • 40
  • Why is it insecure to know the pathname of a file the user selected? – Brian White May 08 '14 at 02:16
  • Javascript code would have access to the filesystem of the user, As far as i know no browser allows that – Spiff May 08 '14 at 05:39
  • However you can read the file with HTML5, put it in a Canvas and process it as you like. – Spiff May 08 '14 at 05:48
  • I suppose.. It could insert the filename as a `src` tag to a `script` element. But this is a filename selected by the user through a dialog which makes it an explicit user action. But it is what it is, I guess. – Brian White May 09 '14 at 11:59
  • I looked at that library, but it ended up being easier just to write a few lines of "native" Javascript instead. – Brian White May 12 '14 at 02:31
1

Building on the link provided by Braj... Here's how I did it:

private String imageDataUrl;

static private native void observeFileSelection(MainActivity main, Element uploader, Element error) /*-{
    function handleFileSelect(selevt) {
        error.innerHTML = "";

        var file = selevt.target.files[0];
        if (file.size > 1 * 1024 * 1024) {
            error.innerHTML = "Error: Image must be less that 1MiB in size.";
            return;
        }

        var reader = new FileReader();
        reader.onload = function (loadevt) {
            main.@com.example.app.MainActivity::setSelectedImageDataUrl(Ljava/lang/String;)(loadevt.target.result);
        }
        reader.readAsDataURL(file);
    }

    uploader.addEventListener("change", handleFileSelect, false);
}-*/;

public void setSelectedImageDataUrl(String dataurl) {
    imageDataUrl = dataurl;
}

private void handleOverlayButton() {
    final DialogBox dialog = new DialogBox();

    final HTMLPanel htmlpanel = new HTMLPanel(
            S.mainOverlayChooseText() + "<hr><div id='fileupload'></div><div id='fileerror' style='color:red'></div><hr>");
    dialog.setHTML("<b>" + S.mainOverlayChooseTitle() + "</b>");
    dialog.add(htmlpanel);
    dialog.setAnimationEnabled(true);
    dialog.setGlassEnabled(true);
    dialog.addStyleName("info-dialog");

    final FileUpload file = new FileUpload();
    file.setName("imgfile");
    htmlpanel.add(file, "fileupload");
    final SimplePanel error = new SimplePanel();
    htmlpanel.add(error, "fileerror");

    final Button ok = new Button(S.buttonOk());
    ok.addClickHandler(new ClickHandler() {
        @Override
        public void onClick(ClickEvent event) {
            dialog.hide();
            dialog.clear();
            setOverlayImage(imageDataUrl);
            imageDataUrl = null;
        }
    });
    htmlpanel.add(ok);

    final Button cancel = new Button(S.buttonCancel());
    cancel.addClickHandler(new ClickHandler() {
        @Override
        public void onClick(ClickEvent event) {
            dialog.hide();
            dialog.clear();
            imageDataUrl = null;
        }
    });
    htmlpanel.add(cancel);

    dialog.center();
    dialog.show();
    observeFileSelection(this, file.getElement(), error.getElement());
}

private void setOverlayImage(String dataurl) {
    // just for testing
    final AbsolutePanel overlay = new AbsolutePanel();
    final Image image = new Image(dataurl);
    overlay.add(image);
    RootPanel.get().add(overlay);
}

Hope that helps if others are trying to do the same.

Brian White
  • 7,745
  • 2
  • 37
  • 63