0

So on WinXP I have been having a hard time converting a PNG file to an ICO with canvas. I found this method encodeImage. I don't know if it works but it looks promising but I can't figure out how to feed the image I drew on a canvas into imgITools.decodeData.

What should I use for aImageStream and/or aMimeType?

imgTools.decodeImageData(aImageStream, aMimeType, imgContainer);

This is more of my code:

 img['asdf'].file = new FileUtils.File(myPathHere);

let iconStream;
try {
  let imgTools = Cc["@mozilla.org/image/tools;1"]
                    .createInstance(Ci.imgITools);
  let imgContainer = { value: null };

  imgTools.decodeImageData(aImageStream, aMimeType, imgContainer);
  iconStream = imgTools.encodeImage(imgContainer.value,
                                    "image/vnd.microsoft.icon",
                                    "format=bmp;bpp=32");
} catch (e) {
  alert('failure converting icon ' + e)
  throw("processIcon - Failure converting icon (" + e + ")");
}

let outputStream = FileUtils.openSafeFileOutputStream(img['asdf'].file);
NetUtil.asyncCopy(iconStream, outStream, netutilCallback);
nmaier
  • 32,336
  • 5
  • 63
  • 78
Noitidart
  • 35,443
  • 37
  • 154
  • 323

1 Answers1

1

Since you're having a canvas already(?), it would be probably easier to use either on of the following canvas methods:

  • toDataURI/toDataURIHD
  • toBlob/toBlobHD
  • mozFetchAsStream

There is also the undocumented -moz-parse-options:, e.g -moz-parse-options:format=bmp;bpp=32. (ref-tests seem to depend on it, so it isn't going away anytime soon I'd think).

So, here is an example for loading stuff into an ArrayBuffer.

(canvas.toBlobHD || canvas.toBlob).call(canvas, function (b) {
    var r = new FileReader();
    r.onloadend = function () {
        // r.result contains the ArrayBuffer.
    };
    r.readAsArrayBuffer(b);
}, "image/vnd.microsoft.icon", "-moz-parse-options:format=bmp;bpp=32");

Here is a more complete example fiddle creating a 256x256 BMP icon.

Since you likely want to feed that data into js-ctypes, having an ArrayBuffer is great because you can create pointers from it directly, or write it to a file using OS.File.

Community
  • 1
  • 1
nmaier
  • 32,336
  • 5
  • 63
  • 78
  • Woww async way thank man!! The `arraybuffer` will be so useful thx to your other post for jsctypes!! the `toBlob` gives me crap quality, im not able to use `HD` no clue why :( Is this `-moz-parse-options:format=bmp;bpp=32` trick possible with `mozFetchAsStream`? – Noitidart Jun 17 '14 at 02:19
  • I don't think so. Not that it would matter as it uses the same implementation as `toBlob`, so the quality is as good as it gets. Sounds like the code you use to draw to the canvas in the first place might be to blame for quality issues. Or you're generating non-standard icons (e.g. not 16x16, 32x32, 256x256 (PNG) and so on) – nmaier Jun 17 '14 at 02:25
  • Hey man Im having a tricky time using `OS.File` to write it to file could you give me a quick pointer. What i did was: `OS.File.writeAtomic(writePath, r.result, {tmpPath:writePath + '.tmp'});` and the error it gave me was: `TypeError: Value [object ArrayBuffer] cannot be converted to a pointer` – Noitidart Jun 17 '14 at 02:52
  • 1
    Wrap it in a `Uint8Array`. Something like `OS.File.writeAtomic(writePath, new Uint8Array(r.result), {tmpPath:writePath + '.tmp'});` should work. – nmaier Jun 17 '14 at 02:54
  • Suuuuuuuuuuuuuuuuuuuuuuuuuper finalllly i got this working in WinXP!!! And async!! Thank you thank youuuuuuuuuu!!!!!! Ive been struggling for 2 weeks haha – Noitidart Jun 17 '14 at 03:02
  • Hey man Im having a hard time getting quality right, im definitely making 16x16 and 32x32 icons. This is image of poor quality, the firefox icon with youtube badge on right side you can see on upper border theres black roughness. http://img.photobucket.com/albums/v135/noitidart/quality20issue_zps13888243.png This is my code: [GitHubGist :: blah L#167](https://gist.github.com/Noitidart/0f55b7ca0f89fe2610fa#file-_ff-addon-snippet-browseforbadgethencreatesaveanapply-js-L167) Can you please give me a pointer :) – Noitidart Jun 17 '14 at 03:14
  • o btw i didnt screenshot the canvas, but the canvas drawing is perfect, none of that black crap at edge haha' – Noitidart Jun 17 '14 at 03:21
  • Can you post a new question about that? The comments section isn't really suited. If you do, can you extract the interesting bits (canvas-drawing) and include it as a js-fiddle? – nmaier Jun 17 '14 at 03:24
  • hey question man is the `32` in `format=bmp;bpp=32` only for if my icon size is 32x32px? if i do other sizes should i change the 32? like if i want 16 should i change it to `format=bmp;bpp=16`? – Noitidart Jun 17 '14 at 21:04
  • 1
    "bpp" means "bit per pixel", and you have 4 channels (r, g, b, alpha), each 8-bit so 32-bit. It is unrelated to the icon size (and/or bit-ness of the OS). 24 would be (usually) just RGB (8-bit per channel). – nmaier Jun 17 '14 at 21:21
  • I missed that comment and just learned it the hard way, all my non-32 image were not being created properly. – Noitidart Jun 21 '14 at 04:57