0

サーバーから画像をダウンロードして、Androidの内部ストレージに保存しようとしています。2 MB 未満の画像をダウンロードしている場合、すべてのケースで問題なく動作しています。しかし、サイズが 2 MB を超える JPEG 画像をダウンロードすると、2 つの問題に直面します。

1 つ目は、エミュレーターを使用してサーバーからイメージをダウンロードして保存しようとすると、「ビットマップ サイズが VM の予算を超えています」などのエラーが発生し、アクティビティがクラッシュすることです。

2 番目の問題は、この問題は自分の携帯電話でアプリケーションを実行したときではなく、代わりに別の問題が発生していることです。ダウンロードした画像を表示すると、画像に他の色 (虹色のようなもの) も含まれています。

画像をダウンロードして保存するために使用しているコードは次のとおりです。

//For downloading the image file
    void downloadFile(String fileUrl)
    {
        URL myFileUrl = null;
        try {
            myFileUrl = new URL(fileUrl);
        } catch (MalformedURLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        try 
        {
            HttpURLConnection conn = (HttpURLConnection) myFileUrl .openConnection();
            conn.setDoInput(true);
            conn.connect();
            InputStream is = conn.getInputStream();
            bmImg = BitmapFactory.decodeStream(is);

        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
    //For saving the downloaded image 
    void saveImage() {
        try 
        {
            String fileName ="displayimg.png";
            final FileOutputStream fos = openFileOutput(fileName, Activation.MODE_PRIVATE);
            bmImg.compress(CompressFormat.PNG, 90, fos);

        } catch (Exception e) 
        {
            e.printStackTrace();
        }

    }

画像を表示するコードは次のとおりです。

private Bitmap myBitmap;
myBitmap= BitmapFactory.decodeFile(imgFile.getAbsolutePath());
ivDisplayImage.setImageBitmap(myBitmap);
4

4 に答える 4

3

コードにはいくつかの問題があります。まず、画像を png 形式で圧縮しようとしていますが、png 形式は圧縮しません。jpegを使用する必要があります。これにより、画像サイズと品質が低下します。2番目に、画像をダウンロードして画像ビューに表示する非常に効率的な方法があります。リンクは次のとおりです。ビットマップを効率的に表示する最初の問題java.lang.OutofMemoryError: ビットマップサイズが VM 予算を超えています。 そして、いくつかの良いライブラリがあります。次のようなテーマを使用することをお勧めします

于 2013-03-19T08:40:10.597 に答える
2

ビットマップをスケーリングしてイメージビューに表示するImageLoader クラスを使用する必要があります。

また、このチュートリアルに従って、Web から画像を表示します。

これがお役に立てば幸いです。

于 2013-03-19T08:36:23.030 に答える
1

Universal Image Loader を使用できます。https://github.com/nostra13/Android-Universal-Image-Loader . 非同期で画像をダウンロードします。メモリまたは SD カードに画像をキャッシュします。

遅延読み込みhttps://github.com/thest1/LazyListもご覧ください。

使用していないビットマップもリサイクルします。

 bitmap.recycle();

bitmpas を効率的にロードするには、リンク内のドキュメントを参照してください。 http://developer.android.com/training/displaying-bitmaps/load-bitmap.html .

java.lang.OutofMemoryError: ビットマップ サイズが VM の予算を超えています。これは、メモリ リークが発生していることを意味します。 http://android-developers.blogspot.de/2009/01/avoiding-memory-leaks.html .

http://www.youtube.com/watch?v=_CruQY55HOk . 話は、メモリ管理とメモリ リークの回避についてです。また、MAT アナライザーを使用してメモリ リークを見つける方法についても説明します。

png への圧縮中にビットマップの色が変化します。おそらくあなたの質問に関連する答えを確認してください。また、お使いの携帯電話が実行している Android のバージョンも確認してください。

png への圧縮中にビットマップの色が変化します。このリンクを確認してください。

于 2013-03-19T08:44:49.097 に答える
0

このライブラリを使用することをお勧めします: http://loopj.com/android-async-http/

サンプルコードは次のとおりです。

            AsyncHttpClient client = new AsyncHttpClient();
        String[] allowedContentTypes = new String[] { "image/jpeg" }; // here you need to type the mimetype of the file

        client.get("link to jpg or any image"),
                new BinaryHttpResponseHandler(allowedContentTypes) {
                    @Override
                    public void onSuccess(byte[] fileData) { 
                        // this means it downloaded succesfully and you could make a filoutputstream to sdcard 
                        FileOutputStream fos;
                        try {
                            fos = new FileOutputStream(Environment
                                    .getExternalStorageDirectory()
                                    + "/Images/test.jpg");

                            fos.write(fileData);
                            fos.close();
                            fos.flush();
                        } catch (FileNotFoundException e) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                        } catch (IOException e) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                        } finally {
                        // here you could set it to an imageview or do anything you wouyld like

                        }
                    }
                });
    }

ご不明な点がございましたら、お知らせください。

于 2013-03-19T08:32:11.273 に答える