图像数组元素在函数外部为零

时间:2017-08-17 14:20:52

标签: javascript

我想将图片转换为Uint8Array,以便在f5stego package的F5隐写术中使用它。

我尝试使用以下代码,但是当我在函数外部的控制台中打印imageArray时,它有0个值,而在其中有值表示真实图像数据。

var stegKey = [1, 2, 3, 4, 5, 6, 7, 8, 9];

var stegger = new f5stego(stegKey); // init stegger with key

var canvas = document.createElement('canvas');
ctx = canvas.getContext('2d'), base64 = 'cover.jpg';
canvas.width = 43, canvas.height = 34;
var image = new Image();
var imageArray = new Uint8Array(4624);
image.onload = (function (canvas, ctx) {
    return function () {
        ctx.drawImage(this, 0, 0);
        var imageData = ctx.getImageData(0, 0, 34, 34);
        // console.log(imageData.data);
        imageArray = imageData.data;
        console.log(imageArray);
    };
})(canvas, ctx);
image.src = base64;

console.log(imageArray);

// Data Array 
var message = "something secret ";
dataArray = new Uint8Array(message.length);
for (var i = 0, j = message.length; i < j; ++i) {
    dataArray[i] = message.charCodeAt(i);
}
console.log(dataArray);

//embed message into image
var secretImage = stegger.embed(imageArray, dataArray);
console.log(secretImage);

//extract message from image
var message = stegger.extract(secretImage);
console.log(message);

1 个答案:

答案 0 :(得分:1)

您正在将图片转换为Uint8Array像素。但是f5stego.js lib需要实际的JPEG文件字节,而不是像素。

如果使用base64编码的JPEG文件,则需要一些库将此字符串转换为Uint8Array。例如,您可以使用this code

如果你使用我链接到的base64 lib,你的代码应该是这样的:

var stegKey = [1, 2, 3, 4, 5, 6, 7, 8, 9];

var stegger = new f5stego(stegKey); // init stegger with key

// just base64 encoded file without data URL scheme
var base64 = '/9j/4AA............6D/2Q==',
    imageArray;

// convert Base64 encoded file to Uint8Array
imageArray = b64.dec(base64)

console.log(imageArray);

// Data Array
var message = "something secret ";
dataArray = new Uint8Array(message.length);
for (var i = 0, j = message.length; i < j; ++i) {
    dataArray[i] = message.charCodeAt(i);
}
console.log(dataArray);

//embed message into image
var secretImage = stegger.embed(imageArray, dataArray);
console.log(secretImage);

//extract message from image
var message = stegger.extract(secretImage);
console.log(message);

如果您想使用canvas修改图片,然后将其与f5stego.js一起使用,则需要使用toDataURL函数而不是getImageData。在这里,您再次需要处理Base64编码。在这种情况下,您的代码应该是这样的:

var stegKey = [1, 2, 3, 4, 5, 6, 7, 8, 9],
    stegger = new f5stego(stegKey); // init stegger with key

// Data Array
var message = "something secret ",
    dataArray = new Uint8Array(message.length);
for (var i = 0, j = message.length; i < j; ++i) {
    dataArray[i] = message.charCodeAt(i);
}
console.log(dataArray);

var canvas = document.createElement('canvas'),
    ctx = canvas.getContext('2d'),
    // now we use data URL scheme instead of plain base64 string
    base64 = 'data:image/jpeg;base64,/9j/4AA............6D/2Q==',
    image = new Image(),
    imageArray;

canvas.width = 43;
canvas.height = 34;

image.onload = (function (canvas, ctx) {
    return function () {
        ctx.drawImage(this, 0, 0);
        var imageData = canvas.toDataURL('image/jpeg', 1.0);

        // imageData is also in data URL scheme. We need to keep base64 part only
        imageData = imageData.split(',')[1];

        // convert Base64 encoded file to Uint8Array
        imageArray = b64.dec(imageData);

        console.log(imageArray);

        //embed message into image
        var secretImage = stegger.embed(imageArray, dataArray);
        console.log(secretImage);

        //extract message from image
        var message = stegger.extract(secretImage);
        console.log(message);
    };
})(canvas, ctx);

image.src = base64

另请注意f5算法的容量是原始文件大小的10%。这意味着如果你想要至少10KB的jpeg文件,你需要嵌入1KB的数据。

另一个提示:您使用charCodeAt将字符串转换为Uint8Array。这仅适用于ASCII字符,并且使用UTF-8符号失败。