【问题标题】:Bitmap to big to use getPixels?位图变大使用getPixels?
【发布时间】:2023-03-22 22:37:01
【问题描述】:

如果我用我的三星 Galaxy s2 制作图片,图片为 3264 x 2448 像素。 我想对其使用颜色范围检查,但它不起作用。

但是,如果我将图片缩小,例如 2500 x 2500(像素更少),那么它确实有效。但我想使用 Galaxy s2 (3264 x 2448) 的图片大小。 我认为这是一个内存问题? 我已经不知道极限是什么了。 但他们是“绕过”这个问题的另一种方式吗?

这是一段代码,我现在怎么做:

bmp = BitmapFactory.decodeResource(getResources(),
                R.drawable.four_colors);

int width = bmp.getWidth();
int height = bmp.getHeight();
int[] pixels = new int[width * height];

bmp.getPixels(pixels, 0, width, 0, 0, width, height);

for (int y = 0; y < height; y++){
            for (int x = 0; x < width; x++){
                     int index = y * width + x;
                     int R = (pixels[index] >> 16) & 0xff;     //bitwise shifting
                     int G = (pixels[index] >> 8) & 0xff;
                     int B = pixels[index] & 0xff;
                     total++;
                     if ((G > R)&&(G > B)){
                         counter++;
                    }
            }
}

它崩溃是因为图片太大,较小的图片可以工作。 那么他们有什么东西可以“绕过”这个问题吗?而不是使用较小的图像:)

我尝试了其他一些事情,但没有成功,我尝试解释我尝试了什么。

  1. 我尝试将图像“剪切”成两半,然后单独扫描(没有用)。

  2. 我尝试只扫描它的一半 (1632 x 1224) 然后将图像旋转 (180 度) 并再次扫描,但这也没有用。

  3. 打我:)

【问题讨论】:

  • 嘿,我明天要试试答案。我会让你听到它的结果

标签: android memory colors bitmap


【解决方案1】:

在处理大图像时,您真的应该使用BitmapRegionDecoder 来分块处理它。

编辑 - 现在举个简单的例子:

    try {
        // Processes file in res/raw/huge.jpg or png
        BitmapRegionDecoder decoder = BitmapRegionDecoder.newInstance(getResources().openRawResource(R.raw.huge), false);
        try  {
            final int width = decoder.getWidth();
            final int height = decoder.getHeight();
            // Divide the bitmap into 1024x768 sized chunks and process it.
            int wSteps = (int) Math.ceil(width / 1024.0);
            int hSteps = (int) Math.ceil(height / 768.0);
            Rect rect = new Rect();
            long total = 0L, counter = 0L;
            for (int h = 0; h < hSteps; h++) {
                for (int w = 0; w < wSteps; w++) {
                    int w2 = Math.min(width, (w + 1) * 1024);
                    int h2 = Math.min(height, (h + 1) * 768);
                    rect.set(w * 1024, h * 768, w2, h2);
                    Bitmap bitmap = decoder.decodeRegion(rect, null);
                    try {
                        int bWidth = bitmap.getWidth();
                        int bHeight = bitmap.getHeight();
                        int[] pixels = new int[bWidth * bHeight];
                        bitmap.getPixels(pixels, 0, bWidth, 0, 0, bWidth, bHeight);
                        for (int y = 0; y < bHeight; y++){
                            for (int x = 0; x < bWidth; x++){
                                int index = y * bWidth + x;
                                int R = (pixels[index] >> 16) & 0xff;     //bitwise shifting
                                int G = (pixels[index] >> 8) & 0xff;
                                int B = pixels[index] & 0xff;
                                total++;
                                if ((G > R)&&(G > B)){
                                    counter++;
                                }
                            }
                        }
                    } finally {
                        bitmap.recycle();
                    }
                }
            }
        } finally {
            decoder.recycle();
        }

【讨论】:

  • 嘿,不知何故,我无法让 BitmapRegionDecoder 工作。怎么用?
  • 文档很简单吗?不过,您通常必须将大量资源放在 res/raw 或 assets 中。
  • 上周刚开始接触 Java。所以这对我来说是全新的。我稍微修改了您发布的代码,因此它可以在我自己的代码中使用。在继续之前,我首先要学习/理解您完全发布的代码。感谢您的帮助!
  • 如何重新加入所有分割的位图?
【解决方案2】:

您可以通过使用 getPixels 方法的某些参数来限制一次加载的图像的像素数据量。我做了一些非常相似的事情,例如,我会一次读一行。

    for(int y = 0; y < height; y++)
    {
        bitmap.getPixels(pixels, 0, width, 0, y, width, 1);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-11-06
    • 1970-01-01
    • 1970-01-01
    • 2021-07-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多