ImageView的子类无法加载图片
在图片预览时,偶现图片无法现实,在查看程序的时候发现Bitmap是实际存在的,但是在ImageView中缺绘制不出来,这个问题困然了我很久,查看代码也查不出原因,再加上是偶现的,查原因时费了不少时间。
先来看看异常:
10-14 09:53:34.902 9003-10023/? W/OpenGLRenderer﹕ Bitmap too large to be uploaded into a texture (1024x9297, max=8192x8192)
10-14 09:53:34.902 9003-10023/? W/OpenGLRenderer﹕ Shape too large to be rendered into a texture (940x8510, max=8192x8192)
10-14 09:53:34.917 9003-10023/? W/OpenGLRenderer﹕ Bitmap too large to be uploaded into a texture (1024x9297, max=8192x8192)
10-14 09:53:34.919 9003-10023/? W/OpenGLRenderer﹕ Bitmap too large to be uploaded into a texture (1024x9297, max=8192x8192)
10-14 09:53:34.919 9003-10023/? W/OpenGLRenderer﹕ Bitmap too large to be uploaded into a texture (1024x9297, max=8192x8192)
其实是因为图片过长的原因,图片可以绘制的最大高度为8192,而我的图片高度为9297,在Canvas绘制时,OpenGL无法绘制出来,所以导致在预览长图时无法显示出来。
修改方式:
1.在异步加载图片时,判断图片的宽高,如果高度超出了底层OpenGL绘制的高度,那就把图片缩小。代码如下:
 public void loadImage(final MediaItem mediaItem) {
         if (mBitmap == null && !mDestoryDecodeThread && !mDestory) {
             mHardWareDecodeFuture = ThreadPool.getInstance().submit(new ThreadPool.Job<Bitmap>() {
                 @Override
                 public Bitmap run(ThreadPool.JobContext jc) {
                     boolean rotated = ((mediaItem.getRotation() / 90) & 1) == 1;
                     int photoWidth = rotated ? mediaItem.getHeight() : mediaItem.getWidth();
                     int photoHeight = rotated ? mediaItem.getWidth() : mediaItem.getHeight();
                     final BitmapFactory.Options options = new BitmapFactory.Options();
                     jc.setCancelListener(new ThreadPool.CancelListener() {
                         @Override
                         public void onCancel() {
                             options.requestCancelDecode();
                         }
                     });
                     InputStream is = null;
                     try {
                         Bitmap bitmap = null;
                         Uri uri = mediaItem.getContentUri();
                         int sampleSize = 1;
                         if (photoHeight > mHeight || photoWidth > mWidth) {
                             final int heightRatio = (int) Math.floor((float) photoHeight / (float) mHeight);
                             final int widthRatio = (int) Math.floor((float) photoWidth / (float) mWidth);
                             sampleSize = heightRatio > widthRatio ? heightRatio : widthRatio;
                         }
                         options.inSampleSize = sampleSize;
                         if (bitmap != null) {
                             options.inBitmap = bitmap;
                         }
                         if (uri.toString().startsWith("file://")) {
                             bitmap = BitmapFactory.decodeFile(uri.toString().substring("file://".length(), uri.toString().length()), options);
                         } else {
                             is = getContext().getContentResolver().openInputStream(uri);
                             bitmap = BitmapFactory.decodeStream(is, null, options);
                         }
                         /*重点缩小图片大小的代码*/
                         int maxHeight = EglUtil.getMaxTextureSize(getContext());
                         if (bitmap.getHeight() > maxHeight) {
                             int w = bitmap.getWidth();
                             int h = bitmap.getHeight();
                             while (h > maxHeight) {
                                 w = w / 2;
                                 h = h / 2;
                             }
                             Bitmap b = Bitmap.createScaledBitmap(bitmap, w, h, true);
                             bitmap.recycle();
                             bitmap = b;
                         }
                         /**/
                         if (jc.isCancelled() || mDestory || mDestoryDecodeThread) {
                             WeakReference<Bitmap> ref = new WeakReference<Bitmap>(bitmap);
                             return null;
                         }
                         return bitmap;
                     } catch (Exception ex) {
                     } finally {
                         MediaItem.closeSilently(is);
                     }
                     return null;
                 }
             }, new FutureListener<Bitmap>() {
                 @Override
                 public void onFutureDone(final Future<Bitmap> future) {
                     if (future != null && future.get() != null) {
                         post(new Runnable() {
                             @Override
                             public void run() {
                                 mBitmap = future.get();
                                 if (!mStopDrawBigBmp && !mDestoryDecodeThread && !mDestory) {
                                     mScreenNailLoaded = true;
                                     initBitmapRect();
                                     invalidate();
                                 } else {
                                     if (mBitmap != null && !mBitmap.isRecycled()) {
                                         mBitmap.recycle();
                                     }
                                 }
                             }
                         });
                     }
                 }
             });
         }
     }
2.判断图片是否超过绘制的最高高度。没一台手机,可绘制的最大高度是有可能不一样的,在Android5.0以上的版本中可以获取绘制的最大高度值,代码如下:
 public static int getMaxTextureSize(Context context){
         if(maxTextureSize != -1){
             return maxTextureSize;
         }
         maxTextureSize = 0;
         int[] maxSize = new int[1];
         try {
             ConfigurationInfo configurationInfo = ((ActivityManager)context.getSystemService(Context.ACTIVITY_SERVICE)).getDeviceConfigurationInfo();
             int glesVersion = configurationInfo.reqGlEsVersion;
             if(Build.VERSION.SDK_INT >= 21) {
                 //configureEGLContext
                 EGLDisplay mEGLDisplay = EGL14.eglGetDisplay(EGL14.EGL_DEFAULT_DISPLAY);
                 if (mEGLDisplay == EGL14.EGL_NO_DISPLAY) {
                     throw new IllegalStateException("No EGL14 display");
                 }
                 int[] version = new int[2];
                 if (!EGL14.eglInitialize(mEGLDisplay, version, /*offset*/ 0, version, /*offset*/ 1)) {
                     throw new IllegalStateException("Cannot initialize EGL14");
                 }
                 int[] attribList = {
                         EGL14.EGL_RED_SIZE, 8,
                         EGL14.EGL_GREEN_SIZE, 8,
                         EGL14.EGL_BLUE_SIZE, 8,
                         EGL14.EGL_RENDERABLE_TYPE, EGL14.EGL_OPENGL_ES2_BIT,
                         //EGL_RECORDABLE_ANDROID, 1,
                         EGL14.EGL_SURFACE_TYPE, EGL14.EGL_PBUFFER_BIT | EGL14.EGL_WINDOW_BIT,
                         EGL14.EGL_NONE
                 };
                 EGLConfig[] configs = new EGLConfig[1];
                 int[] numConfigs = new int[1];
                 EGL14.eglChooseConfig(mEGLDisplay, attribList, /*offset*/ 0, configs, /*offset*/ 0,
                         configs.length, numConfigs, /*offset*/ 0);
                 if (EGL14.eglGetError() != EGL14.EGL_SUCCESS) {
                     throw new IllegalStateException("eglCreateContext RGB888+recordable ES2" + ": EGL error: 0x" + Integer.toHexString(EGL14.eglGetError()));
                 }
                 int[] attrib_list = {
                         EGL14.EGL_CONTEXT_CLIENT_VERSION, 2,
                         EGL14.EGL_NONE
                 };
                 EGLContext mEGLContext = EGL14.eglCreateContext(mEGLDisplay, configs[0], EGL14.EGL_NO_CONTEXT,
                         attrib_list, /*offset*/ 0);
                 if (EGL14.eglGetError() != EGL14.EGL_SUCCESS) {
                     throw new IllegalStateException("eglCreateContext" + ": EGL error: 0x" + Integer.toHexString(EGL14.eglGetError()));
                 }
                 if (mEGLContext == EGL14.EGL_NO_CONTEXT) {
                     throw new IllegalStateException("No EGLContext could be made");
                 }
                 int[] surfaceAttribs = {
                         EGL14.EGL_WIDTH, 64,
                         EGL14.EGL_HEIGHT, 64,
                         EGL14.EGL_NONE
                 };
                 EGLSurface surface = EGL14.eglCreatePbufferSurface(mEGLDisplay, configs[0], surfaceAttribs, 0);
                 EGL14.eglMakeCurrent(mEGLDisplay, surface, surface, mEGLContext);
                 //getMaxTextureSize
                 if(glesVersion >= 0x20000) {
                     GLES20.glGetIntegerv(GLES20.GL_MAX_TEXTURE_SIZE, maxSize, 0);
                 }else if(glesVersion >= 0x10000) {
                     GLES10.glGetIntegerv(GLES10.GL_MAX_TEXTURE_SIZE, maxSize, 0);
                 }
                 //releaseEGLContext
                 EGL14.eglMakeCurrent(mEGLDisplay, EGL14.EGL_NO_SURFACE, EGL14.EGL_NO_SURFACE, EGL14.EGL_NO_CONTEXT);
                 EGL14.eglDestroyContext(mEGLDisplay, mEGLContext);
                 EGL14.eglReleaseThread();
                 EGL14.eglTerminate(mEGLDisplay);
             }else {
                 if(glesVersion >= 0x20000) {
                     GLES20.glGetIntegerv(GLES20.GL_MAX_TEXTURE_SIZE, maxSize, 0);
                 }else if(glesVersion >= 0x10000) {
                     GLES10.glGetIntegerv(GLES10.GL_MAX_TEXTURE_SIZE, maxSize, 0);
                 }
             }
         } catch (IllegalStateException e) {
             e.printStackTrace();
         }
         maxTextureSize = maxSize[0] > 0 ? maxSize[0] : DEFAULT_MAX_BITMAP_DIMENSION;
         return maxTextureSize;
     }
注意:以上获取最大高度值是在android5.0以上的版本才行。android5.0以下的版本使用:
private static final int DEFAULT_MAX_BITMAP_DIMENSION = 8196;
这样就能保证不管图片有多长,都能显示出来了。
ImageView的子类无法加载图片的更多相关文章
- Android Studio [ImageView/使用第三方库加载图片]
		ImageViewActivity.class package com.xdw.a122; import android.support.v7.app.AppCompatActivity; impor ... 
- [Android]异步加载图片,内存缓存,文件缓存,imageview显示图片时增加淡入淡出动画
		以下内容为原创,欢迎转载,转载请注明 来自天天博客:http://www.cnblogs.com/tiantianbyconan/p/3574131.html 这个可以实现ImageView异步加载 ... 
- android 网络加载图片,对图片资源进行优化,并且实现内存双缓存 + 磁盘缓存
		经常会用到 网络文件 比如查看大图片数据 资源优化的问题,当然用开源的项目 Android-Universal-Image-Loader 或者 ignition 都是个很好的选择. 在这里把原来 ... 
- ImageLoader加载图片
		先导universal-image-loader-1.9.3包 在application配置 android:name=".MyApplication" intent权限 1 pa ... 
- Glide 加载图片
		//通过model获取到图片的url,将Url转换成bitmap对象: //设置不保存内存和硬盘缓存, 1 Glide.with(mContext).load(model.getVideoUrl()) ... 
- 实例演示Android异步加载图片
		本文给大家演示异步加载图片的分析过程.让大家了解异步加载图片的好处,以及如何更新UI.首先给出main.xml布局文件:简单来说就是 LinearLayout 布局,其下放了2个TextView和5个 ... 
- 实例演示Android异步加载图片(转)
		本文给大家演示异步加载图片的分析过程.让大家了解异步加载图片的好处,以及如何更新UI.首先给出main.xml布局文件:简单来说就是 LinearLayout 布局,其下放了2个TextView和5个 ... 
- android listview 异步加载图片并防止错位
		网上找了一张图, listview 异步加载图片之所以错位的根本原因是重用了 convertView 且有异步操作. 如果不重用 convertView 不会出现错位现象, 重用 convertVie ... 
- ListView异步加载图片,完美实现图文混排
		昨天参加一个面试,面试官让当场写一个类似于新闻列表的页面,文本数据和图片都从网络上获取,想起我还没写过ListView异步加载图片并实现图文混排效果的文章,so,今天就来写一下,介绍一下经验. Lis ... 
随机推荐
- Android-获取外置SDcard路径
			Android手机支持SDcard.目前很多手机厂商把SDcard集成到手机中,当然有的手机同时也支持可插拔的SDcard.这就有了内置SDcard和位置SDcard之分.当手机同时支持内置和外置SD ... 
- HTMLTestRunner 自动化测试报告
			http://tungwaiyip.info/software/HTMLTestRunner.html下载,将下载后的文件放在python的Lib目录下 # -*- coding:utf-8 -*- ... 
- devi into python 笔记(一)字典 列表的简单操作
			模块: python中模块是很重要的概念,在模块中加入 if __name__ == "__main__": pass 会使模块应用起来更加灵活,避免出错. =========== ... 
- 门面模式 到 socket
			http://www.cnblogs.com/java-my-life/archive/2012/05/02/2478101.html 1.门面模式定义: 门面模式是对象的结构模式,外部与一个子系统的 ... 
- 批量导入图片到word并添加文件名
			Sub InsertPic() Dim myfile As FileDialog Set myfile = Application.FileDialog(msoFileDialogFilePicker ... 
- Java多线程内存模型
			Java虚拟机规范中试图定义一种Java内存模型(Java Memory Model,JMM)来屏蔽掉各种硬件和操作系统的内存访问差异,以实现让Java程序在各种平台下都能达到一致的并发效果.在此之前 ... 
- Windows和Ubuntu双系统,修复UEFI引导的两种办法
			查看ubuntu是否是从 efi/uefi 启动的方法: 若 /sys/firmware/efi 存在则是,否则不是.shell命令: [ -d /sys/firmware/efi ] && ... 
- Android studio开发常用快捷键
			最常用快捷键 1.Ctrl+E 可以显示最近编辑的文件列表 2.Shift+Click(点击) 可以关闭文件 3.Ctrl+[或者ctrl+] 可以跳到大括号的开头结尾 4.Ctrl+Shift ... 
- mvc Html.BeginForm 生成 ?Length=
			今天再做mvc Html.BeginForm的方法的时候发现提交的时候都会带length= ,后面查看网上文档资料是后台model设置最小长度生成的 改成 @using (Html.BeginFor ... 
- 推荐一个可视化的学习Git的好网站:LearnGitBranching
			博客搬到了fresky.github.io - Dawei XU,请各位看官挪步.最新的一篇是:推荐一个可视化的学习Git的好网站:LearnGitBranching. 
