android 图像的位图子采样
android Bitmap Subsampling of Image
我在 SD 卡的列表视图中显示图像时遇到内存不足错误问题
我知道这是因为我需要对位图进行子采样,因为它们是 8mp 的大图片,如果我将它们缩小到 600 x 450,它们可以完美加载
我使用以下方式正常加载它们
Bitmap bmp = BitmapFactory.decodeFile("/storage/emulated/0/Pictures/" + text7[i]);
item_details.setImage(bmp);
正如我所说,如果我使用全尺寸图像,这会使应用程序崩溃
我有以下两种可能对位图进行子采样的方法
public static Bitmap decodeSampledBitmapFromResource(Resources res, int resId,
int reqWidth, int reqHeight) {
// First decode with inJustDecodeBounds=true to check dimensions
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeResource(res, resId, options);
// Calculate inSampleSize
options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
// Decode bitmap with inSampleSize set
options.inJustDecodeBounds = false;
return BitmapFactory.decodeResource(res, resId, options);
}
public static int calculateInSampleSize(
BitmapFactory.Options options, int reqWidth, int reqHeight) {
// Raw height and width of image
final int height = options.outHeight;
final int width = options.outWidth;
int inSampleSize = 1;
if (height > reqHeight || width > reqWidth) {
final int halfHeight = height / 2;
final int halfWidth = width / 2;
// Calculate the largest inSampleSize value that is a power of 2 and keeps both
// height and width larger than the requested height and width.
while ((halfHeight / inSampleSize) > reqHeight
&& (halfWidth / inSampleSize) > reqWidth) {
inSampleSize *= 2;
}
}
return inSampleSize;
}
问题是我不知道如何调用它所以显示
这是我填充列表视图的方法
private ArrayList<ListItemDetails> GetSearchResults() {
// TODO Auto-generated method stub
ArrayList<ListItemDetails> results = new ArrayList<ListItemDetails>();
ImageView imageview = (ImageView) findViewById(R.id.imageView1);
DBAdapter db = new DBAdapter(this);
db.open();
Cursor c = db.getAsset3();
String[] text1 = new String[c.getCount()];
String[] text2 = new String[c.getCount()];
String[] text3 = new String[c.getCount()];
String[] text4 = new String[c.getCount()];
String[] text5 = new String[c.getCount()];
String[] text6 = new String[c.getCount()];
String[] text7 = new String[c.getCount()];
for(int i = 0; c.moveToNext(); ++i)
{
text1[i] = c.getString(0);
text2[i] = c.getString(1);
text3[i] = c.getString(2);
text4[i] = c.getString(3);
text5[i] = c.getString(4);
text6[i] = c.getString(5);
text7[i] = c.getString(6);
}
c.close();
for(int i=0;i<text1.length;i++)
{
item_details= new ListItemDetails();
item_details.setSR1("School: " + text1[i]);
item_details.setSR2("Building: " + text2[i]);
item_details.setSR3("Floor: " + text3[i]);
item_details.setSR4("Room: " + text4[i]);
item_details.setSR5("Drawing Ref: " + text5[i]);
item_details.setSR6("Fault: " + text6[i]);
item_details.setSR7("Picture Filename: " + text7[i]);
String picFormat="Harris%d.jpg";
String pic = String.format(picFormat, i+1);
/////////////////////////////////////////////////////////////////
/// Load bitmap
imageview.setImageBitmap(decodeSampledBitmapFromResource(getResources(),
R.id.imageView1, 100, 100));
results.add(item_details);
}
return results;
}
它似乎在列表视图加载时工作,并且每个项目上的所有文本都在那里,但图像是空白的
我哪里出错了?
感谢任何帮助
马克
您没有将图像文件名传递给 decodeSampledBitmapFromResource
,那么它如何知道要加载哪个文件?您传入的资源 ID 是您的 ImageView 的资源 ID,而不是图像资源的资源 ID。
如果您想从给定文件名而不是资源的文件中加载图像,您需要将 decodeSampledBitmapFromResource
更改为使用 BitmapFactory.decodeFile() instead of BitmapFactory.decodeResource 从文件中加载图像,如下所示:
public static Bitmap decodeSampledBitmapFromFile(String filename,
int reqWidth, int reqHeight) {
// First decode with inJustDecodeBounds=true to check dimensions
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeFile(filename, options);
// Calculate inSampleSize
options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
// Decode bitmap with inSampleSize set
options.inJustDecodeBounds = false;
return BitmapFactory.decodeFile(filename, options);
}
然后更改您的 ArrayList 代码以将文件名传递给它:
item_details.setImageBitmap(decodeSampledBitmapFromFile("/storage/emulated/0/Pictures/" + text7[i], 100, 100));
你可以用Picasso http://square.github.io/picasso/,它很简单,你会避免很多头痛。
我在 SD 卡的列表视图中显示图像时遇到内存不足错误问题
我知道这是因为我需要对位图进行子采样,因为它们是 8mp 的大图片,如果我将它们缩小到 600 x 450,它们可以完美加载
我使用以下方式正常加载它们
Bitmap bmp = BitmapFactory.decodeFile("/storage/emulated/0/Pictures/" + text7[i]);
item_details.setImage(bmp);
正如我所说,如果我使用全尺寸图像,这会使应用程序崩溃
我有以下两种可能对位图进行子采样的方法
public static Bitmap decodeSampledBitmapFromResource(Resources res, int resId,
int reqWidth, int reqHeight) {
// First decode with inJustDecodeBounds=true to check dimensions
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeResource(res, resId, options);
// Calculate inSampleSize
options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
// Decode bitmap with inSampleSize set
options.inJustDecodeBounds = false;
return BitmapFactory.decodeResource(res, resId, options);
}
public static int calculateInSampleSize(
BitmapFactory.Options options, int reqWidth, int reqHeight) {
// Raw height and width of image
final int height = options.outHeight;
final int width = options.outWidth;
int inSampleSize = 1;
if (height > reqHeight || width > reqWidth) {
final int halfHeight = height / 2;
final int halfWidth = width / 2;
// Calculate the largest inSampleSize value that is a power of 2 and keeps both
// height and width larger than the requested height and width.
while ((halfHeight / inSampleSize) > reqHeight
&& (halfWidth / inSampleSize) > reqWidth) {
inSampleSize *= 2;
}
}
return inSampleSize;
}
问题是我不知道如何调用它所以显示
这是我填充列表视图的方法
private ArrayList<ListItemDetails> GetSearchResults() {
// TODO Auto-generated method stub
ArrayList<ListItemDetails> results = new ArrayList<ListItemDetails>();
ImageView imageview = (ImageView) findViewById(R.id.imageView1);
DBAdapter db = new DBAdapter(this);
db.open();
Cursor c = db.getAsset3();
String[] text1 = new String[c.getCount()];
String[] text2 = new String[c.getCount()];
String[] text3 = new String[c.getCount()];
String[] text4 = new String[c.getCount()];
String[] text5 = new String[c.getCount()];
String[] text6 = new String[c.getCount()];
String[] text7 = new String[c.getCount()];
for(int i = 0; c.moveToNext(); ++i)
{
text1[i] = c.getString(0);
text2[i] = c.getString(1);
text3[i] = c.getString(2);
text4[i] = c.getString(3);
text5[i] = c.getString(4);
text6[i] = c.getString(5);
text7[i] = c.getString(6);
}
c.close();
for(int i=0;i<text1.length;i++)
{
item_details= new ListItemDetails();
item_details.setSR1("School: " + text1[i]);
item_details.setSR2("Building: " + text2[i]);
item_details.setSR3("Floor: " + text3[i]);
item_details.setSR4("Room: " + text4[i]);
item_details.setSR5("Drawing Ref: " + text5[i]);
item_details.setSR6("Fault: " + text6[i]);
item_details.setSR7("Picture Filename: " + text7[i]);
String picFormat="Harris%d.jpg";
String pic = String.format(picFormat, i+1);
/////////////////////////////////////////////////////////////////
/// Load bitmap
imageview.setImageBitmap(decodeSampledBitmapFromResource(getResources(),
R.id.imageView1, 100, 100));
results.add(item_details);
}
return results;
}
它似乎在列表视图加载时工作,并且每个项目上的所有文本都在那里,但图像是空白的
我哪里出错了?
感谢任何帮助
马克
您没有将图像文件名传递给 decodeSampledBitmapFromResource
,那么它如何知道要加载哪个文件?您传入的资源 ID 是您的 ImageView 的资源 ID,而不是图像资源的资源 ID。
如果您想从给定文件名而不是资源的文件中加载图像,您需要将 decodeSampledBitmapFromResource
更改为使用 BitmapFactory.decodeFile() instead of BitmapFactory.decodeResource 从文件中加载图像,如下所示:
public static Bitmap decodeSampledBitmapFromFile(String filename,
int reqWidth, int reqHeight) {
// First decode with inJustDecodeBounds=true to check dimensions
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeFile(filename, options);
// Calculate inSampleSize
options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
// Decode bitmap with inSampleSize set
options.inJustDecodeBounds = false;
return BitmapFactory.decodeFile(filename, options);
}
然后更改您的 ArrayList 代码以将文件名传递给它:
item_details.setImageBitmap(decodeSampledBitmapFromFile("/storage/emulated/0/Pictures/" + text7[i], 100, 100));
你可以用Picasso http://square.github.io/picasso/,它很简单,你会避免很多头痛。