2

What My code does . is take a snapshot of the map convert it to gray (opencv) and then make it to byte array. Now what I dont know how to start doing is making this Bytearray to a 2D Array,

here is a block of the code.

                    Date now = new Date();
                    android.text.format.DateFormat.format("yyyy-MM-dd_hh:mm:ss",now);
                    try {
                        StrictMode.ThreadPolicy old = StrictMode.getThreadPolicy();
                        StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder(old)
                                .permitDiskWrites()
                                .build());
                        String mPath = Environment.getExternalStorageDirectory().toString() + "/" + now + ".jpg";
                        File imageFile = new File(mPath);
                        FileOutputStream out = new FileOutputStream(imageFile);
                        bitmap.compress(Bitmap.CompressFormat.PNG,90,out);
                        Log.d("Image:","Saved Snashot. Starting covertion");
                        //show snapshot in imageview
                        ImageView imgview = (ImageView) findViewById(R.id.imageView);
                        Bitmap smyBitmap = BitmapFactory.decodeFile(mPath);
                        Bitmap myBitmap = BitmapFactory.decodeFile(mPath);
                        imgview.setImageBitmap(smyBitmap);
                        Mat mat = new Mat(myBitmap.getHeight(),myBitmap.getWidth(),CvType.CV_8UC3);
                        Mat mat1 = new Mat(myBitmap.getHeight(),myBitmap.getWidth(),CvType.CV_8UC1);
                        Imgproc.cvtColor(mat,mat1,Imgproc.COLOR_BGR2GRAY);
                        ImageView imgview2 = (ImageView) findViewById(R.id.imageView2);
                            Mat tmp = new Mat (myBitmap.getWidth(), myBitmap.getHeight(), CvType.CV_8UC1);
                            Utils.bitmapToMat(myBitmap, tmp);
                            Imgproc.cvtColor(tmp, tmp, Imgproc.COLOR_RGB2GRAY);
                            Utils.matToBitmap(tmp, myBitmap);
                          //  Utils.matToBitmap(mat1,img);
                        String mPathgray = Environment.getExternalStorageDirectory().toString() + "/" + now + "gray.jpg";
                        File imageFilegray = new File(mPathgray);
                        FileOutputStream gout = new FileOutputStream(imageFilegray);

                        bitmap.compress(Bitmap.CompressFormat.PNG,90,gout);

                        byte[] byteArray = bttobyte(myBitmap);
                        Log.d("location"," " + mPathgray);
                            imgview2.setImageBitmap(myBitmap);

                        Log.d("Activity", "Byte array: "+ Arrays.toString(byteArray));

                    }

                    catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            };
            mMap.snapshot(callback);
            Log.d("test","test2");
        }
    });

}

public byte[] bttobyte(Bitmap bitmap) {
    ByteArrayOutputStream stream = new ByteArrayOutputStream();
    bitmap.compress(Bitmap.CompressFormat.JPEG, 70, stream);
    return stream.toByteArray();
}
Demeteor
  • 1,193
  • 2
  • 17
  • 33
  • Did you delete my comment from yesterday or did the system trick me into thinking it went through??? Anyways there all I said was : Your (uncompressed) bitmap is already an array of [X] [Y] values (each pixel colour has an x/y position) so if you want to fill array just sample **directly** from bitmap. If you add compression like JPEG (your `bitmap.compress(Bitmap.CompressFormat.JPEG, 70, stream);`) then how does that figure into your array? What do you expect your 2D array to contain from one long strip of JPEG bytes? JPEG begins with `FF D8 FF E0` so what goes where in your `img = {[],[])`? – VC.One Mar 28 '17 at 20:52
  • Read the above and clarify your expectations of `img = {[],[])` content after you make jpeg bytes. Maybe explain why specifically "into a 2D array" then easier to advise you. _EG:_ Are you trying to make a [**hex editor**](https://www.google.co.uk/search?q=hex+editor&source=lnms&tbm=isch&sa=X&ved=0ahUKEwiXyIHVi_rSAhUrK8AKHTjEB0UQ_AUICCgB&biw=1600&bih=731) style grid view of the JPEG bytes? – VC.One Mar 28 '17 at 21:00
  • I am trying to make a 2D array map of the picture so I can perform seartch algorithm. BFS . to pathplan for an autonomous boat and also no idid not delete your comment. I dont have that kind of access – Demeteor Mar 29 '17 at 11:44
  • So why are you compressing the image? – Michael Mar 31 '17 at 08:37

2 Answers2

2

The problem you are trying to solve is actually extracting image data from JPEG encoding in the byte array. It is not as simple as being stored pixel by pixel in a grid of width and height equal to your image size, as you seem to be implying. That is a consequence of using this

bitmap.compress(Bitmap.CompressFormat.JPEG, 70, stream);

For example that byte data actually might encode JFIF format:

  • 0xffd8 - SOI - exactly 1 - start of image e.g. 0xffe0 - zero or more - e.g. APP0 for JFIF - [some sort of header, either JFIF or EXIF].
  • 0xffdb - DQT - one or more - define quantisation tables. These are the main source of quality in the image.
  • 0xffcn - SOFn - exactly one - start of frame. SOF0 indicates a baseline DCT JPEG
  • 0xffc4 - DHT - one or more - define Huffman tables. These are used in the final lossless encoding steps.
  • 0xffda - SOS - exactly one (for baseline, more than one intermixed with more DHTs if progressive) - start of stream. This is where the actual data starts.
  • 0xffd9 - EOI - exactly one - end of image.

Essentially once you have transformed your bitmap, you need a JPEG decoder to parse this data.

I think what you want is to be working with the original bitmap. For example there are APIs to extract pixel data. That is what you need if I understand what it is you want to do correctly.

Bitmap.getPixels(int[] pixels, int offset, int stride, int x, int y, int width, int height)

The array pixels[] is filled with data. You can then parse the array if you want to store it in a w by h 2D array by iterating copying the data. Something like:

int offset = 0;
int pixels2d[w][h]= new int[w][h];
for (int[] row : pixels2d) {
    System.arraycopy(pixels, offset, row, 0, row.length);
    offset += row.length;
}
dr_g
  • 1,179
  • 7
  • 10
1

You just create a new array with 2 dimensions

byte[][] picture = new byte[myBitmap.getWidth()][,myBitmap.getHeight()]

which you can access via

byte myByte = picture[x][y]

after this you iterate your original bytarray by line followed by row

Michael
  • 276
  • 2
  • 10
  • Hey man, I don't find how this can work. Lets say I want to print the entire thing out just to see if I get the correct results how do I do it ? I mean I dont get how to use what you gave me, Mind to edit your answer and elaborate a bit ? – Demeteor Mar 28 '17 at 07:48
  • Instead of writing long answers, which already exists, I will you point to this: http://stackoverflow.com/questions/6524196/java-get-pixel-array-from-image] – Michael Mar 28 '17 at 09:13
  • Hey, I am gonna take my time reading and testing those, ill post back here if I need anything else, Ill go ahead and reward you with the 50rep since you are the only one who answered and managed to remove the block I had, Now I have a more general idea thanks Micheal , ill let you know if I find any issues (in 3hours when it will allow me) – Demeteor Mar 28 '17 at 09:37