指定されたURIでSDカードからサムネイルを取得する方法?? bitmapfactory を使用してみましたが、パフォーマンスが悪いか、OutOfMemoryError です。大量のデータを含むリストビューにサムネイルを配置する予定ですが、サムネイルまたは何か提案を使用する必要がありますか? サムネイルを使用する場合は、どうすればいいですか...?
助けてくれてありがとう
指定されたURIでSDカードからサムネイルを取得する方法?? bitmapfactory を使用してみましたが、パフォーマンスが悪いか、OutOfMemoryError です。大量のデータを含むリストビューにサムネイルを配置する予定ですが、サムネイルまたは何か提案を使用する必要がありますか? サムネイルを使用する場合は、どうすればいいですか...?
助けてくれてありがとう
次のメソッドを使用して、画像のサムネイルを取得できます。
private Bitmap getBitmap(String path) {
Uri uri = getImageUri(path);
InputStream in = null;
try {
final int IMAGE_MAX_SIZE = 1200000; // 1.2MP
in = mContentResolver.openInputStream(uri);
// Decode image size
BitmapFactory.Options o = new BitmapFactory.Options();
o.inJustDecodeBounds = true;
BitmapFactory.decodeStream(in, null, o);
in.close();
int scale = 1;
while ((o.outWidth * o.outHeight) * (1 / Math.pow(scale, 2)) > IMAGE_MAX_SIZE) {
scale++;
}
Log.d(TAG, "scale = " + scale + ", orig-width: " + o.outWidth + ", orig-height: " + o.outHeight);
Bitmap b = null;
in = mContentResolver.openInputStream(uri);
if (scale > 1) {
scale--;
// scale to max possible inSampleSize that still yields an image
// larger than target
o = new BitmapFactory.Options();
o.inSampleSize = scale;
b = BitmapFactory.decodeStream(in, null, o);
// resize to desired dimensions
int height = b.getHeight();
int width = b.getWidth();
Log.d(TAG, "1th scale operation dimenions - width: " + width + ", height: " + height);
double y = Math.sqrt(IMAGE_MAX_SIZE
/ (((double) width) / height));
double x = (y / height) * width;
Bitmap scaledBitmap = Bitmap.createScaledBitmap(b, (int) x, (int) y, true);
b.recycle();
b = scaledBitmap;
System.gc();
} else {
b = BitmapFactory.decodeStream(in);
}
in.close();
Log.d(TAG, "bitmap size - width: " +b.getWidth() + ", height: " + b.getHeight());
return b;
} catch (IOException e) {
Log.e(TAG, e.getMessage(),e);
return null;
}
}
ビットマップを使用した後は、常に bitmap.recycle() メソッドを呼び出します。メモリからビットマップをクリアします。また、コード内のメモリ リークも回避してください。これで OOME が解決されます。
このコードを試してみると、メモリ不足エラーが修正されます。高さと幅を自分のものに変更します。ここで、intent_data2 はファイル パスです。
public Bitmap custom_SizedImage(String intent_data2) {
int targetHeight = 534, targetWidth = 534;
Options options = new Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeFile(intent_data2, options);
double sampleSize = 0;
Boolean scaleByHeight = Math.abs(options.outHeight - targetHeight) >= Math
.abs(options.outWidth - targetWidth);
if (options.outHeight * options.outWidth * 2 >= 1638) {
sampleSize = scaleByHeight ? options.outHeight / targetHeight
: options.outWidth / targetWidth;
sampleSize = (int) Math.pow(2d,
Math.floor(Math.log(sampleSize) / Math.log(2d)));
}
options.inJustDecodeBounds = false;
options.inTempStorage = new byte[128];
while (true) {
try {
options.inSampleSize = (int) sampleSize;
mBitmap = BitmapFactory.decodeFile(intent_data2, options);
Display display = getWindowManager().getDefaultDisplay();
int width = display.getWidth();
int height = display.getHeight();
int screenDiff = height - width;
int screenRatio = screenDiff / 3;
float scaleFactor = mBitmap.getWidth() / width;
float y_Pos = scaleFactor * screenRatio;
Matrix matrix = new Matrix();
matrix.postScale(0.5f, 0.5f);
croppedBitmap = Bitmap.createBitmap(mBitmap, 0, (int) y_Pos,
mBitmap.getWidth(), mBitmap.getWidth(), matrix, true);
scaledBitmap = Bitmap.createBitmap(targetWidth, targetHeight,
Config.RGB_565);
float ratioX = targetWidth / (float) croppedBitmap.getWidth();
float ratioY = targetHeight / (float) croppedBitmap.getHeight();
float middleX = targetWidth / 2.0f;
float middleY = targetHeight / 2.0f;
Matrix scaleMatrix = new Matrix();
scaleMatrix.setScale(ratioX, ratioY, middleX, middleY);
Canvas canvas = new Canvas(scaledBitmap);
canvas.setMatrix(scaleMatrix);
canvas.drawBitmap(croppedBitmap,
middleX - croppedBitmap.getWidth() / 2, middleY
- croppedBitmap.getHeight() / 2, new Paint(
Paint.FILTER_BITMAP_FLAG));
//saveImage(scaledBitmap);
break;
} catch (Exception ex) {
try {
sampleSize = sampleSize * 2;
} catch (Exception ex1) {
}
}
}
return scaledBitmap;
}
// Parameters
int w,h;
// First only decode image size
BitmapFactory.Options opt = new BitmapFactory.Options();
opt.inJustDecodeBounds = true;
Bitmap bmp = BitmapFactory.decodeFile(file, opt);
// Decode small enough image
int heightRatio = (int)opt.outHeight/h;
int widthRatio = (int)opt.outWidth/w;
if (heightRatio > 1 || widthRatio > 1)
{
if (heightRatio > widthRatio)
opt.inSampleSize = heightRatio;
else
opt.inSampleSize = widthRatio;
}
opt.inJustDecodeBounds = false;
bmp = BitmapFactory.decodeFile(file, opt);