canvas.mozFetchAsStream上的CreateIconFromResourceEx,如何提供流?

时间:2014-06-12 21:03:16

标签: winapi canvas firefox-addon icons jsctypes

我的目标是在画布上绘制.icoHICON。以下是Windows的片段。它的作用是让你提取文件。您选择一个图像,然后将画布添加到当前选项卡中的文档(位于底部),然后在cavas上绘制32px徽标,然后将其覆盖在浏览的图像上。现在我尝试使用CreateIconFromResourceEx jsctypes的winapi canvas.mozFetchAsStream,但我无法弄明白。

我被困在这一行:alert(streamData)

对于我PBYTE中的CreateIconFromResourceEx,将其设置为ctypes.unsigned_char.ptr是否正确? (因为我知道的字节只是ctypes.unsigned_char对吗?)

Components.utils.import('resource://gre/modules/ctypes.jsm');

var user32 = ctypes.open('user32.dll');


/* http://msdn.microsoft.com/en-us/library/windows/desktop/ms648061%28v=vs.85%29.aspx
* HICON WINAPI CreateIconFromResourceEx(
* __in_  PBYTE pbIconBits,
* __in_  DWORD cbIconBits,
* __in_  BOOL fIcon,
* __in_  DWORD dwVersion,
* __in_  int cxDesired,
* __in_  int cyDesired,
* __in_  UINT uFlags
* );
*/
var CreateIconFromResourceEx = user32.declare('CreateIconFromResourceEx', ctypes.winapi_abi, ctypes.voidptr_t,
    ctypes.unsigned_char.ptr, /* PBYTE pbIconBits */
    ctypes.unsigned_long, /* DWORD cbIconBits */
    ctypes.bool, /* BOOL fIcon */
    ctypes.unsigned_long, /* DWORD dwVersion */
    ctypes.int, /* int cxDesired */
    ctypes.int, /* int cyDesired */
    ctypes.unsigned_int /* UINT uFlags */
);

/////////////// running stuff below. above was just defining stuff
var me = Services.wm.getMostRecentWindow(null);

var canvas = document.createElementNS('http://www.w3.org/1999/xhtml', 'canvas');
var ctx = canvas.getContext('2d');
gBrowser.contentDocument.documentElement.appendChild(canvas);

var fp = Cc['@mozilla.org/filepicker;1'].createInstance(Ci.nsIFilePicker);
fp.init(window, 'Select Badge Image', Ci.nsIFilePicker.modeOpen);
fp.appendFilters(Ci.nsIFilePicker.filterAll | Ci.nsIFilePicker.filterText);

var rv = fp.show();
if (rv == Ci.nsIFilePicker.returnOK || rv == Ci.nsIFilePicker.returnReplace) {
  var file = fp.file;
  // Get the path as string. Note that you usually won't 
  // need to work with the string paths.
  var path = fp.file.path;


    var oImage = new Image();
    oImage.src = 'chrome://branding/content/icon32.png'; //Services.io.newFileURI(file).spec;
    oImage.onload = function() {
        alert('loaded')
        canvas.width = this.width;
        canvas.height = this.height;
        ctx.clearRect(0, 0, this.width, this.height);
        ctx.drawImage(this, 0, 0);

        var oImage = new Image();
        oImage.src = Services.io.newFileURI(file).spec;
        oImage.onload = function() {
            alert('loaded')
            ctx.drawImage(this, canvas.width-this.width, canvas.height-this.width);
            //mozFetchAsStream stuff: https://github.com/mozilla/build-partner-repacks/blob/885947b726c5d6e131af4e4aae621d51109bded4/partners/yandex-drp/distribution/extensions/vb%40yandex.ru/cbapp/parts/screenshotsGrabber.js#L295
            var asyncStreamCallback = {
                    onInputStreamReady: function (streamData) {
                        alert(streamData)
                    },
                    QueryInterface: XPCOMUtils.generateQI([
                        Ci.nsISupports,
                        Ci.nsIInputStreamCallback
                    ])
                };
            canvas.mozFetchAsStream(asyncStreamCallback, 'image/vnd.microsoft.icon')
            //now do canvas.mozGetAFile(blob) then reconstruct icon
        }
    }
}

////////////////

user32.close();

1 个答案:

答案 0 :(得分:1)

我不知道你的代码有什么问题。但是,由于你的目标是将画布内容转换为ICO,所以这是另一种方式(我敢说更为直截了当)。

// assuming ctx holds your drawings
let imgdata = ctx.getImageData(0,0,32,32); // this is a 32x32 icon, right?
let icoencoder = Cc["@mozilla.org/image/encoder;2?type=image/vnd.microsoft.icon"].createInstance(Ci.imgIEncoder);
icoencoder.initFromData(imgdata.data, imgdata.data.length, 32, 32, 32*4, Ci.imgIEncoder.INPUT_FORMAT_RGBA, "");
icoencoder.QueryInterface(Ci.nsIInputStream);

var icofile = new FileUtils.File("/path/to/canvas.ico");
var output = FileUtils.openSafeFileOutputStream(icofile);
NetUtil.asyncCopy(icoencoder, output, youroptionalcallback);

结果是一个正确的canvas.ico文件,您可以将其传递给windows api函数。