如何高效地将Bitmap对象读入二维整数数组?

7

我需要在我的Android应用程序中将整个位图对象读入一个二维整数数组中。

目前,我正在逐个像这样阅读每个像素:

for (int y = 0; y < coverImageHeight; y++)
{
    for (int x = 0; x < coverImageWidth; x++)
    {
        coverImageIntArray[x][y] = coverImageBitmap.getPixel(x, y);
    }
}

然而,在大型图像上执行此操作需要很长时间(约15秒)。

有没有一种方法可以一次性完成所有操作以提高效率?


位图图像有多大? - markspace
@markspace - 感谢您的快速回复!需要15秒才能加载的图像大小为1920x1200像素,所以我无法想象在4000x3000像素的图像上需要多长时间。 - You'reAGitForNotUsingGit
2
我不是Android程序员,但我看到一个copyPixelsToBuffer方法,可能更适合于速度和图像处理。 - markspace
你可以使用OpenCV库,它提供了各种图像处理方法,比如转换为数组。 - Rajeev Singh
https://dev59.com/Tmkw5IYBdhLWcg3wBl-A - jscs
显示剩余2条评论
3个回答

7

我对Android开发不太熟悉,但通常情况下,对于图像对象,您可以获取一些底层缓冲区的引用或副本。这个缓冲区通常是1D的,但您应该能够相对容易地转换它。在您的情况下,要获取像素,有一个getPixels函数看起来很完美。

int[] coverImageIntArray1D = new int[coverImageWidth * coverImageHeight]
coverImageBitmap.getPixels(coverImageIntArray1D, 0, coverImageWidth,
    0, 0, coverImageWidth, coverImageHeight)
// coverImageIntArray1D should now contain the entire image's pixels

请注意,您可以使用2D索引来索引此类型的1D数组:

int pixel = coverImageIntArray1D[x + y*coverImageWidth]

这将为您提供在 [x][y] 像素处的像素。因此,您仍然可以以二维方式使用它,而无需执行低效的转换。

嗯...所以通过使用getPixels(),导入到1D数组中非常快(不到一秒),但是我在将1D数组转换为2D数组时遇到了一些严重的问题。我尝试了您提供的链接中的两个答案,但它们都将图像旋转了90度,并且其中一个还引入了垂直伪影。如果您能帮助我找到一个真正有效的1D--> 2D转换方法,我将很高兴接受并点赞您的答案 :) - You'reAGitForNotUsingGit
现在我想起来了,将图像数据转换为你想要的格式实际上很麻烦(而且非常低效),因为图像数据是按行存储的,但[x][y]数组按列存储数据 - 这就是为什么你发现事情被旋转了。重新考虑你的数据结构可能是一个好主意!我已经添加了一条注释,展示了如何使用具有2D索引的1D数组。如果你真的坚持要使用2D数组,你可以使用那个符号和你原来的循环重构它。 - Wacov
是的,我想我会尝试重写数组代码使其成为YX而不是XY,看看是否可以修复旋转问题。 - You'reAGitForNotUsingGit
1
好的,我已经修复完成,速度显著提升了!非常感谢! - You'reAGitForNotUsingGit

1

0

不要使用二维数组,考虑使用一点 for 循环逻辑和一个一维数组

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

这种方法应该比尝试将一维数组拆分成二维数组更高效,因为您将转换像素数据(似乎在内部存储为int[])为int[][],仅仅是为了稍微简化逻辑。

int[] pixels = new int[bitmap.getWidth() * bitmap.getHeight()];
bitmap.getPixels(pixels, 0, bitmap.getWidth(), 0, 0, bitmap.getWidth(), bitmap.getHeight());
for (int row = 0; row < bitmap.getHeight(); row++)
    for (int column = 0; column < bitmap.getWidth(); column++)
        Color color = Color.valueOf(pixels[row * bitMap.getWidth() + column]);

请查看Android开发者参考文档,了解Bitmap.getPixels(int[], int, int, int, int, int, int)Color.valueOf(int)(分别提取单个颜色组件的方法为Color.alpha(int)Color.red(int)Color.green(int)Color.blue(int))。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接