【发布时间】:2011-02-02 12:33:12
【问题描述】:
我想将位图图像的裁剪版本加载到位图对象中,而不加载原始位图。
如果不编写自定义加载例程来处理原始数据,这是否可能?
谢谢, 桑德尔
【问题讨论】:
标签: android performance graphics
我想将位图图像的裁剪版本加载到位图对象中,而不加载原始位图。
如果不编写自定义加载例程来处理原始数据,这是否可能?
谢谢, 桑德尔
【问题讨论】:
标签: android performance graphics
您可以使用以下算法在不完全加载位图的情况下加载位图的缩放版本
查看以下帖子 Android: Resize a large bitmap file to scaled output file 了解更多详情。
【讨论】:
这实际上非常简单。使用
Bitmap yourBitmap = Bitmap.createBitmap(sourceBitmap, x to start from, y to start from, width, height)
更新:使用BitmapRegionDecoder
【讨论】:
使用RapidDecoder。
只需这样做
import rapid.decoder.BitmapDecoder;
Rect bounds = new Rect(left, top, right, bottom);
Bitmap bitmap = BitmapDecoder.from(getResources(), R.drawable.image)
.region(bounds).decode();
需要 Android 2.2 或更高版本。
【讨论】:
@RKN
如果裁剪的位图超出 VM,您的方法也可能抛出 OutOfMemoryError 异常。
我的方法结合了您的方法和针对此异常的保护: (l, t, r, b - 图像的百分比)
Bitmap cropBitmap(ContentResolver cr, String file, float l, float t, float r, float b)
{
try
{
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
// First decode with inJustDecodeBounds=true to check dimensions
BitmapFactory.decodeFile(file, options);
int oWidth = options.outWidth;
int oHeight = options.outHeight;
InputStream istream = cr.openInputStream(Uri.fromFile(new File(file)));
BitmapRegionDecoder decoder = BitmapRegionDecoder.newInstance(istream, false);
if (decoder != null)
{
options = new BitmapFactory.Options();
int startingSize = 1;
if ((r - l) * oWidth * (b - t) * oHeight > 2073600)
startingSize = (int) ((r - l) * oWidth * (b - t) * oHeight / 2073600) + 1;
for (options.inSampleSize = startingSize; options.inSampleSize <= 32; options.inSampleSize++)
{
try
{
return decoder.decodeRegion(new Rect((int) (l * oWidth), (int) (t * oHeight), (int) (r * oWidth), (int) (b * oHeight)), options);
}
catch (OutOfMemoryError e)
{
Continue with for loop if OutOfMemoryError occurs
}
}
}
else
return null;
}
catch (FileNotFoundException e)
{
e.printStackTrace();
}
catch (IOException e)
{
e.printStackTrace();
}
return null;
}
并返回最大可用位图或 null
【讨论】:
startingSize > 32 最初是因为输入图像太大怎么办?
试试这个
InputStream istream = null;
try {
istream = this.getContentResolver().openInputStream(yourBitmapUri);
} catch (FileNotFoundException e1) {
e1.printStackTrace();
}
BitmapRegionDecoder decoder = null;
try {
decoder = BitmapRegionDecoder.newInstance(istream, false);
} catch (IOException e) {
e.printStackTrace();
}
Bitmap bMap = decoder.decodeRegion(new Rect(istream, x to start from, y to start from, x to end with, y to end with), null);
imageView.setImageBitmap(bMap);
【讨论】: