我的目标是在画布上绘制.ico
或HICON
。以下是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();
答案 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函数。