Android: получить миниатюру изображения на SD-карте, учитывая Uri исходного изображения
Итак, у меня есть Uri изображения, которое пользователь выбирает из изображений со своей SD-карты. И я хотел бы отобразить эскиз этого изображения, потому что, очевидно, изображение может быть огромным и занимать весь экран. Кто-нибудь знает как?
5 ответов
Вы можете просто создать миниатюру видео и изображения, используя класс java ThumnailUtil
Bitmap resized = ThumbnailUtils.extractThumbnail(BitmapFactory.decodeFile(file.getPath()), width, height);
public static Bitmap createVideoThumbnail (String filePath, int kind)
Добавлено на уровне API 8 Создание миниатюры видео для видео. Может возвращать ноль, если видео повреждено или формат не поддерживается.
Параметры filePath путь вида видеофайла может быть MINI_KIND или MICRO_KIND
Для получения дополнительной исходный код класса Thumbnail Util
Этот код сделает работу:
Bitmap getPreview(URI uri) {
File image = new File(uri);
BitmapFactory.Options bounds = new BitmapFactory.Options();
bounds.inJustDecodeBounds = true;
BitmapFactory.decodeFile(image.getPath(), bounds);
if ((bounds.outWidth == -1) || (bounds.outHeight == -1))
return null;
int originalSize = (bounds.outHeight > bounds.outWidth) ? bounds.outHeight
: bounds.outWidth;
BitmapFactory.Options opts = new BitmapFactory.Options();
opts.inSampleSize = originalSize / THUMBNAIL_SIZE;
return BitmapFactory.decodeFile(image.getPath(), opts);
}
Вы можете рассчитать ближайшую степень 2, чтобы использовать для inSampleSize
потому что это называется быстрее.
Я считаю, что этот код является самым быстрым способом создания миниатюры из файла на SD-карте:
public static Bitmap decodeFile(String file, int size) {
//Decode image size
BitmapFactory.Options o = new BitmapFactory.Options();
o.inJustDecodeBounds = true;
BitmapFactory.decodeFile(file, o);
//Find the correct scale value. It should be the power of 2.
int width_tmp = o.outWidth, height_tmp = o.outHeight;
int scale = (int)Maths.pow(2, (double)(scale-1));
while (true) {
if (width_tmp / 2 < size || height_tmp / 2 < size) {
break;
}
width_tmp /= 2;
height_tmp /= 2;
scale++;
}
//Decode with inSampleSize
BitmapFactory.Options o2 = new BitmapFactory.Options();
o2.inSampleSize = scale;
return BitmapFactory.decodeFile(file, o2);
}
Несколько попыток я не смог получить эскиз пути изображения с SD. Я решил эту проблему, получая растровое изображение для Android, прежде чем создать представление изображения в адаптере для gridview (или там, где вам нужно). Поэтому я называю метод imageView.setImageBitmap(someMethod(Context context, imageID))
Bitmap someMethod(Context context, long imageId){
Bitmap bitmap = Media.Images.Thumbnails.getThumbnail(context.getAplicationContext.getContentResolver(), imageid, MediaStore.Images.Thumbnails.MINI_KIND, null);
return bitmap;
}
Вы можете получить ID изображения с вашего SD, используя это руководство ( Получить список фотогалерей на Android)
Если вам нравятся эскизы HQ, используйте библиотеку [RapidDecoder][1]. Это просто как следовать:
import rapid.decoder.BitmapDecoder;
...
Bitmap bitmap = BitmapDecoder.from(getResources(), R.drawable.image)
.scale(width, height)
.useBuiltInDecoder(true)
.decode();
Не забудьте использовать встроенный декодер, если вы хотите уменьшить масштаб менее чем на 50% и получить результат HQ. Я проверял это в API Level 8:)
Этот пакет позволит вам получить доступ к URI изображения для получения размера изображения, больших данных Bitmap, выборки изображения любого меньшего размера для экономии памяти и повышения производительности.
Он использует InputStream и BitmapFactory:
public int[] getImageSize(Uri uri){
try {
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
InputStream input = this.getContentResolver().openInputStream(uri);
BitmapFactory.decodeStream(input, null, options); input.close();
return new int[]{options.outWidth, options.outHeight};
}
catch (Exception e){}
return new int[]{0,0};
}
public Bitmap BitmapImage(Uri uri){return BitmapImage(uri,-1,-1);}
public Bitmap BitmapImage(Uri uri, int maxSize){return BitmapImage(uri,maxSize,maxSize);}
public Bitmap BitmapImage(Uri uri, int Wmax, int Hmax){
try {
InputStream input = this.getContentResolver().openInputStream(uri);
double ratio=1;
if ((Wmax>-1)&&(Hmax>-1)){
int[] wh=getImageSize(uri); double w=wh[0], h=wh[1];
if (w/Wmax>1){ratio=Wmax/w; if (h*ratio>Hmax){ratio=Hmax/h;}}
else if (h/Hmax>1){ratio=Hmax/h;}
}
BitmapFactory.Options bitmapOptions = new BitmapFactory.Options();
bitmapOptions.inSampleSize = (int)Math.ceil(1/ratio);
bitmapOptions.inPreferredConfig=Bitmap.Config.ARGB_8888;
Bitmap bitmap = BitmapFactory.decodeStream(input, null, bitmapOptions);
input.close();
return bitmap;
}
catch (Exception e){}
return null;
}
Четыре функции для разных вариантов использования:
/*
getImageSize(Uri uri): return int[]{ width, height}
BitmapImage(Uri uri): return Bitmap in full size
BitmapImage(Uri uri, int maxSize): return sampled Bitmap which is limited in square size
BitmapImage(Uri uri, int Wmax, int Hmax): return sampled Bitmap which is limited width and height
*/