Asked  5 Months ago    Answers:  5   Viewed   29 times

Reference: FileReader.readAsDataURL

Considering the following example:

function previewFile(file) {

  var reader  = new FileReader();

  reader.onloadend = function () {
    console.log(reader.result);
  }
  reader.readAsDataURL(file);
}

It states:

instanceOfFileReader.readAsDataURL(blob);

blob: The Blob or File from which to read.

  1. How can a local file URL like: 'file:///C:/path-to/root.png' be passed to the readAsDataURL()

  2. Is FileReader() available in a Firefox Addon?

 Answers

41

This information is outdated as of now, but cannot be deleted.

  1. You can create File instances just by specifying a path when your code is chrome-privileged:

    new File("/path/to/file");
    

    File is a sub-class of Blob, so all File instances are also valid Blobs. Please note that this requires a platform path, and not a file URL.

  2. Yes, FileReader is available to addons.

File and FileReader are available in all windows. If you want to use them in a non-window scope (like bootstrap.js or a code module), you may use nsIDOMFile/nsIDOMFileReader.

Thursday, June 3, 2021
 
Strae
answered 5 Months ago
74

well, I keep looking for solutions and I found this one: Canvas.

Canvas element have the toDataUrl() method that returns a Data URL for the image that it contains.

So I keep doing the same thing but when I submit the form I use the following function:

function putImage(){
    var url = document.getElementById("img1").src; // 'img1' is the thumbnail - I had to put an id on it
    var canvas = document.getElementById("MyCanvas");
    if (canvas.getContext) {
        var ctx = canvas.getContext("2d");

        var img = new Image();
        img.src = url;
        img.onload = function () {
            // Desenha a imagem no canvas...
            ctx.drawImage(img,0,0);

            // Grava o Data URL na imagem...
            var myImage = canvas.toDataURL("image/png");
            document.getElementById("dataurl").value = myImage;
        }
    }
};

I create one more element on the page for canvas:

<canvas id="MyCanvas">This browser or document mode doesn't support canvas</canvas>

and one more element on the form to save the Data URL:

<input id="dataurl" name="dataurl" type="text" size="50" />

well, now I can get it all in PHP and do something like this:

if($_POST)
{
    //echo '<pre>'; print_r($_POST); echo '</pre>';

    $blob = $_POST['bloburl'];
    $type = $_POST['blobtype'];
    $data = $_POST['dataurl'];

    $contents_split = explode(',', $data);
    $encoded = $contents_split[count($contents_split)-1];
    $decoded = "";
    for ($i=0; $i < ceil(strlen($encoded)/256); $i++) {
        $decoded = $decoded . base64_decode(substr($encoded,$i*256,256)); 
    }

    $fp = fopen('imagembaixada.jpg', 'w');
        fwrite($fp, $decoded);
        fclose($fp);
    }
}

Now my image is saved.

It works, but looks pretty inefficient.

If someone knows a better way to create a preview for images before upload them, please tell me!

Wednesday, March 31, 2021
 
Shreejibawa
answered 7 Months ago
34

The current recommendation (with JDK 1.7+) is to convert URL ? URI ? Path. So to convert a URL to File, you would say Paths.get(url.toURI()).toFile(). If you can’t use JDK 1.7 yet, I would recommend new File(URI.getSchemeSpecificPart()).

Converting file ? URI: First I’ll show you some examples of what URIs you are likely to get in Java.

                          -classpath URLClassLoader File.toURI()                Path.toUri()
C:Program Files          file:/C:/Program%20Files/ file:/C:/Program%20Files/   file:///C:/Program%20Files/
C:main.c++               file:/C:/main.c++         file:/C:/main.c++           file:///C:/main.c++
\VBOXSVRDownloads       file://VBOXSVR/Downloads/ file:////VBOXSVR/Downloads/ file://VBOXSVR/Downloads/
C:Résume.txt             file:/C:/R%c3%a9sume.txt  file:/C:/Résume.txt         file:///C:/Résume.txt
\?C:Windows (non-path) file://%3f/C:/Windows/    file:////%3F/C:/Windows/    InvalidPathException

Some observations about these URIs:

  • The URI specifications are RFC 1738: URL, superseded by RFC 2396: URI, superseded by RFC 3986: URI. (The WHATWG also has a URI spec, but it does not specify how file URIs should be interpreted.) Any reserved characters within the path are percent-quoted, and non-ascii characters in a URI are percent-quoted when you call URI.toASCIIString().
  • File.toURI() is worse than Path.toUri() because File.toURI() returns an unusual non-RFC 1738 URI (gives file:/ instead of file:///) and does not format URIs for UNC paths according to Microsoft’s preferred format. None of these UNC URIs work in Firefox though (Firefox requires file://///).
  • Path is more strict than File; you cannot construct an invalid Path from “.” prefix. “These prefixes are not used as part of the path itself,” but they can be passed to Win32 APIs.

Converting URI ? file: Let’s try converting the preceding examples to files:

                            new File(URI)            Paths.get(URI)           new File(URI.getSchemeSpecificPart())
file:///C:/Program%20Files  C:Program Files         C:Program Files         C:Program Files
file:/C:/Program%20Files    C:Program Files         C:Program Files         C:Program Files
file:///C:/main.c++         C:main.c++              C:main.c++              C:main.c++
file://VBOXSVR/Downloads/   IllegalArgumentException \VBOXSVRDownloads     \VBOXSVRDownloads
file:////VBOXSVR/Downloads/ \VBOXSVRDownloads      \VBOXSVRDownloads     \VBOXSVRDownloads
file://///VBOXSVR/Downloads \VBOXSVRDownloads      \VBOXSVRDownloads     \VBOXSVRDownloads
file://%3f/C:/Windows/      IllegalArgumentException IllegalArgumentException \?C:Windows
file:////%3F/C:/Windows/    \?C:Windows           InvalidPathException     \?C:Windows

Again, using Paths.get(URI) is preferred over new File(URI), because Path is able to handle the UNC URI and reject invalid paths with the ? prefix. But if you can’t use Java 1.7, say new File(URI.getSchemeSpecificPart()) instead.

By the way, do not use URLDecoder to decode a file URL. For files containing “+” such as “file:///C:/main.c++”, URLDecoder will turn it into “C:main.c  ”! URLDecoder is only for parsing application/x-www-form-urlencoded HTML form submissions within a URI’s query (param=value&param=value), not for unquoting a URI’s path.

2014-09: edited to add examples.

Friday, July 9, 2021
 
skrilled
answered 4 Months ago
62

Normally, one would use FormData to compose the postData of a request, but unfortunately we cannot do so here, as there is currently no way to get the stream (and other information) from a FormData instance (nsIXHRSendable is not scriptable, unfortunately), so we'll have to create a multipart/form-data stream ourselves.

Since it is likely you'll want to post some file data as well, I added file uploads as well. ;)

function encodeFormData(data, charset) {
  let encoder = Cc["@mozilla.org/intl/saveascharset;1"].
                createInstance(Ci.nsISaveAsCharset);
  encoder.Init(charset || "utf-8",
               Ci.nsISaveAsCharset.attr_EntityAfterCharsetConv + 
               Ci.nsISaveAsCharset.attr_FallbackDecimalNCR,
               0);
  let encode = function(val, header) {
    val = encoder.Convert(val);
    if (header) {
      val = val.replace(/rn/g, " ").replace(/"/g, "\"");
    }
    return val;
  }

  let boundary = "----boundary--" + Date.now();
  let mpis = Cc['@mozilla.org/io/multiplex-input-stream;1'].
             createInstance(Ci.nsIMultiplexInputStream);
  let item = "";
  for (let k of Object.keys(data)) {
    item += "--" + boundary + "rn";
    let v = data[k];
    if (v instanceof Ci.nsIFile) {
      let fstream = Cc["@mozilla.org/network/file-input-stream;1"].
                    createInstance(Ci.nsIFileInputStream); 
      fstream.init(v, -1, -1, Ci.nsIFileInputStream.DEFER_OPEN);
      item += "Content-Disposition: form-data; name="" + encode(k, true) + "";" +
              " filename="" + encode(v.leafName, true) + ""rn";
      let ctype = "application/octet-stream";
      try {
        let mime = Cc["@mozilla.org/mime;1"].getService(Ci.nsIMIMEService);
        ctype = mime.getTypeFromFile(v) || ctype;
      }
      catch (ex) {
        console.warn("failed to get type", ex);
      }
      item += "Content-Type: " + ctype + "rnrn";
      let ss = Cc["@mozilla.org/io/string-input-stream;1"].
               createInstance(Ci.nsIStringInputStream);
      ss.data = item;
      mpis.appendStream(ss);
      mpis.appendStream(fstream);
      item = "";
    }
    else {
      item += "Content-Disposition: form-data; name="" + encode(k, true) + ""rnrn";
      item += encode(v);
    }
    item += "rn";
  }
  item += "--" + boundary + "--rn";
  let ss = Cc["@mozilla.org/io/string-input-stream;1"].
           createInstance(Ci.nsIStringInputStream);
  ss.data = item;
  mpis.appendStream(ss);
  let postStream = Cc["@mozilla.org/network/mime-input-stream;1"].
                   createInstance(Ci.nsIMIMEInputStream);
  postStream.addHeader("Content-Type",
                       "multipart/form-data; boundary=" + boundary);
  postStream.setData(mpis);
  postStream.addContentLength = true;
  return postStream;
}

(You could use additional nsIMIMEInputStream instead of string-concatenating stuff together, but this would perform worse and has no real merit).

Which can then be used like e.g.:

let file = Services.dirsvc.get("Desk", Ci.nsIFile);
file.append("australis-xp hällow, wörld.png");

let postData = encodeFormData({
  "filename": "",
  "image_url": "",
  "image_content": "--somne value ---",
  "contents": file
}, "iso8859-1");

gBrowser.loadOneTab("http://www.example.org/", {
  inBackground: false,
  postData: postData
});
Friday, July 30, 2021
 
PeterTheLobster
answered 3 Months ago
70

gBrowser offers this functionality right out of the box.

var dataStream = Cc["@mozilla.org/io/string-input-stream;1"].createInstance(Ci.nsIStringInputStream);
dataStream.data = "foo=bar&alpha=beta"; // make sure the values are properly encoded with encodeURIComponent

var postStream = Cc["@mozilla.org/network/mime-input-stream;1"].createInstance(Ci.nsIMIMEInputStream);
postStream.addHeader("Content-Type", "application/x-www-form-urlencoded");
postStream.addContentLength = true;
postStream.setData(dataStream);

gBrowser.loadOneTab("http://www.example.com/", {inBackground: false, postData: postStream});
Thursday, October 21, 2021
 
JackTheKnife
answered 7 Days ago
Only authorized users can answer the question. Please sign in first, or register a free account.
Not the answer you're looking for? Browse other questions tagged :  
Share