从SD CARD读取大图像并保存它们的大小(内存不足!)

时间:2011-10-12 11:45:12

标签: android image bitmap out-of-memory

我正在尝试从SD卡中读取图像并将其保存在我的自定义目录中,其大小调整为1024像素,但我总是得到一个OutOfMemory。我已经在stackoverflow中尝试了大多数关于“内存不足”的工作人员的例子......

我问我Galería应用程序如何轻松管理4000像素的图像???

感谢。 大卫。

4 个答案:

答案 0 :(得分:2)

  

我问我GaleríaApp如何管理4000像素的图像   容易吗?

它将BitmapFactory.Options.inSampleSizeBitmapFactory的解码方法结合使用,从磁盘加载缩小尺寸的缩略图。它还会平铺图像并仅在图像缩放时加载图像的某个部分。

答案 1 :(得分:1)

请尝试以下代码。希望这会有所帮助。

位图bMap = BitmapFactory.decodeFile(photoPath);

    int orig_width = bMap.getWidth();
    int orig_height = bMap.getHeight();
    int aspect = orig_width / orig_height;

    float aspectRatio = orig_width / orig_height;

    int new_height = (int) (orig_height / (aspectRatio));
    int new_width = (int) ((orig_width * aspectRatio)/2);

    Bitmap scaled = Bitmap.createScaledBitmap(bMap, new_height, new_width, true);

    ByteArrayOutputStream bos = new ByteArrayOutputStream(); 
    scaled.compress(CompressFormat.PNG, 0 /*ignored for PNG*/, bos); 
    byte[] bitmapdata = bos.toByteArray();

    BitmapFactory.Options options = new BitmapFactory.Options(); 
    options.inSampleSize = 5; 

    File sdImageMainDirectory = Environment.getExternalStorageDirectory();
    FileOutputStream fileOutputStream = null; 
    String tempFile = "tempImage"; 
    int quality = 50; 

    Bitmap myImage = BitmapFactory.decodeByteArray(bitmapdata, 0,bitmapdata.length);

    try {
        fileOutputStream = new FileOutputStream(sdImageMainDirectory.toString() +"/" + tempFile + ".jpg");
        BufferedOutputStream bosBufferedOutputStream = new BufferedOutputStream(fileOutputStream); 

        myImage.compress(CompressFormat.JPEG, quality, bosBufferedOutputStream); 
        bosBufferedOutputStream.flush();
        bosBufferedOutputStream.close(); 
    } catch (FileNotFoundException e1) {
        e1.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }

答案 2 :(得分:1)

在Android上,移动应用程序的内存有限,所以没有人会想到像内存那样巨大的Bitmap(4000px)。 只是处理这种情况的一些提示:

  1. 调整图像大小以适合屏幕显示(适合视图显示更好)
  2. 将质量降低到可接受的水平(而用户的眼睛可能感觉不到差异),
  3. 不会同时显示太多Bitmap张图片。
  4. 避免过多使用getPixel()setPixel,这会导致非常糟糕的表现。请改用getPixels()setPixels()
  5. 完成后使用Bitmaprecycle()释放内存(GC知道此时该做什么)。
  6. 不要试图创建这么多对Bitmap个对象的引用,之后你会自杀!

答案 3 :(得分:0)

                        BitmapFactory.Options o = new BitmapFactory.Options(); 
                    o.inJustDecodeBounds = true; 
                    BitmapFactory.decodeFile(filePath, o); 

                    int REQUIRED_SIZE = 640; 
                    int width_tmp = o.outWidth, height_tmp = o.outHeight; 
                    int scale = 1; 
                    while(true) { 
                        if (width_tmp < REQUIRED_SIZE && height_tmp < REQUIRED_SIZE) break; 
                        width_tmp /= 2; 
                        height_tmp /= 2; 
                        scale *= 2; 
                    } 

                    BitmapFactory.Options o2 = new BitmapFactory.Options(); 
                    o2.inSampleSize = scale; 
                    Bitmap bitmap = BitmapFactory.decodeFile(filePath, o2); 

                    ByteArrayOutputStream bs2 = new ByteArrayOutputStream();
                    bitmap.compress(Bitmap.CompressFormat.PNG, 90, bs2);
                    getIntent().putExtra("byte_picture", bs2.toByteArray());

收到:

Bitmap photo = BitmapFactory.decodeByteArray(data.getByteArrayExtra("byte_picture"),0,data.getByteArrayExtra("byte_picture").length);