У меня есть изображение большого размера. Во время выполнения я хочу прочитать изображение из хранилища и масштабировать его, чтобы уменьшить его вес и размер, и я могу использовать его как миниатюру. Когда пользователь нажимает на миниатюру, я хочу отобразить полноразмерное изображение.Android, как создать временную эскиз
ответ
мое решение
byte[] imageData = null;
try
{
final int THUMBNAIL_SIZE = 64;
FileInputStream fis = new FileInputStream(fileName);
Bitmap imageBitmap = BitmapFactory.decodeStream(fis);
imageBitmap = Bitmap.createScaledBitmap(imageBitmap, THUMBNAIL_SIZE, THUMBNAIL_SIZE, false);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
imageBitmap.compress(Bitmap.CompressFormat.JPEG, 100, baos);
imageData = baos.toByteArray();
}
catch(Exception ex) {
}
Используйте BitmapFactory.decodeFile(...)
, чтобы получить объект Bitmap
и установите его на ImageView
с ImageView.setImageBitmap()
.
На ImageView
установить размеры макета на что-то маленькое, например:
android:layout_width="66dip" android:layout_height="48dip"
Добавить onClickListener
в ImageView
и начать новый вид деятельности, в котором отображать изображение в полном размере с
android:layout_width="wrap_content" android:layout_height="wrap_content"
или укажите какой-либо более крупный размер.
Если у вас есть несколько изображений, вы должны заранее рассмотреть его масштабирование до размера большого пальца. в противном случае это может замедлить производительность при перемещении набора. – Moritz
Действительно, и для этого вы должны использовать Bitmap.createScaledBitmap (originalBitmap, newWidth, newHeight, false); –
dones следующий метод также уменьшает вес изображения? Bitmap.createScaledBitmap (originalBitmap, newWidth, newHeight, false) –
Вот более полное решение для масштабирования растрового изображения до размера миниатюр. Он расширяется в решении Bitmap.createScaledBitmap, поддерживая пропорции изображений, а также дополняя их одинаковой шириной, чтобы они выглядели хорошо в ListView.
Кроме того, было бы лучше всего сделать это масштабирование один раз и сохранить полученный битмап как blob в вашей базе данных Sqlite. Я включил фрагмент кода о том, как преобразовать Bitmap в массив байтов для этой цели.
public static final int THUMBNAIL_HEIGHT = 48;
public static final int THUMBNAIL_WIDTH = 66;
imageBitmap = BitmapFactory.decodeByteArray(mImageData, 0, mImageData.length);
Float width = new Float(imageBitmap.getWidth());
Float height = new Float(imageBitmap.getHeight());
Float ratio = width/height;
imageBitmap = Bitmap.createScaledBitmap(imageBitmap, (int)(THUMBNAIL_HEIGHT*ratio), THUMBNAIL_HEIGHT, false);
int padding = (THUMBNAIL_WIDTH - imageBitmap.getWidth())/2;
imageView.setPadding(padding, 0, padding, 0);
imageView.setImageBitmap(imageBitmap);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
imageBitmap.compress(Bitmap.CompressFormat.PNG, 100, baos);
byte[] byteArray = baos.toByteArray();
Есть ли причина, по которой вы изменили порядок аргументов для 'THUMBNAIL_HEIGHT' и' THUMBNAIL_HEIGHT' для 'createScaledBitmap'? – jayeffkay
Попробуйте
Bitmap ThumbImage = ThumbnailUtils.extractThumbnail(BitmapFactory.decodeFile(imagePath), THUMBSIZE, THUMBSIZE);
Эта утилита доступна из API_LEVEl 8. [Source]
Используя этот код, вы фактически загружаете в память копию большого растрового изображения, поэтому это не очень хороший способ управления большими изображениями. – GuillermoMP
@GuillermoMP Каков же тогда хороший способ? – Rafouille
Правильный способ - декодировать уменьшенную версию файла. Другие ответы предлагают такой подход. Также официальные документы хорошо объясняют процесс: https://developer.android.com/intl/es/training/displaying-bitmaps/load-bitmap.html. Поскольку этот вопрос является наиболее проголосовавшим (из-за его простоты), я просто хотел предупредить всех, что это не лучший способ. – GuillermoMP
/**
* Creates a centered bitmap of the desired size.
*
* @param source original bitmap source
* @param width targeted width
* @param height targeted height
* @param options options used during thumbnail extraction
*/
public static Bitmap extractThumbnail(
Bitmap source, int width, int height, int options) {
if (source == null) {
return null;
}
float scale;
if (source.getWidth() < source.getHeight()) {
scale = width/(float) source.getWidth();
} else {
scale = height/(float) source.getHeight();
}
Matrix matrix = new Matrix();
matrix.setScale(scale, scale);
Bitmap thumbnail = transform(matrix, source, width, height,
OPTIONS_SCALE_UP | options);
return thumbnail;
}
где is transform (matrix, source, width, height, OPTIONS_SCALE_UP | options) Метод – Andy
https://code.google.com/p/kontalk/source/browse/src/org/kontalk/xmpp/util/ThumbnailUtils. java? repo = androidclient & name = xmpp & r = f879e85d21d6e0a8a6f736ebe90c03e851b51436 – user1546570
Thanx дорого получил его. – Andy
Лучшее решение я нашел следующее. По сравнению с другими решениями, для этого нет необходимости загружать полное изображение для создания миниатюры, поэтому оно более эффективно! Его предел в том, что вы не можете иметь эскиз с точной шириной и высотой, но решение как можно ближе.
File file = ...; // the image file
Options bitmapOptions = new Options();
bitmapOptions.inJustDecodeBounds = true; // obtain the size of the image, without loading it in memory
BitmapFactory.decodeFile(file.getAbsolutePath(), bitmapOptions);
// find the best scaling factor for the desired dimensions
int desiredWidth = 400;
int desiredHeight = 300;
float widthScale = (float)bitmapOptions.outWidth/desiredWidth;
float heightScale = (float)bitmapOptions.outHeight/desiredHeight;
float scale = Math.min(widthScale, heightScale);
int sampleSize = 1;
while (sampleSize < scale) {
sampleSize *= 2;
}
bitmapOptions.inSampleSize = sampleSize; // this value must be a power of 2,
// this is why you can not have an image scaled as you would like
bitmapOptions.inJustDecodeBounds = false; // now we want to load the image
// Let's load just the part of the image necessary for creating the thumbnail, not the whole image
Bitmap thumbnail = BitmapFactory.decodeFile(file.getAbsolutePath(), bitmapOptions);
// Save the thumbnail
File thumbnailFile = ...;
FileOutputStream fos = new FileOutputStream(thumbnailFile);
thumbnail.compress(Bitmap.CompressFormat.JPEG, 90, fos);
fos.flush();
fos.close();
// Use the thumbail on an ImageView or recycle it!
thumbnail.recycle();
Это лучше всего подходит для устройств с низкой памятью – Lunatikul
Спасибо. Он решил проблему с исключением из памяти. –
Если вы хотите получить высококачественный результат, используйте библиотеку [RapidDecoder] [1]. Это просто следующим образом:
import rapid.decoder.BitmapDecoder;
...
Bitmap bitmap = BitmapDecoder.from(getResources(), R.drawable.image)
.scale(width, height)
.useBuiltInDecoder(true)
.decode();
Не забывайте использовать встроенный декодер, если вы хотите масштабировать до менее чем 50% и результат HQ.
Я нашел легкий способ сделать это
Bitmap thumbnail = ThumbnailUtils.extractThumbnail(BitmapFactory.decodeFile(mPath),200,200)
Синтаксис
Bitmap thumbnail = ThumbnailUtils.extractThumbnail(Bitmap source,int width,int height)
ИЛИ
использовать Пикассо зависимостях
компиляции 'com.squareup.picasso: Picasso: 2.5.2'
Picasso.with(context)
.load("file:///android_asset/DvpvklR.png")
.resize(50, 50)
.into(imageView2);
Ссылка Picasso
Этот ответ основан на решении, представленном в https://developer.android.com/topic/performance/graphics/load-bitmap.html (без использования внешних библиотек) с некоторыми изменения меня, чтобы сделать его функциональность лучше и практичнее.
Некоторые замечания по поводу этого решения:
Предполагается, что вы хотите сохранить пропорции. Другими слова:
finalWidth/finalHeight == sourceBitmap.getWidth()/sourceBitmap.getWidth()
(Вне зависимости от литья и округления вопросов)Предполагается, что у вас есть два значения (
maxWidth
&maxHeight
), что вы хотите любого из размеров ваше окончательное растровое изображение не превышает его соответствующее значение. Другими словами:finalWidth <= maxWidth && finalHeight <= maxHeight
Так
minRatio
был помещен в качестве основы расчетов (см реализацию). UNLIKE основное решение, которое положилоmaxRatio
в качестве основы расчетов в фактических. Кроме того, расчетinSampleSize
был намного лучше (более логичный, краткий и эффективный).Предполагается, что вы хотите (по крайней мере) один из конечных размеров имеет точно значение своего соответствующего MaxValue (каждый из них можно было, с учетом вышеуказанных допущений). Другими словами:
finalWidth == maxWidth || finalHeight == maxHeight
Конечный дополнительный шаг в сравнении с основным раствором (
Bitmap.createScaledBitmap(...)
) для этого ограничения «именно».Очень важно отметить , вы не должны делать этот шаг сначала (например, the accepted answer), из-за его значительного потребления памяти в случае огромных изображений!Он предназначен для декодирования
file
. Вы можете изменить его, как базовое решение для декодированияresource
(или все, что поддерживаетBitmapFactory
).
Реализация:
public static Bitmap decodeSampledBitmap(String pathName, int maxWidth, int maxHeight) {
// First decode with inJustDecodeBounds=true to check dimensions
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeFile(pathName, options);
final float wRatio_inv = (float) options.outWidth/maxWidth,
hRatio_inv = (float) options.outHeight/maxHeight; // Working with inverse ratios is more comfortable
final int finalW, finalH, minRatio_inv /* = max{Ratio_inv} */;
if (wRatio_inv > hRatio_inv) {
minRatio_inv = (int) wRatio_inv;
finalW = maxWidth;
finalH = Math.round(options.outHeight/wRatio_inv);
} else {
minRatio_inv = (int) hRatio_inv;
finalH = maxHeight;
finalW = Math.round(options.outWidth/hRatio_inv);
}
options.inSampleSize = pow2Ceil(minRatio_inv); // pow2Ceil: A utility function that comes later
options.inJustDecodeBounds = false; // Decode bitmap with inSampleSize set
return Bitmap.createScaledBitmap(BitmapFactory.decodeFile(pathName, options),
finalW, finalH, true);
}
/**
* @return the largest power of 2 that is smaller than or equal to number.
* WARNING: return {0b1000000...000} for ZERO input.
*/
public static int pow2Ceil(int number) {
return 1 << -(Integer.numberOfLeadingZeros(number) + 1); // is equivalent to:
// return Integer.rotateRight(1, Integer.numberOfLeadingZeros(number) + 1);
}
Пример использования, в случае, если вы имеете imageView
с определенным значением для layout_width
(match_parent
или явного значения) и неопределенные значение для layout_height
(wrap_content
) и вместо этого определено значение для maxHeight
:
imageView.setImageBitmap(decodeSampledBitmap(filePath,
imageView.getWidth(), imageView.getMaxHeight()));
- 1. Как создать эскиз
- 2. SharePoint: как создать эскиз?
- 3. Как создать эскиз видео?
- 4. Rails + Filepicker - как создать эскиз?
- 5. Как создать эскиз для iPad?
- 6. Как создать эскиз веб-сайта?
- 7. Создать эскиз документа Word
- 8. Создать эскиз в php
- 9. Создать эскиз документов PowerPoint
- 10. Как создать эскиз веб-страницы в Qt/QML для android
- 11. Создать эскиз с белой рамкой
- 12. Невозможно создать временную таблицу в Android SQLite
- 13. PHP - создать эскиз с url
- 14. Создать эскиз после загрузки, PHP
- 15. Как создать эскиз видео с помощью flowplayer?
- 16. Как создать прозрачный эскиз в symfony 1.4?
- 17. Как создать эскиз во время загрузки видео?
- 18. Как создать эскиз видео с помощью C#
- 19. Как создать эскиз в моем UIView?
- 20. .NET: Как создать эскиз со вспышки
- 21. Как создать эскиз из http-ответа?
- 22. Как создать эскиз из swf-игр?
- 23. Как создать временную метку города
- 24. Как загрузить эскиз изображения из sdcard android?
- 25. Как правильно завершить эскиз обработки в Android
- 26. Создать временную таблицу
- 27. Создать временную диаграмму Excel
- 28. PHP Создать временную метку
- 29. Создать эскиз для каждой страницы документа
- 30. Создать эскиз из файла Adobe Illustrator?
Мои файлы были большими, поэтому мне пришлось использовать sub-выборку в шаге 'BitmapFactory.decodeStream (fis);'. См. [Docs] (http://developer.android.com/reference/android/graphics/BitmapFactory.Options.html#inSampleSize) для более подробной информации о подэмплинге. – Diederik
Лучше использовать класс 'ThumbnailUils' для Android, как показано ниже. – afollestad
@afollestad Не совсем, этот подход правильный. Использование ThumbnailUtils - это только хорошая идея, если вы на 100% уверены, что работаете с небольшими файлами. – GuillermoMP