×

java bitmap java c

java bitmap(java中的Bitmap类型通过jni传进cpp后如何转换成IPLImage*类型呢谢谢!)

admin admin 发表于2022-09-07 14:18:58 浏览188 评论0

抢沙发发表评论

本文目录

java中的Bitmap类型通过jni传进cpp后如何转换成IPLImage*类型呢谢谢!


JNI 的基本问题就是解决 Java 和 C++ 代码互相调用的通信问题,在 C++ 代码编写过程中最大的问题莫过于适应其中的代码编写规则,C++调用或是返回的内容必须遵守 JVM 和 C++ 代码的通信规则。
C++ 调用 Java 的一般步骤如下:
获得类:
jclass cls = env-》FindClass(“com/ldq/Student“);
cls 可认为是类的句柄
“com/ldq/Student“ 就是类文件,注意不能用 “com.ldq.Student“
获得方法:
jmethodID mid = env-》GetMethodID(cls,“《init》“,“()V“);
以上为构造函数,参数是 “《init》“ “()V“
jmethodID mid = env-》GetMethodID(cls,“getAge“,“()I“);
以上为类的方法,第一个参数是类句柄,第二个参数是方法名字,第三个参数是签名标识
Java类型
符号
boolean Z
byte
B
char
C
short S
int I
long L
float F
double
D
void
V
objects对象 Lfully-qualified-class-name; L类名;
Arrays数组 [array-type [数组类型
methods方法 (argument-types)return-type(参数类型)返回类型
获得对象:
jobject obj=env-》NewObject(cls,mid);
以上便获得了一个对象的句柄
获得对象成员变量:
jfieldID fid=env-》GetFieldID(cls,“age“,“I“);
以上和获得类方法差不多
操作成员变量:
jint a=env-》GetIntField(obj,mid);
age=age+10;
env-》SetIntField(obj,fid,a);
返回:
return obj;
下面是本人练习的例子
ExList.java
Java代码
package com.ldq.list;

import java.util.List;

public class ExList {

/**
* @param args
*/
public static void main(String args) {
// TODO Auto-generated method stub
System.out.println(“-------WifiManager.test()“);
System.out.println(WifiManager.test());

System.out.println(“-------WifiManager.testArray()“);
String s1 = WifiManager.testArray();
for (int i = 0; i 《 s1.length; i++) {
System.out.println(s1[i]);
}

System.out.println(“-------WifiManager.testObject()“);
System.out.println(WifiManager.testObject().ssid);
System.out.println(WifiManager.testObject().mac);
System.out.println(WifiManager.testObject().level);

System.out.println(“-------WifiManager.getScanResultsA()“);
ScanResult s2 = WifiManager.getScanResultsA();
for (int i = 0; i 《 s2.length; i++) {
System.out.println(s2[i].ssid);
System.out.println(s2[i].mac);
System.out.println(s2[i].level);
}

System.out.println(“-------WifiManager.getScanResults()“);
List《ScanResult》 list = WifiManager.getScanResults();
System.out.println(list.get(0).ssid);
System.out.println(list.get(0).mac);
System.out.println(list.get(0).level);

}
}
package com.ldq.list;import java.util.List;public class ExList { /** * @param args */ public static void main(String args) { // TODO Auto-generated method stub System.out.println(“-------WifiManager.test()“); System.out.println(WifiManager.test()); System.out.println(“-------WifiManager.testArray()“); String s1 = WifiManager.testArray(); for (int i = 0; i 《 s1.length; i++) { System.out.println(s1[i]); } System.out.println(“-------WifiManager.testObject()“); System.out.println(WifiManager.testObject().ssid); System.out.println(WifiManager.testObject().mac); System.out.println(WifiManager.testObject().level); System.out.println(“-------WifiManager.getScanResultsA()“); ScanResult s2 = WifiManager.getScanResultsA(); for (int i = 0; i 《 s2.length; i++) { System.out.println(s2[i].ssid); System.out.println(s2[i].mac); System.out.println(s2[i].level); } System.out.println(“-------WifiManager.getScanResults()“); List《ScanResult》 list = WifiManager.getScanResults(); System.out.println(list.get(0).ssid); System.out.println(list.get(0).mac); System.out.println(list.get(0).level); }}

求教java中有没有类似android中的bitmap类



imageio
if(type == BufferedImage.TYPE_CUSTOM) {
ColorModel cm = source.getColorModel();
WritableRaster raster = cm.createCompatibleWritableRaster(CmsConfig.picWith, CmsConfig.picHeight);
boolean alphaPremultiplied = cm.isAlphaPremultiplied();
target = new BufferedImage(cm, raster, alphaPremultiplied, null);
} else {
target = new BufferedImage(CmsConfig.picWith, CmsConfig.picHeight, type);
Graphics2D g = target.createGraphics();
g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC);
g.drawRenderedImage(source, AffineTransform.getScaleInstance(sx, sy));
g.dispose();
}
ImageIO.write(target, formatName, file);

java Bitmap怎么转成BufferedImage呢


先用Bitmap对象的write(OutputStream)方法写到输出流,再从输出流读到输入流InputStream,再用ImageIO.read(InputStream);这样就可得到BufferedImage了,但这样太麻烦了,最简单的方式你就不生成Bitmap对象,直接以图片文件生成BufferedImage。
你看下ImageIO的read方法,看下怎么简单怎么做吧
-java

如何解决bitmap 内存溢出out of memory的问题


  很多人在android开发中都遇到了生成bitmap时候内存溢出,也就是out of memory(OOM)的问题,网上对这样的问题的的解决说法不一。笔者作为一个初级开发者,在这里向大家提供一种比较实用,比较易于理解的方法,这种方法不如一些高级开发者提出的方案来的深刻,但是也能帮助大家有效地解决问题。
  废话不多说了,直接上代码。
  Java代码
  BitmapFactory.Options opt = new BitmapFactory.Options();
  //这个isjustdecodebounds很重要
  opt.inJustDecodeBounds = true;
  bm = BitmapFactory.decodeFile(absolutePath, opt);
  
  //获取到这个图片的原始宽度和高度
  int picWidth = opt.outWidth;
  int picHeight = opt.outHeight;
  
  //获取屏的宽度和高度
  WindowManager windowManager = getWindowManager();
  Display display = windowManager.getDefaultDisplay();
  int screenWidth = display.getWidth();
  int screenHeight = display.getHeight();
  
  //isSampleSize是表示对图片的缩放程度,比如值为2图片的宽度和高度都变为以前的1/2
  opt.inSampleSize = 1;
  //根据屏的大小和图片大小计算出缩放比例
  if(picWidth 》 picHeight){
  if(picWidth 》 screenWidth)
  opt.inSampleSize = picWidth/screenWidth;
  }
  else{
  if(picHeight 》 screenHeight)
  
  opt.inSampleSize = picHeight/screenHeight;
  }
  
  //这次再真正地生成一个有像素的,经过缩放了的bitmap
  opt.inJustDecodeBounds = false;
  bm = BitmapFactory.decodeFile(absolutePath, opt);
  
  //用imageview显示出bitmap
  iv.setImageBitmap(bm);
  BitmapFactory.Options opt = new BitmapFactory.Options();
  //这个isjustdecodebounds很重要
  opt.inJustDecodeBounds = true;
  bm = BitmapFactory.decodeFile(absolutePath, opt);
  //获取到这个图片的原始宽度和高度
  int picWidth = opt.outWidth;
  int picHeight = opt.outHeight;
  //获取屏的宽度和高度
  WindowManager windowManager = getWindowManager();
  Display display = windowManager.getDefaultDisplay();
  int screenWidth = display.getWidth();
  int screenHeight = display.getHeight();
  //isSampleSize是表示对图片的缩放程度,比如值为2图片的宽度和高度都变为以前的1/2
  opt.inSampleSize = 1;
  //根据屏的大小和图片大小计算出缩放比例
  if(picWidth 》 picHeight){
  if(picWidth 》 screenWidth)
  opt.inSampleSize = picWidth/screenWidth;
  }
  else{
  if(picHeight 》 screenHeight)
  opt.inSampleSize = picHeight/screenHeight;
  }
  //这次再真正地生成一个有像素的,经过缩放了的bitmap
  opt.inJustDecodeBounds = false;
  bm = BitmapFactory.decodeFile(absolutePath, opt);
  //用imageview显示出bitmap
  iv.setImageBitmap(bm);
  inJustDecodeBounds 的介绍
  public boolean inJustDecodeBounds
  Since: API Level 1
  If set to true, the decoder will return null (no bitmap), but the out... fields will still be set, allowing the caller to query the bitmap without having to allocate the memory for its pixels.
  就是说,如果设置inJustDecodeBounds为true,仍可以获取到bitmap信息,但完全不用分配内存,因为没有获取像素,所以我们可以利用得到的Bitmap的大小,重新压缩图片,然后在内存中生成一个更小的Bitmap,这样即便是一个4MB的JPG,我们也可以随心所欲地把他压缩到任意大小,从而节省了内存,看到这里是不是恍然大悟,牛b了牛b了!
  下面这个参数就是跟压缩图片有关的部分,很容易懂,不多解释了:
  inSampleSize 的介绍
  public int inSampleSize
  Since: API Level 1
  If set to a value 》 1, requests the decoder to subsample the original image, returning a smaller image to save memory. The sample size is the number of pixels in either dimension that correspond to a single pixel in the decoded bitmap. For example, inSampleSize == 4 returns an image that is 1/4 the width/height of the original, and 1/16 the number of pixels. Any value
-c

JAVA int数组转bitmap问题


先看 int数组是什么值 。。。。。。
简单地,可以使用BufferedImage的
void
setRGB(int x,
int y,
int rgb)
Sets a pixel in this BufferedImage to the specified
RGB value.
-java

android 在Java代码中,我调用一个函数后返回Bitmap图,想将它设为背景,每次调用setbackground都出错


一般情况下,错误信息中都会含带错误出现的页面位置,比如多少行,那么就到你部署的程序的服务器中查看work下面编译成java代码以后的jsp页面。用记事本或者notepad++打开,定位到那一行,就可以确定是哪一句的问题。
可以在jsp页面中的服务器脚本中写System.out.println(“123“);看是否输出(此处的System.out.println(“123“)尽量多写几行,在你认为有可能发生错误的一段内也可以),逐渐缩小范围。
最后一种就是:空指针异常都是由于“对象点”引起的,这种写法的地方都值得怀疑一下,尤其是传值过来的。
-c

如何高效使用和管理Bitmap


一、图片加载流程 

        首先,我们谈谈加载图片的流程,项目中的该模块处理流程如下: 

1.在UI主线程中,从内存缓存中获取图片,找到后返回。找不到进入下一步; 

2.在工作线程中,从磁盘缓存中获取图片,找到即返回并更新内存缓存。找不到进入下一步; 

3.在工作线程中,从网络中获取图片,找到即返回并同时更新内存缓存和磁盘缓存。找不到显示默认以提示。 

二、内存缓存类(PanoMemCache)

        这里使用Android提供的LruCache类,该类保存一个强引用来限制内容数量,每当Item被访问的时候,此Item就会移动到队列的头部。当cache已满的时候加入新的item时,在队列尾部的item会被回收。-java

[java] view plain copy print ?

public class PanoMemoryCache {  

  

    // LinkedHashMap初始容量  

    private static final int INITIAL_CAPACITY = 16;  

    // LinkedHashMap加载因子  

    private static final int LOAD_FACTOR = 0.75f;  

    // LinkedHashMap排序模式  

    private static final boolean ACCESS_ORDER = true;  

  

    // 软引用缓存  

    private static LinkedHashMap《String, SoftReference《Bitmap》》 mSoftCache;  

    // 硬引用缓存  

    private static LruCache《String, Bitmap》 mLruCache;  

      

    public PanoMemoryCache() {  

    // 获取单个进程可用内存的最大值  

    // 方式一:使用ActivityManager服务(计量单位为M)  

        /*int memClass = ((ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE)).getMemoryClass();*/  -c

    // 方式二:使用Runtime类(计量单位为Byte)  

        final int memClass = (int) Runtime.getRuntime().maxMemory();  

        // 设置为可用内存的1/4(按Byte计算)  

        final int cacheSize = memClass / 4;  

        mLruCache = new LruCache《String, Bitmap》(cacheSize) {  

            @Override  

            protected int sizeOf(String key, Bitmap value) {  

                if(value != null) {  

                    // 计算存储bitmap所占用的字节数  

                    return value.getRowBytes() * value.getHeight();  

                } else {  

                    return 0;  

                }  

            }  

              

            @Override  

            protected void entryRemoved(boolean evicted, String key, Bitmap oldValue, Bitmap newValue) {  -java

                if(oldValue != null) {  

                    // 当硬引用缓存容量已满时,会使用LRU算法将最近没有被使用的图片转入软引用缓存  

                    mSoftCache.put(key, new SoftReference《Bitmap》(oldValue));  

                }  

            }  

        };  

          

    /* 

    * 第一个参数:初始容量(默认16) 

    * 第二个参数:加载因子(默认0.75) 

    * 第三个参数:排序模式(true:按访问次数排序;false:按插入顺序排序) 

    */  

        mSoftCache = new LinkedHashMap《String, SoftReference《Bitmap》》(INITIAL_CAPACITY, LOAD_FACTOR, ACCESS_ORDER) {  -c

            private static final long serialVersionUID = 7237325113220820312L;  

            @Override  

            protected boolean removeEldestEntry(Entry《String, SoftReference《Bitmap》》 eldest) {  

                if(size() 》 SOFT_CACHE_SIZE) {  

                    return true;  

                }  

                return false;  

            }  

        };  

    }  

      

    /** 

     * 从缓存中获取Bitmap 

     * @param url 

     * @return bitmap 

     */  

    public Bitmap getBitmapFromMem(String url) {  

        Bitmap bitmap = null;  

        // 先从硬引用缓存中获取  

        synchronized (mLruCache) {  

            bitmap = mLruCache.get(url);  

            if(bitmap != null) {  

                // 找到该Bitmap之后,将其移到LinkedHashMap的最前面,保证它在LRU算法中将被最后删除。  

                mLruCache.remove(url);  

                mLruCache.put(url, bitmap);  

                return bitmap;  

            }  

        }  

  

  

        // 再从软引用缓存中获取  

        synchronized (mSoftCache) {  

            SoftReference《Bitmap》 bitmapReference = mSoftCache.get(url);  

            if(bitmapReference != null) {  

                bitmap = bitmapReference.get();  

                if(bitmap != null) {  

                    // 找到该Bitmap之后,将它移到硬引用缓存。并从软引用缓存中删除。  

                    mLruCache.put(url, bitmap);  

                    mSoftCache.remove(url);  

                    return bitmap;  

                } else {  

                    mSoftCache.remove(url);  

                }  

            }  

        }  

        return null;  

    }  

      

    /** 

     * 添加Bitmap到内存缓存 

     * @param url 

     * @param bitmap 

     */  

    public void addBitmapToCache(String url, Bitmap bitmap) {  

        if(bitmap != null) {  

            synchronized (mLruCache) {  

              mLruCache.put(url, bitmap);    

            }  

        }  

    }  

      

    /** 

     * 清理软引用缓存 

     */  

    public void clearCache() {  

        mSoftCache.clear();  

    mSoftCache = null;  

    }  

}  

        补充一点,由于4.0平台以后对SoftReference类引用的对象调整了回收策略,所以该类中的软引用缓存实际上没什么效果,可以去掉。2.3以前平台建议保留。 

三、磁盘缓存类(PanoDiskCache) 

 

五、使用decodeByteArray()还是decodeStream()? 

        讲到这里,有童鞋可能会问我为什么使用BitmapFactory.decodeByteArray(data, 0, data.length, opts)来创建Bitmap,而非使用BitmapFactory.decodeStream(is, null, opts)。你这样做不是要多写一个静态方法readInputStream()吗? -java

        没错,decodeStream()确实是该使用情景下的首选方法,但是在有些情形下,它会导致图片资源不能即时获取,或者说图片被它偷偷地缓存起来,交 还给我们的时间有点长。但是延迟性是致命的,我们等不起。所以在这里选用decodeByteArray()获取,它直接从字节数组中获取,贴近于底层 IO、脱离平台限制、使用起来风险更小。 -c

六、引入缓存机制后获取图片的方法 

[java] view plain copy print ?

/** 

     * 加载Bitmap 

     * @param url 

     * @return  

     */  

    private Bitmap loadBitmap(String url) {  

        // 从内存缓存中获取,推荐在主UI线程中进行  

        Bitmap bitmap = memCache.getBitmapFromMem(url);  

        if(bitmap == null) {  

            // 从文件缓存中获取,推荐在工作线程中进行  

            bitmap = diskCache.getBitmapFromDisk(url);  

            if(bitmap == null) {  

                // 从网络上获取,不用推荐了吧,地球人都知道~_~  

                bitmap = PanoUtils.downloadBitmap(this, url);  

                if(bitmap != null) {  

                    diskCache.addBitmapToCache(bitmap, url);  

                    memCache.addBitmapToCache(url, bitmap);  

                }  

            } else {  

                memCache.addBitmapToCache(url, bitmap);  

            }  

        }  

        return bitmap;  

    }  

七、工作线程池化 

        有关多线程的切换问题以及在UI线程中执行loadBitmap()方法无效的问题,请参见另一篇博文: 使用严苛模式打破Android4.0以上平台应用中UI主线程的“独断专行”。 

有关工作线程的处理方式,这里推荐使用定制线程池的方式,核心代码如下: 

[java] view plain copy print ?

// 线程池初始容量  

private static final int POOL_SIZE = 4;  

private ExecutorService executorService;  

@Override  

public void onCreate(Bundle savedInstanceState) {  

    super.onCreate(savedInstanceState);  

  

    // 获取当前使用设备的CPU个数  

    int cpuNums = Runtime.getRuntime().availableProcessors();  

    // 预开启线程池数目  

    executorService = Executors.newFixedThreadPool(cpuNums * POOL_SIZE);  

  

    ...  

    executorService.submit(new Runnable() {  

        // 此处执行一些耗时工作,不要涉及UI工作。如果遇到,直接转交UI主线程  

        pano.setImage(loadBitmap(url));  

    });  

    ...  

  

}  

        我们知道,线程构造也是比较耗资源的。一定要对其进行有效的管理和维护。千万不要随意而行,一张图片的工作线程不搭理也许没什么,当使用场景变为 ListView和GridView时,线程池化工作就显得尤为重要了。Android不是提供了AsyncTask吗?为什么不用它?其实 AsyncTask底层也是靠线程池支持的,它默认分配的线程数是128,是远大于我们定制的executorService。-java


java中getBitmap()什么意思


给你个连接自己看看http://resources.esri.com/help/9.3/arcgisengine/java/api/arcobjects/com/esri/arcgis/controls/ControlsGlobeLayerListToolControl.html#getBitmap()
下面是详细信息:
public int getBitmap()
throws IOException,
AutomationExceptionThe bitmap that is used as the icon on this command.
Remarks
When implementing ICommand to create a custom command, use the Bitmap property to set the bitmap to be used as the icon on this command. In your Visual Basic project for this command, the bitmap can be stored in a resource file or in a PictureBox control on a form.
You must use a Bitmap file (.bmp) for the Bitmap property; Icon files (.ico) are not supported. Bitmap files should be 16 X 16 pixels. The color of the upper left pixel of the bitmap is treated as the transparent color. For example, if the upper left pixel of the bitmap is red, then all of the red pixels in the bitmap will be converted to transparent.
When a command is put on a toolbar, the command is displayed with the bitmap only by default; the display type is set to Image Only (ICommandItem::Style = esriCommandStyleIconOnly). When a command is put on a menu, the command is displayed with the bitmap and caption by default; the display type is set to Image and Text (ICommandItem::Style = esriCommandStyleIconAndText). However, if the Bitmap property is not set for this command, then the command will be displayed with the caption only by default when it is put on a toolbar or menu; the display type is set to Text Only (ICommandItem::Style = esriCommandStyleTextOnly).
Product Availability
Available with ArcGIS Engine, ArcGIS Desktop, and ArcGIS Server.
Supported Platforms
Windows, Solaris, Linux
When implementing ICommand to create a custom command, there is no need to implement this method. In the custom Java Command class, set the bitmapPath String to the physical location of the bitmap file to be used on the toolbar.
bitmapPath = “/images/mybitmap.bmp“;You must use a Bitmap file (.bmp); Icon files (.ico) are not supported. Bitmap files should be 16 X 16 pixels. The color of the upper left pixel of the bitmap is treated as the transparent color. For example, if the upper left pixel of the bitmap is red, then all of the red pixels in the bitmap will be converted to transparent.
When a command is put on a toolbar, the command is displayed with the bitmap only by default; the display type is set to Image Only (esriCommandStyles.esriCommandStyleIconOnly). When a command is put on a menu, the command is displayed with the bitmap and caption by default; the display type is set to Image and Text (esriCommandStyles.esriCommandStyleIconAndText). However, if the Bitmap property is not set for this command, then the command will be displayed with the caption only by default when it is put on a toolbar or menu; the display type is set to Text Only (esriCommandStyles.esriCommandStyleTextOnly).
Specified by:
getBitmap in interface ICommand
Returns:
The bitmap (A COM typedef)
Throws:
IOException - If there are interop problems.
AutomationException - If the ArcObject component throws an exception.
-c

Bitmap 究竟占多大内存


最近在做一款塔防游戏,用的事surfaceview框架,由于图片过多,而且游戏过程中都需要这些图片,所以加载成bitmap后造成OOM(outofmemory)异常。下面是我一步一步找解决此问题的纪录,再此分享,希望对以后出现此问题的开发者有所帮助。第一:出现问题,我的测试手机是2。2android操作系统,不会出现oom问题,但是在老板的android4.2上却出现了问题,因为是oom,所以我首先想到的是手动改变手机的内存大小限制。网上有些帖子说可以通过函数设置应用的HEAPSIZE来解决这个问题,其实是不对的。VMRuntime.getRuntime().setMinimumHeapSize(NewSize);堆(HEAP)是VM中占用内存最多的部分,通常是动态分配的。堆的大小不是一成不变的,通常有一个分配机制来控制它的大小。比如初始的HEAP是4M大,当4M的空间被占用超过75%的时候,重新分配堆为8M大;当8M被占用超过75%,分配堆为16M大。倒过来,当16M的堆利用不足30%的时候,缩减它的大小为8M大。重新设置堆的大小,尤其是压缩,一般会涉及到内存的拷贝,所以变更堆的大小对效率有不良影响。MaxHeapSize,是堆内存的上限值,Android的缺省值是16M(某些机型是24M),对于普通应用这是不能改的。函数setMinimumHeapSize其实只是改变了堆的下限值,它可以防止过于频繁的堆内存分配,当设置最小堆内存大小超过上限值时仍然采用堆的上限值,对于内存不足没什么作用。setTargetHeapUtilization(floatnewTarget)可以设定内存利用率的百分比,当实际的利用率偏离这个百分比的时候,虚拟机会在GC的时候调整堆内存大小,让实际占用率向个百分比靠拢。在手机上进行了多次测试,确实不好使,在此,我断了改变内存限制的方法。第二:查找出现问题的原因。1,在网上搜索bitmap内存溢出,找到很多说是因为图片大小引起的此问题。观察我的资源文件,没有太大的图片,只是图片数量过多,有将近900张,分别找出一张最大的图片和几张比较大的图片,单独测试,没有发现问题。方法1排除。2,既然图片数量过多,突破点可能就是图片数量问题。于是分别找了200,400,600图片进行测试,在500左右的时候遇到错误,通过宝哥知道了将小图片整合存放到一张大图的方法,以此来减少图片的数量,但是仔细想想,加载成bitmap的时候还是要切割成小图生成bitmap,所以对此方法表示怀疑。由于以前没用过此方法,试试也无妨。所用到的工具是gdx—texturepackger,它只是一个工具,这里就不多说了。测试的最终结果是还是oom。方法2排除。3,现在看来,既然不是图片数量的问题,而且会在500张左右的时候报错,那就可能是占用内存大小的问题了,Android手机有内存限制,但是我的图片大小又大于这个限制,这让我头疼了很长时间,研究国外的一些文章,从中发现了一些有用的信息,这些信息能够加深你对Android的解析bitmap机制的理解,在此分享:AsofHoneycombBitmapdataisallocatedintheVMheap.作为蜂窝位图数据是在VM分配堆。)ThereisareferencetoitintheVMheap(whichissmall),buttheactualdataisallocatedintheNativeheapbytheunderlyingSkiagraphicslibrary.有一个引用在VM堆(小),但实际的数据是在本机堆分配由底层Skia图形库。Unfortunately,whilethedefinitionofBitmapFactory.decode…()saysthatitreturnsnulliftheimagedatacouldnotbedecoded,theSkiaimplementation(orrathertheJNIgluebetweentheJavacodeandSkia)logsthemessageyou’reseeing(“VMwon’tletusallocatexxxxbytes”)andthenthrowsanOutOfMemoryexceptionwiththemisleadingmessage“bitmapsizeexceedsVMbudget”.不幸的是,虽然BitmapFactory.decode的定义…()表示,它返回null如果图像数据不能解码,Skia实现(或者说JNI胶之间的Java代码和Skia)日志消息你看到(“VM不会让我们分配xxxx字节”),然后抛出一个OutOfMemory异常与误导信息”位图的大小超过VM预算”。TheissueisnotintheVMheapbutisratherintheNativeheap.这个问题不是在VM堆而是在本机堆。TheNatïveheapissharedbetweenrunningapplications,sotheamountoffreespacedependsonwhatotherapplicationsarerunningandtheirbitmapusage.本机堆是正在运行的应用程序之间共享,因此空闲空间的大小取决于其他运行程序,他们使用的位图。However,IhavefoundthatgetNativeHeapFreeSize()andgetNativeHeapSize()arenotreliable.然而,我发现getNativeHeapFreeSize()和getNativeHeapSize()是不可靠的。TheNativeheapsizevariesbyplatform.本机堆大小不同的平台。Soatstartup,wecheckthemaximumallowedVMheapsizetodeterminethemaximumallowedNativeheapsize.所以在启动时,我们检查最大允许VM堆大小来确定最大允许本机堆大小。“BitmapdataisnotallocatedintheVMheap”—itisallocatedontheVMheapasofHoneycomb“位图数据不是在VM分配堆”——这是VM分配的堆在蜂窝Yes.是的。AsofHoneycomb(v3.0),bitmapdataisallocatedontheVMheap.作为蜂窝(v3.0),位图数据堆上分配VM。SoalloftheaboveonlyappliestoGingerbread(v2.3.x)andbefore所以所有上述只适用于姜饼(v23x)和之前这些信息零零散散,但是不难发现,问题的原因就在于根据Android版本的不同,bitmapdata存放的位置是不同的,3.0以前是分配在nativeheap上,3.0以后是分配在VMheap上。
-java

Drawable和Bitmap的区别


一个Bitmap对象是一张bitmap格式image的表示(类似于Java.awt.image)。一个Drawable对象是“那些能够在其上面图画的任意对象”,它也许是一个bitmap对象,也可能是一个solid color、一个其他Drawable对象的集合,亦或是某种结构。 大多数Android UI框架喜欢用Drawable对象,而不是Bitmap对象。一个View可以接受任何Drawable对象作为background,一个Imageview可以显示Drawable前景对象;作为资源的Images一般加载为Drawable对象。
-c