分割位图文件产生 y + height must be <= bitmap.height() 错误

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

我正在尝试用我做的这个方法分割位图:

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;
}

我正在处理的位图大小是240x4298。这是一个非常非常长的图像。我需要生成位图列表(来自原始来源的分段位图)。当 i 达到 2400 时,它会喷出一条错误消息:

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

我的逻辑是这样的: 1.) 我在 y 轴上从 0 像素到 400 像素开始 2.) 我从 y 轴 400 到 800 像素开始 等等……

当前迭代还没有达到 4298 并且它在抱怨(在 2400px)。想过为什么会这样吗?

谢谢!

正如我从您的代码中看到的那样,问题在于:

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

例如,您有 width = 1000, height = 3000,但 everyPixel = 2000。在循环的第二次迭代中,您将拥有 i = 2000 并且您将尝试通过获取 left = 0、top = 2000、width = 1000 和 height = i + everyPixel = 4000 的部分来从 comicbitmap 创建位图,但总体高度位图是 3000,所以你得到这个错误。

有关详细信息,请参阅 this and this

这是我的新方法:

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;
}

注意以下几行:

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

这实际上确保所有像素都被考虑在内。例如,在我的例子中,高度是 4298,我达到了 4000。由于我需要处理最后的 298,因此限制应该只是 298 而不是我的 everyPixel 值。

我的看法是方法 Bitmap.createBitmap(comicBitmap, 0, i, width, limit) 第三个参数 (y) 实际上添加到第五个参数(高度)。所以如果我想处理第 400-800 个像素,它应该是:

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

评估位图的最终高度时,第三个参数添加到第五个参数。

我发现这非常违反直觉。但我想这只是我。