Get string from lsb of pixels of a PNG image

0

I've written a code that modify the least significant bit of every pixel of a PNG image and then save the image on external memory. Now, when I open the PNG image, I don't know how to do the reverse operation, that means I don't know how to get the string from that bits. Is there someone that can explain me it? Thanks.

This is the code that inserts the string in the least significant beats.

protected void onActivityResult(int requestCode, int resultCode, Intent data)
{
    super.onActivityResult(requestCode, resultCode, data);
    switch (requestCode)
    {
        case FILE_SELECT_CODE:
            if(resultCode==RESULT_OK)
            {
                Uri uri2 = data.getData();
                String[] proj = {MediaStore.Images.Media.DATA};
                CursorLoader cursorLoader = new CursorLoader(this,uri2,proj,null,null,null);
                Cursor cursor = cursorLoader.loadInBackground();
                int column_index=cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
                cursor.moveToFirst();
                String uri = cursor.getString(column_index);
                Bitmap img = BitmapFactory.decodeFile(uri);
                int height = img.getHeight();
                int width = img.getWidth();
                int[] pixel = new int[height * width];
                img.getPixels(pixel, 0, width, 1, 1, width - 1, height - 1);
                String key = "prova";
                byte[] b = key.getBytes();
                int count = 0;
                for (byte current_byte : b) {
                    for (int j = 7; j >= 0; j--) {
                        int lsb = (current_byte >> j) & 1;
                        pixel[count] = (pixel[count] & 0xfffffffe) + lsb;
                        count++;
                    }
                }
                Bitmap newImg = Bitmap.createBitmap(pixel,0,width, width-1,height-1, Bitmap.Config.ARGB_8888);
                ImageView imageView = new ImageView(this);
                imageView.setImageBitmap(newImg);
                setContentView(imageView);
                String filename = "myimage.png";
                File file2 = new File(getExternalFilesDir(null), filename);
                try
                {
                    FileOutputStream fileOutputStream = new FileOutputStream(file2);
                    newImg.compress(Bitmap.CompressFormat.PNG,100,fileOutputStream);
                    fileOutputStream.flush();
                    fileOutputStream.close();
                }
                catch (Exception e1)
                {
                    e1.printStackTrace();
                }
            }
            break;
    }
}

The following is the start of the code to read the string from that bits.

public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    final Intent intent = getIntent();
    Uri uri2 = intent.getData();
    String[] proj = {MediaStore.Images.Media.DATA};
    CursorLoader cursorLoader = new CursorLoader(this,uri2,proj,null,null,null);
    Cursor cursor = cursorLoader.loadInBackground();
    int column_index=cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
    cursor.moveToFirst();
    String uri = cursor.getString(column_index);
    Bitmap img = BitmapFactory.decodeFile(uri);
    int height = img.getHeight();
    int width = img.getWidth();
    int[] pixel = new int[height * width];
    img.getPixels(pixel, 0, width, 1, 1, width - 1, height - 1);

At the end of this part, in which i've took the array of pixels from image, I've to use this to get the string from the least significant beats.

PS: I cannot use BufferedImage.

java
android
image
steganography
asked on Stack Overflow May 15, 2015 by Paolo Guizzardi • edited May 15, 2015 by Paolo Guizzardi

1 Answer

0

Like this?

int[] pixel;
byte[] b = new byte[5 * 2]; // Default Java string encoding uses 2 bytes per symbol
// Read .png, fill pixel array etc
// Also you might wish to save string length to the pixel array first

for (int count = 0; count < pixel.length / 8 && count < b.length; count++) {
    int current_byte = 0;
    for (int j = 7; j >= 0; j--) {
        int lsb = (pixel[count * 8 + j] & 1) << j;
        current_byte += lsb;
    }
    b[count] = current_byte;
}
String key = new String(b, java.nio.charset.Charset.defaultCharset ()); // You might want to consider UTF-8
answered on Stack Overflow May 15, 2015 by pelya

User contributions licensed under CC BY-SA 3.0