Android: максимальная разрешенная ширина и высота растрового изображения

Im создает приложение, которое должно декодировать большие изображения в растровые изображения, которые будут отображаться в ImageView.

Если я просто попытаюсь их декодировать прямо в bitmap, я получаю следующую ошибку: «Растровое изображение слишком велико для загрузки в текстуру (1944×2592, max = 2048×2048)»

Таким образом, чтобы показывать изображения с высоким разрешением, используя:

Bitmap bitmap = BitmapFactory.decodeFile(path); if(bitmap.getHeight()>=2048||bitmap.getWidth()>=2048){ DisplayMetrics metrics = new DisplayMetrics(); getWindowManager().getDefaultDisplay().getMetrics(metrics); int width = metrics.widthPixels; int height = metrics.heightPixels; bitmap =Bitmap.createScaledBitmap(bitmap, width, height, true); } 

Это работает, но я действительно не хочу, чтобы hardcode максимальное значение 2048, как и в if-statement, но я не могу узнать, как получить максимально допустимый размер растрового изображения для устройства

Есть идеи?

Этот предел должен исходить из базовой реализации OpenGL. Если вы уже используете OpenGL в своем приложении, вы можете использовать что-то вроде этого, чтобы получить максимальный размер:

 int[] maxSize = new int[1]; gl.glGetIntegerv(GL10.GL_MAX_TEXTURE_SIZE, maxSize, 0); // maxSize[0] now contains max size(in both dimensions) 

Это показывает, что мои оба Galaxy Nexus и Galaxy S2 имеют максимум 2048×2048.

К сожалению, если вы еще не используете его, единственный способ получить контекст OpenGL, чтобы вызвать это, – это создать его (в том числе viewview и т. Д.), Что является большим количеством накладных расходов, чтобы запросить максимальный размер.

Другим способом получения максимального разрешенного размера было бы перебрать все конфигурации EGL10 и отслеживать наибольший размер.

 public static int getMaxTextureSize() { // Safe minimum default size final int IMAGE_MAX_BITMAP_DIMENSION = 2048; // Get EGL Display EGL10 egl = (EGL10) EGLContext.getEGL(); EGLDisplay display = egl.eglGetDisplay(EGL10.EGL_DEFAULT_DISPLAY); // Initialise int[] version = new int[2]; egl.eglInitialize(display, version); // Query total number of configurations int[] totalConfigurations = new int[1]; egl.eglGetConfigs(display, null, 0, totalConfigurations); // Query actual list configurations EGLConfig[] configurationsList = new EGLConfig[totalConfigurations[0]]; egl.eglGetConfigs(display, configurationsList, totalConfigurations[0], totalConfigurations); int[] textureSize = new int[1]; int maximumTextureSize = 0; // Iterate through all the configurations to located the maximum texture size for (int i = 0; i < totalConfigurations[0]; i++) { // Only need to check for width since opengl textures are always squared egl.eglGetConfigAttrib(display, configurationsList[i], EGL10.EGL_MAX_PBUFFER_WIDTH, textureSize); // Keep track of the maximum texture size if (maximumTextureSize < textureSize[0]) maximumTextureSize = textureSize[0]; } // Release egl.eglTerminate(display); // Return largest texture size found, or default return Math.max(maximumTextureSize, IMAGE_MAX_BITMAP_DIMENSION); } 

Из моего тестирования это довольно надёжно и не требует создания экземпляра. По производительности, это заняло 18 миллисекунд, чтобы выполнить на моей заметке 2 и только 4 миллисекунды на моем G3.

это будет декодировать и масштабировать изображение перед загрузкой в ​​память, просто измените пейзаж и портрет на нужный размер

 BitmapFactory.Options options = new BitmapFactory.Options(); options.inJustDecodeBounds = true; BitmapFactory.decodeFile(path, options); int imageHeight = options.outHeight; int imageWidth = options.outWidth; String imageType = options.outMimeType; if(imageWidth > imageHeight) { options.inSampleSize = calculateInSampleSize(options,512,256);//if landscape } else{ options.inSampleSize = calculateInSampleSize(options,256,512);//if portrait } options.inJustDecodeBounds = false; bitmap = BitmapFactory.decodeFile(path,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) { // Calculate ratios of height and width to requested height and width final int heightRatio = Math.round((float) height / (float) reqHeight); final int widthRatio = Math.round((float) width / (float) reqWidth); // Choose the smallest ratio as inSampleSize value, this will guarantee // a final image with both dimensions larger than or equal to the // requested height and width. inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio; } return inSampleSize; } 

Если вы используете API уровня 14+ (ICS), вы можете использовать функции getMaximumBitmapWidth и getMaximumBitmapHeight в classе Canvas . Это будет работать как на аппаратных, так и на программных уровнях.

Я считаю, что аппаратное обеспечение Android должно хотя бы поддерживать 2048×2048, так что это будет безопасное минимальное значение. На слоях программного обеспечения максимальный размер составляет 32766×32766.

Предел 2048 * 2048 предназначен для GN. GN является устройством xhdpi и, возможно, вы помещаете изображение в неправильный ковш плотности. Я переместил изображение 720 * 1280 от drawable to drawable-xhdpi, и оно сработало.

Спасибо за ответ Ромен Гай. Вот ссылка его ответа.

  • Масштабированный битмап, поддерживающий соотношение сторон
  • почему мой метод сравнения исключает исключение - метод сравнения нарушает общий контракт!
  • Android конвертирует дату и время в миллисекунды
  • android: выключить экран, когда он близок к лицу
  • Как я могу избежать задержек сбора мусора в Java-играх? (Лучшие практики)
  • Android ListView текущее местоположение прокрутки Y пикселей
  • Android «высота» не показывает тень
  • В андроидном приложении Toolbar.setTitle метод не действует - имя приложения отображается как заголовок
  • Android: Как получить уровень сигнала GSM для всех доступных сетевых операторов
  • AVD - PANIC: Не удалось открыть ... - не проблема
  • Android: Как сделать все элементы внутри LinearLayout того же размера?
  • Давайте будем гением компьютера.