2016-04-03 9 views
1

Facebook、Instagramまたはデバイス自体から画像をトリミングする必要があります。ユーザフローの最後(彼がそれらを選択するところ)で、上記のすべてのイメージをサーバに送信する必要があります。しかし、すべて同じ幅/高さ比(例えば3/2)であるため、手動で画像を切り抜く必要があります。ここでメモリ不足の例外なしでビットマップをロードおよびクロップする

私のアップロードサービスやトリミングで何が起こっているかの簡単な例:

Bitmap bitmap = ImageLoading.getLoader(UploadService.this).loadImageSync(path); 
//crop calculations 
Bitmap croppedBitmap = Bitmap.createBitmap(bitmap, x, y, w, y); 
String croppedPath = saveCroppedImage(croppedBitmap); 

私は、ファイルシステムからこのファイルを読み込み、バックエンドに送信するBASE64にそれをエンコードします。

複数の画像でこれを行う必要があるときは、定期的にOOM例外を取得します。たぶん私はこれを間違った方向に向かっています。サーバー側を切り抜くことは、バックエンドがFacebookやInstagramをクエリする必要があるため、本当に最後にやりたいことです。

ビットマップのスケーリングされたバージョンを読み込むことはオプションではありません。デバイスに表示しません。

私が試みた:

  • にSystem.gc()
  • Bitmap.recycle()。
  • マニフェストでlargeHeapを実際に使用する必要がありますか?

注:私はユニバーサルイメージローダーもユーザーフローに使用しています。そのため、アップロードサービスでも使用しています。

+1

GCは問題ではありません。 Androidヒープは断片化します。割り当て要求を満たすのに十分な大きさの単一の空きブロックは存在しません。 'Bitmap'オブジェクト(' BitmapFactory.Options'の 'inBitmap'を参照)を再利用しようとすると、UILを使わずに自分自身でイメージを読み込む必要があります。理想的には、(createBitmap()のように)イメージの別のコピーの作成を含まないクロップを行う方法があります。また、saveCroppedImage()でできることもあります。 – CommonsWare

+0

コメントありがとうございました! saveCroppedImage()はFileOutputStreamを使用し、PNG 100に圧縮します。私は本当に品質の低下を余裕がありません。私はinBitmapを見ましたが、それはさまざまな画像サイズの使用を制限するようです。 –

+1

「inBitmapを見ましたが、これはさまざまな画像サイズの使用を制限するようです」 - APIレベル19+では柔軟性が向上しますが、それは限られています。一方、NDKの使用を開始し、C/C++で画像の切り抜きを行う場合を除き、たくさんのオプションがありません。 – CommonsWare

答えて

0

AndroidManifestファイルにlargeHeap = trueを追加する必要があると思います。

第2に、ユニバーサルImageLoaderを使用している場合、ビットマップをより小さなサイズでダウンロードできます。

ImageSize targetSize = new ImageSize(80, 50); // result Bitmap will be fit to this size 
Bitmap bmp = imageLoader.loadImageSync(imageUri, targetSize, options); // This bitmap will be of specified size. 

あなたはさらにリンクをたどる約Universal Image Loaderを読むことができます:このコードを見てください。

+0

ビットマップのより小さいバージョンを読み込むことはオプションではありません。私は恐れています。我々は完全な品質が必要です。私はlargeHeapを使わなければならないかもしれないと思ったが、それは汚れたコードのように聞こえる。 –

関連する問題