问题描述:

GLSurfaceView中通过纹理绘制图形,纹理长宽为2的幂次(128*64)。资源放在res/drawable文件夹下面。发现在hdpi手机上图形为白色,还有同事手机上是黑色。


初步判断

可能原因是纹理丢失。。导致绘制图形采用默认颜色绘制:白色或者黑色,结果随机。

为什么纹理丢失呢?我直接把问题归咎于奇葩的android,感觉hdpi手机优先搜索drawable-hdpi文件夹,并没有搜索drawable目录??


问题排查:

步骤1:通过图片资源上传gl前,将图片保存到磁盘。结果发现图片确实被搜索到。否定了之前的猜测。

步骤2:图片上传gl时,打log输出图片尺寸。结果惊人地发现hdpi手机上图片大小变为192*96。。看来是因为图片尺寸不是2的幂次导致纹理创建失败。真的有文章。

步骤3:于是我将尺寸为128*64的资源拷贝到res/drawable-hdpi下,再次运行程序。结果发现纹理创建成功,图形绘制正确,输出图像尺寸正确为128*64。

原因定位:为什么前后两种情况图像尺寸会变化呢?计算了一下,恰好长宽相差1.5倍,想起了android的多分辨率规则:3:4:6:8。 正常分辨率手机为1,ldpi手机需要缩小为0.75,hdpi手机需要拉伸到1.5,xhdpi手机需要拉伸到2.0。对Android这个自作多情地隐式操作真无语


结论:

正常情况下图片资源需要放在res/drawableres/drawable-ldpires/drawable-hdpires/drawable-xhdpi,且不同分辨率文件夹下都需要放置一份。对于适配gles1.0特意制作的大小为2的幂次的资源,为了防止android隐式缩放,尤其需要在不同分辨率文件夹下放置一份相同的拷贝。然后通过资源加载原始bitmap:

Bitmap mMarkerBmp = BitmapFactory.decodeResource(mapView.getResources(), R.drawable.bus_subway);

对于不希望被拉伸地资源,更好地方式直接放在assets目录下,通过文件方式加载资源:

    protected Bitmap readBitmapFromAssets(String filename) {        InputStream istr;        try {            istr = mapView.getContext().getAssets().open(filename);        } catch (IOException e) {            istr = null;            return null;        }        return BitmapFactory.decodeStream(istr);    }

想到了其他与本文无关的点,1.通过纹理坐标也可以DIY android 的9patch效果;2. png图像是LZW无损压缩算法,难怪android这么提倡使用png。


更多相关文章

  1. Android性能优化之路(二)
  2. Android中的资源
  3. Android(安卓)OpenGL 纹理绘制图像---总结
  4. Android中View绘图总结
  5. Android(安卓)Frame动画概述及示例
  6. Android(安卓)- 支持不同的设备 - 支持不同的屏幕
  7. android 性能测试 基础入门
  8. [置顶] android图形系统详解六:View layer
  9. Android中View的绘制

随机推荐

  1. 第3.1.3节 排布视图
  2. Android的px、dp、sp的区别
  3. 安卓图片反复压缩后为什么普遍会变绿而不
  4. [置顶] [Android(安卓)Studio 权威教程]配
  5. Android(安卓)添加白名单实现保活
  6. 从 0 开始,搭建一个完整的 Android(安卓)
  7. Android(安卓)native crash 日志分析
  8. Android(安卓)CheckBox 修改选择框
  9. 浅析Android(安卓)4.0的通知系统(附Androi
  10. Android(安卓)强弱指针分析