nww04
nww04

Reputation: 1857

Splitting bitmap file produces y + height must be <= bitmap.height() error

I am trying to split bitmap with this method I made:

private List<Bitmap> splitBitmap(File file, int everyPixel)
{
    Bitmap comicBitmap = BitmapFactory.decodeFile(file.getAbsolutePath());
    List<Bitmap> segments = new ArrayList<Bitmap>();

    if(comicBitmap == null)
        return segments;

    int height = comicBitmap.getHeight();
    int width = comicBitmap.getWidth();
    int h = 0;

    for(int i = 0; i < height; i += everyPixel)
    {
        i = i >= height? height : i;

        Bitmap bitmap = Bitmap.createBitmap(comicBitmap, 0, i, width, i + everyPixel);
        segments.add(bitmap);
    }

    return segments;
}

The size of the bitmap I am processing is 240x4298. Its a very very long image. I need to generate a list of bitmaps (segmented bitmap from the original source). When the i hits 2400, it spews out an error saying:

Caused by: java.lang.IllegalArgumentException: y + height must be <= bitmap.height()

My logic here is something like: 1.) I start with 0 pixels to 400 pixels in y axis 2.) I start with 400 pixels to 800 pixels in y axis and so on and so forth...

The current iteration haven't reached 4298 yet and its complaining (at 2400px). Any thought why this so?

Thanks!

Upvotes: 2

Views: 2630

Answers (2)

nww04
nww04

Reputation: 1857

So here is my new method:

private List<Bitmap> splitBitmap(File file, int everyPixel)
{
    Bitmap comicBitmap = BitmapFactory.decodeFile(file.getAbsolutePath());
    List<Bitmap> segments = new ArrayList<>();

    if(comicBitmap == null)
        return segments;

    int height = comicBitmap.getHeight();
    int width = comicBitmap.getWidth();

    for(int i = 0; i < height; i += everyPixel)
    {
        i = i >= height? height : i;
        int limit = i + everyPixel >= height? height - i : everyPixel;

        Bitmap bitmap = Bitmap.createBitmap(comicBitmap, 0, i, width, limit);
        segments.add(bitmap);
    }

    return segments;
}

Notice the lines:

i = i >= height? height : i;
int limit = i + everyPixel >= height? height - i : everyPixel;

This actually make sure all pixels are accounted for. For example in my case the height is 4298 and I reached 4000. Since I need to process the last 298, the limit should be just 298 instead of my everyPixel value.

The way I see this is that the method Bitmap.createBitmap(comicBitmap, 0, i, width, limit) third param (y) actually adds to the 5th param (height). So if I want to process 400-800th pixel it should be:

Bitmap.createBitmap(comicBitmap, 0, 400, width, 400);

The third param adds to the 5th when evaluating the final height of the bitmap.

I find this very counter intuitive. But its just me, I guess.

Upvotes: 1

Mikhail Spitsin
Mikhail Spitsin

Reputation: 2608

As I see from you code, problem is in line:

Bitmap bitmap = Bitmap.createBitmap(comicBitmap, 0, i, width, i + everyPixel);

For example, you have width = 1000, height = 3000, but everyPixel = 2000. In second iteration of cycle you will have i = 2000 and you will try to create bitmap from comicbitmap by getting part with left = 0, top = 2000, width = 1000 and height = i + everyPixel = 4000, but height of overall bitmap is 3000 so you get this error.

See this and this for more info.

Upvotes: 1

Related Questions