Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/339.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 用字节数组修改后如何将图像字节数组转换成位图_Java_Android_Arrays_Bitmap_Steganography - Fatal编程技术网

Java 用字节数组修改后如何将图像字节数组转换成位图

Java 用字节数组修改后如何将图像字节数组转换成位图,java,android,arrays,bitmap,steganography,Java,Android,Arrays,Bitmap,Steganography,我正在尝试在Android中实现隐写术,我已经实现了一点一点地编码图像的代码 private Bitmap add_text(Bitmap image, String text) { //convert all items to byte arrays: image, message, message length byte img[] = get_byte_data(image); byte msg[] = text.getBytes(); byte len[

我正在尝试在Android中实现隐写术,我已经实现了一点一点地编码图像的代码

private Bitmap add_text(Bitmap image, String text)
{
    //convert all items to byte arrays: image, message, message length
    byte img[]  = get_byte_data(image);
    byte msg[] = text.getBytes();
    byte len[]   = bit_conversion(msg.length);
    displaybit(img, "Start");

    try
    {
        encode_text(img, len,  0); //0 first positiong
        encode_text(img, msg, 32); //4 bytes of space for length: 4bytes*8bit = 32 bits

        return BitmapFactory.decodeByteArray(img, 0, img.length);
    }
    catch(Exception e)
    {
        e.printStackTrace();
    }
    return image;
}

private byte[] get_byte_data(Bitmap image)
{
    ByteArrayOutputStream stream = new ByteArrayOutputStream();
    image.compress(Bitmap.CompressFormat.JPEG, 100, stream);

    return stream.toByteArray();
}

private byte[] bit_conversion(int i)
{
    //originally integers (ints) cast into bytes
    //byte byte7 = (byte)((i & 0xFF00000000000000L) >>> 56);
    //byte byte6 = (byte)((i & 0x00FF000000000000L) >>> 48);
    //byte byte5 = (byte)((i & 0x0000FF0000000000L) >>> 40);
    //byte byte4 = (byte)((i & 0x000000FF00000000L) >>> 32);

    //only using 4 bytes
    byte byte3 = (byte)((i & 0xFF000000) >>> 24); //0
    byte byte2 = (byte)((i & 0x00FF0000) >>> 16); //0
    byte byte1 = (byte)((i & 0x0000FF00) >>> 8 ); //0
    byte byte0 = (byte)((i & 0x000000FF)       );
    //{0,0,0,byte0} is equivalent, since all shifts >=8 will be 0
    return(new byte[]{byte3,byte2,byte1,byte0});
}

private byte[] encode_text(byte[] image, byte[] addition, int offset)
{
    //check that the data + offset will fit in the image
    if(addition.length + offset > image.length)
    {
        throw new IllegalArgumentException("File not long enough!");
    }
    //loop through each addition byte
    for(int i=0; i<addition.length; ++i)
    {
        //loop through the 8 bits of each byte
        int add = addition[i]; //0
        for(int bit=7; bit>=0; --bit, ++offset) //ensure the new offset value carries on through both loops
        {
            //assign an integer to b, shifted by bit spaces AND 1
            //a single bit of the current byte
            int b = (add >>> bit) & 1;
            //assign the bit by taking: [(previous byte value) AND 0xfe] OR bit to add
            //changes the last bit of the byte in the image to be the bit of addition
            image[offset] = (byte)((image[offset] & 0xFE) | b );
        }
    }
    return image;
}

因此,请有人帮我找出为什么字节数组在android中无效。

您从JPEG数据的
字节[]
开始。然后修改该数据,半随机地更改位,而不考虑JPEG数据格式。然后尝试解码修改后的
字节[]
。毫不奇怪,
BitmapFactory
无法对其进行解码,因为它不再是有效的图像格式

我的最佳猜测是,您认为
字节[]
是ARGB格式的原始像素


如果是这种情况,那么使用
Bitmap
上的
getPixel()
setPixel()
等方法修改像素,并跳过位图的编码和解码步骤。

我终于能够找到答案,正如上面的注释所述,解决方案是逐像素解决问题。所以我取了一个像素,一点一点地把数据放在它的rgb值中。这就是代码:

private Bitmap add_text(Bitmap image, String text, File tempFile) {
    //convert all items to byte arrays: image, message, message length
    byte msg[] = text.getBytes();
    byte len[] = bit_conversion(msg.length);

    try {

        return encodeTextRGB(image, len, msg, tempFile);

    } catch (Exception e) {
        e.printStackTrace();
    }
    return image;
}

private byte[] bit_conversion(int i) {
    //originally integers (ints) cast into bytes
    //byte byte7 = (byte)((i & 0xFF00000000000000L) >>> 56);
    //byte byte6 = (byte)((i & 0x00FF000000000000L) >>> 48);
    //byte byte5 = (byte)((i & 0x0000FF0000000000L) >>> 40);
    //byte byte4 = (byte)((i & 0x000000FF00000000L) >>> 32);

    //only using 4 bytes
    byte byte3 = (byte) ((i & 0xFF000000) >>> 24); //0
    byte byte2 = (byte) ((i & 0x00FF0000) >>> 16); //0
    byte byte1 = (byte) ((i & 0x0000FF00) >>> 8); //0
    byte byte0 = (byte) ((i & 0x000000FF));
    //{0,0,0,byte0} is equivalent, since all shifts >=8 will be 0
    return (new byte[]{byte3, byte2, byte1, byte0});
}

public Bitmap encodeTextRGB(Bitmap buffer, byte[] len, byte[] data, File tempFile) {

    pixelRow = 0;
    pixelCol = 0;

    byte[] overhead = len;

    int bitCount = 0;
    int iteration = 0;

    while (iteration++ < 2) {
        for (int i = 0; i < overhead.length; i++) {
            byte currentByte = overhead[i];
            System.out.println("add: " + currentByte);
            for (int j = 7; j >= 0; j--) {
                int bit = (currentByte & (0x1 << j)) >> j;
                bit = bit & 0x1;
                System.out.println("Bit: " + bit);
                if (bitCount % 3 == 0) {
                    int red;
                    if (bit == 0) {
                        red = Color.red(buffer.getPixel(pixelCol, pixelRow)) & 0xFE;
                    } else {
                        red = Color.red(buffer.getPixel(pixelCol, pixelRow)) | 0x1;
                    }
                    buffer.setPixel(pixelCol, pixelRow, Color.argb(
                            Color.alpha(buffer.getPixel(pixelCol, pixelRow)), red,
                            Color.green(buffer.getPixel(pixelCol, pixelRow)),
                            Color.blue(buffer.getPixel(pixelCol, pixelRow))));
                } else if (bitCount % 3 == 1) {
                    int blue;
                    if (bit == 0) {
                        blue = Color.blue(buffer.getPixel(pixelCol, pixelRow)) & 0xFE;
                    } else {
                        blue = Color.blue(buffer.getPixel(pixelCol, pixelRow)) | 0x1;
                    }
                    buffer.setPixel(pixelCol, pixelRow, Color.argb(
                            Color.alpha(buffer.getPixel(pixelCol, pixelRow)),
                            Color.red(buffer.getPixel(pixelCol, pixelRow)),
                            Color.green(buffer.getPixel(pixelCol, pixelRow)), blue));
                } else {
                    int green;
                    if (bit == 0) {
                        green = Color.green(buffer.getPixel(pixelCol, pixelRow)) & 0xFE;
                    } else {
                        green = Color.green(buffer.getPixel(pixelCol, pixelRow)) | 0x1;
                    }
                    buffer.setPixel(pixelCol, pixelRow, Color.argb(
                            Color.alpha(buffer.getPixel(pixelCol, pixelRow)),
                            Color.red(buffer.getPixel(pixelCol, pixelRow)), green,
                            Color.blue(buffer.getPixel(pixelCol, pixelRow))));
                    incrementPixel(buffer.getWidth());
                }
                bitCount++;
            }
        }

        overhead = data;
    }
    FileOutputStream out = null;
    try {
        out = new FileOutputStream(tempFile);
        buffer.compress(Bitmap.CompressFormat.PNG, 100, out);
        out.flush();
        out.close();
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }

    incrementPixel(buffer.getWidth());
    return buffer;
}
专用位图添加\文本(位图图像、字符串文本、文件tempFile){
//将所有项目转换为字节数组:图像、消息、消息长度
字节msg[]=text.getBytes();
字节len[]=位转换(消息长度);
试一试{
返回encodeTextRGB(图像、len、msg、tempFile);
}捕获(例外e){
e、 printStackTrace();
}
返回图像;
}
专用字节[]位_转换(int i){
//最初,整数(INT)转换为字节
//字节字节7=(字节)((i&0xFF00000000000000L)>>>56);
//字节字节6=(字节)((i&0x00FF000000000000L)>>>48);
//字节字节5=(字节)((i&0x0000FF0000000000L)>>>40);
//字节字节4=(字节)((i&0x000000FF00000000L)>>>32);
//仅使用4个字节
字节字节3=(字节)((i&0xFF000000)>>>24);//0
字节字节2=(字节)((i&0x00FF0000)>>>16);//0
字节字节1=(字节)((i&0x0000FF00)>>>8);//0
字节字节0=(字节)((i&0x000000FF));
//{0,0,0,byte0}是等价的,因为所有移位>=8都是0
返回(新字节[]{byte3,byte2,byte1,byte0});
}
公共位图encodeTextRGB(位图缓冲区,字节[]len,字节[]数据,文件tempFile){
pixelRow=0;
pixelCol=0;
字节[]开销=len;
int位计数=0;
int迭代=0;
while(迭代+++<2){
for(int i=0;i=0;j--){
int位=(当前字节&(0x1>j;
位=位&0x1;
System.out.println(“位:”+Bit);
如果(位计数%3==0){
红色;
如果(位==0){
红色=Color.red(buffer.getPixel(pixelCol,pixelRow))&0xFE;
}否则{
红色=Color.red(buffer.getPixel(pixelCol,pixelRow))| 0x1;
}
buffer.setPixel(pixelCol、pixelRow、Color.argb(
Color.alpha(buffer.getPixel(pixelCol,pixelRow)),红色,
Color.green(buffer.getPixel(pixelCol,pixelRow)),
Color.blue(buffer.getPixel(pixelCol,pixelRow));
}else if(位计数%3==1){
蓝色;
如果(位==0){
蓝色=Color.blue(buffer.getPixel(pixelCol,pixelRow))&0xFE;
}否则{
蓝色=Color.blue(buffer.getPixel(pixelCol,pixelRow))| 0x1;
}
buffer.setPixel(pixelCol、pixelRow、Color.argb(
Color.alpha(buffer.getPixel(pixelCol,pixelRow)),
Color.red(buffer.getPixel(pixelCol,pixelRow)),
绿色(buffer.getPixel(pixelCol,pixelRow)),蓝色);
}否则{
绿色;
如果(位==0){
绿色=Color.green(buffer.getPixel(pixelCol,pixelRow))&0xFE;
}否则{
绿色=Color.green(buffer.getPixel(pixelCol,pixelRow))| 0x1;
}
buffer.setPixel(pixelCol、pixelRow、Color.argb(
Color.alpha(buffer.getPixel(pixelCol,pixelRow)),
Color.red(buffer.getPixel(pixelCol,pixelRow)),green,
Color.blue(buffer.getPixel(pixelCol,pixelRow));
递增像素(buffer.getWidth());
}
位计数++;
}
}
开销=数据;
}
FileOutputStream out=null;
试一试{
out=新文件输出流(tempFile);
buffer.compress(Bitmap.CompressFormat.PNG,100,out);
out.flush();
out.close();
}catch(filenotfounde异常){
e、 printStackTrace();
}捕获(IOE异常){
e、 printStackTrace();
}
递增像素(buffer.getWidth());
返回缓冲区;
}

如果不知道
get\u byte\u data()
做了什么,
bit\u conversion()
做了什么,或者
encode\u text()
做了什么,就不可能帮到你。请记住,传递给
decodebytarray()
字节[]
需要采用可识别和支持的图像格式(例如PNG、JPEG、WebP)。好的,我会把代码放进去。事实上,我需要改变字节,所以有没有办法改变字节而不损坏它们。就像我上面提到的Java一样,同样的算法给了我正确的输出。@Satymarai:“我需要改变字节”--为什么?“那么有没有办法改变字节而不损坏它们呢?”--确保完成后得到一个有效的JPEG。我不知道你打算怎么做
private Bitmap add_text(Bitmap image, String text, File tempFile) {
    //convert all items to byte arrays: image, message, message length
    byte msg[] = text.getBytes();
    byte len[] = bit_conversion(msg.length);

    try {

        return encodeTextRGB(image, len, msg, tempFile);

    } catch (Exception e) {
        e.printStackTrace();
    }
    return image;
}

private byte[] bit_conversion(int i) {
    //originally integers (ints) cast into bytes
    //byte byte7 = (byte)((i & 0xFF00000000000000L) >>> 56);
    //byte byte6 = (byte)((i & 0x00FF000000000000L) >>> 48);
    //byte byte5 = (byte)((i & 0x0000FF0000000000L) >>> 40);
    //byte byte4 = (byte)((i & 0x000000FF00000000L) >>> 32);

    //only using 4 bytes
    byte byte3 = (byte) ((i & 0xFF000000) >>> 24); //0
    byte byte2 = (byte) ((i & 0x00FF0000) >>> 16); //0
    byte byte1 = (byte) ((i & 0x0000FF00) >>> 8); //0
    byte byte0 = (byte) ((i & 0x000000FF));
    //{0,0,0,byte0} is equivalent, since all shifts >=8 will be 0
    return (new byte[]{byte3, byte2, byte1, byte0});
}

public Bitmap encodeTextRGB(Bitmap buffer, byte[] len, byte[] data, File tempFile) {

    pixelRow = 0;
    pixelCol = 0;

    byte[] overhead = len;

    int bitCount = 0;
    int iteration = 0;

    while (iteration++ < 2) {
        for (int i = 0; i < overhead.length; i++) {
            byte currentByte = overhead[i];
            System.out.println("add: " + currentByte);
            for (int j = 7; j >= 0; j--) {
                int bit = (currentByte & (0x1 << j)) >> j;
                bit = bit & 0x1;
                System.out.println("Bit: " + bit);
                if (bitCount % 3 == 0) {
                    int red;
                    if (bit == 0) {
                        red = Color.red(buffer.getPixel(pixelCol, pixelRow)) & 0xFE;
                    } else {
                        red = Color.red(buffer.getPixel(pixelCol, pixelRow)) | 0x1;
                    }
                    buffer.setPixel(pixelCol, pixelRow, Color.argb(
                            Color.alpha(buffer.getPixel(pixelCol, pixelRow)), red,
                            Color.green(buffer.getPixel(pixelCol, pixelRow)),
                            Color.blue(buffer.getPixel(pixelCol, pixelRow))));
                } else if (bitCount % 3 == 1) {
                    int blue;
                    if (bit == 0) {
                        blue = Color.blue(buffer.getPixel(pixelCol, pixelRow)) & 0xFE;
                    } else {
                        blue = Color.blue(buffer.getPixel(pixelCol, pixelRow)) | 0x1;
                    }
                    buffer.setPixel(pixelCol, pixelRow, Color.argb(
                            Color.alpha(buffer.getPixel(pixelCol, pixelRow)),
                            Color.red(buffer.getPixel(pixelCol, pixelRow)),
                            Color.green(buffer.getPixel(pixelCol, pixelRow)), blue));
                } else {
                    int green;
                    if (bit == 0) {
                        green = Color.green(buffer.getPixel(pixelCol, pixelRow)) & 0xFE;
                    } else {
                        green = Color.green(buffer.getPixel(pixelCol, pixelRow)) | 0x1;
                    }
                    buffer.setPixel(pixelCol, pixelRow, Color.argb(
                            Color.alpha(buffer.getPixel(pixelCol, pixelRow)),
                            Color.red(buffer.getPixel(pixelCol, pixelRow)), green,
                            Color.blue(buffer.getPixel(pixelCol, pixelRow))));
                    incrementPixel(buffer.getWidth());
                }
                bitCount++;
            }
        }

        overhead = data;
    }
    FileOutputStream out = null;
    try {
        out = new FileOutputStream(tempFile);
        buffer.compress(Bitmap.CompressFormat.PNG, 100, out);
        out.flush();
        out.close();
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }

    incrementPixel(buffer.getWidth());
    return buffer;
}