Android 从源码分析Bitmap和BitmapFactory常用API
来源:互联网 发布:鲍尔州立大学 知乎 编辑:程序博客网 时间:2024/06/14 01:36
Bitmap
recycle()
调用nativeRecycle()释放该bitmap分配的native对象,清除对像素数据的引用。不会同步的释放像素数据,只是简单的允许bitmap在没有其他引用时被垃圾回收。此bitmap被标记为dead,意味着调用getPixels()或者setPixels()将会抛出异常,而且不会绘制。此操作不能回退,所以最好在bitmap不会用到时调用。这是一个高级调用,通常不应该调用,因为通常情况下如果此bitmap没有被引用,垃圾回收进程会释放占用的内存空间。
/** * Free the native object associated with this bitmap, and clear the * reference to the pixel data. This will not free the pixel data synchronously; * it simply allows it to be garbage collected if there are no other references. * The bitmap is marked as "dead", meaning it will throw an exception if * getPixels() or setPixels() is called, and will draw nothing. This operation * cannot be reversed, so it should only be called if you are sure there are no * further uses for the bitmap. This is an advanced call, and normally need * not be called, since the normal GC process will free up this memory when * there are no more references to this bitmap. */ public void recycle() { if (!mRecycled && mNativePtr != 0) { if (nativeRecycle(mNativePtr)) { // return value indicates whether native pixel object was actually recycled. // false indicates that it is still in use at the native level and these // objects should not be collected now. They will be collected later when the // Bitmap itself is collected. mBuffer = null; mNinePatchChunk = null; } mRecycled = true; } }
isRecycled()
判断位图内存是否已经被回收。
checkRecycled
如果已经被回收,则抛出非法状态异常IllegalStateException。
/** * This is called by methods that want to throw an exception if the bitmap * has already been recycled. */ private void checkRecycled(String errorMessage) { if (mRecycled) { throw new IllegalStateException(errorMessage); } }
getWidth() 获取宽度
getHeight() 获取高度
getScaledWidth(Canvas canvas)
获取经指定密度转换后的宽度
/** * Convenience for calling {@link #getScaledWidth(int)} with the target * density of the given {@link Canvas}. */ public int getScaledWidth(Canvas canvas) { return scaleFromDensity(getWidth(), mDensity, canvas.mDensity); } /** * Convenience for calling {@link #getScaledWidth(int)} with the target * density of the given {@link DisplayMetrics}. */ public int getScaledWidth(DisplayMetrics metrics) { return scaleFromDensity(getWidth(), mDensity, metrics.densityDpi); } /** * @hide */ static public int scaleFromDensity(int size, int sdensity, int tdensity) { if (sdensity == DENSITY_NONE || tdensity == DENSITY_NONE || sdensity == tdensity) { return size; } // Scale by tdensity / sdensity, rounding up. return ((size * tdensity) + (sdensity >> 1)) / sdensity; }
getScaledHeight(Canvas canvas)
获取经制定密度转换后的高度
/** * Convenience for calling {@link #getScaledHeight(int)} with the target * density of the given {@link Canvas}. */ public int getScaledHeight(Canvas canvas) { return scaleFromDensity(getHeight(), mDensity, canvas.mDensity); } /** * Convenience for calling {@link #getScaledHeight(int)} with the target * density of the given {@link DisplayMetrics}. */ public int getScaledHeight(DisplayMetrics metrics) { return scaleFromDensity(getHeight(), mDensity, metrics.densityDpi); }
getRowBytes()
获取native位图行像素的byte数
/** * Return the number of bytes between rows in the bitmap's pixels. Note that * this refers to the pixels as stored natively by the bitmap. If you call * getPixels() or setPixels(), then the pixels are uniformly treated as * 32bit values, packed according to the Color class. * * <p>As of {@link android.os.Build.VERSION_CODES#KITKAT}, this method * should not be used to calculate the memory usage of the bitmap. Instead, * see {@link #getAllocationByteCount()}. * * @return number of bytes between rows of the native bitmap pixels. */ public final int getRowBytes() { if (mRecycled) { Log.w(TAG, "Called getRowBytes() on a recycle()'d bitmap! This is undefined behavior!"); } return nativeRowBytes(mNativePtr); }
getByteCount()
获取可以存储此bitmap像素的最小字节。返回行像素x高度。
/** * Returns the minimum number of bytes that can be used to store this bitmap's pixels. * * <p>As of {@link android.os.Build.VERSION_CODES#KITKAT}, the result of this method can * no longer be used to determine memory usage of a bitmap. See {@link * #getAllocationByteCount()}.</p> */ public final int getByteCount() { // int result permits bitmaps up to 46,340 x 46,340 return getRowBytes() * getHeight(); }
getAllocationByteCount()
获取用来存储bitmap所分配的内存大小。在bitmap的生命周期内此值不会改变。
/** * Returns the size of the allocated memory used to store this bitmap's pixels. * * <p>This can be larger than the result of {@link #getByteCount()} if a bitmap is reused to * decode other bitmaps of smaller size, or by manual reconfiguration. See {@link * #reconfigure(int, int, Config)}, {@link #setWidth(int)}, {@link #setHeight(int)}, {@link * #setConfig(Bitmap.Config)}, and {@link BitmapFactory.Options#inBitmap * BitmapFactory.Options.inBitmap}. If a bitmap is not modified in this way, this value will be * the same as that returned by {@link #getByteCount()}.</p> * * <p>This value will not change over the lifetime of a Bitmap.</p> * * @see #reconfigure(int, int, Config) */ public final int getAllocationByteCount() { if (mBuffer == null) { // native backed bitmaps don't support reconfiguration, // so alloc size is always content size return getByteCount(); } return mBuffer.length; }
getConfig()
获取Config枚举:
- ALPHA_8, 代表8位Alpha位图,每个像素占用1byte内存
- RGB_565,代表8位RGB位图,每个像素占用2byte内存
- ARGB_4444 (@deprecated),代表16位ARGB位图,每个像素占用2byte内存
- ARGB_8888,代表32位ARGB位图,每个像素占用4byte内存
/** * If the bitmap's internal config is in one of the public formats, return * that config, otherwise return null. */ public final Config getConfig() { if (mRecycled) { Log.w(TAG, "Called getConfig() on a recycle()'d bitmap! This is undefined behavior!"); } return Config.nativeToConfig(nativeConfig(mNativePtr)); }
hasAlpha()
检测bitmap是否支持像素级别透明。
/** Returns true if the bitmap's config supports per-pixel alpha, and * if the pixels may contain non-opaque alpha values. For some configs, * this is always false (e.g. RGB_565), since they do not support per-pixel * alpha. However, for configs that do, the bitmap may be flagged to be * known that all of its pixels are opaque. In this case hasAlpha() will * also return false. If a config such as ARGB_8888 is not so flagged, * it will return true by default. */ public final boolean hasAlpha() { if (mRecycled) { Log.w(TAG, "Called hasAlpha() on a recycle()'d bitmap! This is undefined behavior!"); } return nativeHasAlpha(mNativePtr); }
setHasAlpha(boolean hasAlpha)
设置bitmap是否支持像素级别透明
/** * Tell the bitmap if all of the pixels are known to be opaque (false) * or if some of the pixels may contain non-opaque alpha values (true). * Note, for some configs (e.g. RGB_565) this call is ignored, since it * does not support per-pixel alpha values. * * This is meant as a drawing hint, as in some cases a bitmap that is known * to be opaque can take a faster drawing case than one that may have * non-opaque per-pixel alpha values. */ public void setHasAlpha(boolean hasAlpha) { checkRecycled("setHasAlpha called on a recycled bitmap"); nativeSetHasAlpha(mNativePtr, hasAlpha, mRequestPremultiplied); }
eraseColor(@ColorInt int c)
用颜色值填充bitmap的像素。
/** * Fills the bitmap's pixels with the specified {@link Color}. * * @throws IllegalStateException if the bitmap is not mutable. */ public void eraseColor(@ColorInt int c) { checkRecycled("Can't erase a recycled bitmap"); if (!isMutable()) { throw new IllegalStateException("cannot erase immutable bitmaps"); } nativeErase(mNativePtr, c); }
getPixel(int x, int y)
获取指定位置像素的颜色值。
/** * Returns the {@link Color} at the specified location. Throws an exception * if x or y are out of bounds (negative or >= to the width or height * respectively). The returned color is a non-premultiplied ARGB value. * * @param x The x coordinate (0...width-1) of the pixel to return * @param y The y coordinate (0...height-1) of the pixel to return * @return The argb {@link Color} at the specified coordinate * @throws IllegalArgumentException if x, y exceed the bitmap's bounds */ @ColorInt public int getPixel(int x, int y) { checkRecycled("Can't call getPixel() on a recycled bitmap"); checkPixelAccess(x, y); return nativeGetPixel(mNativePtr, x, y); }
setPixel(int x, int y, @ColorInt int color)
设置指定位置像素的颜色值。
/** * <p>Write the specified {@link Color} into the bitmap (assuming it is * mutable) at the x,y coordinate. The color must be a * non-premultiplied ARGB value.</p> * * @param x The x coordinate of the pixel to replace (0...width-1) * @param y The y coordinate of the pixel to replace (0...height-1) * @param color The ARGB color to write into the bitmap * * @throws IllegalStateException if the bitmap is not mutable * @throws IllegalArgumentException if x, y are outside of the bitmap's * bounds. */ public void setPixel(int x, int y, @ColorInt int color) { checkRecycled("Can't call setPixel() on a recycled bitmap"); if (!isMutable()) { throw new IllegalStateException(); } checkPixelAccess(x, y); nativeSetPixel(mNativePtr, x, y, color); }
writeToParcel(Parcel p, int flags)
打包bitmap
/** * Write the bitmap and its pixels to the parcel. The bitmap can be * rebuilt from the parcel by calling CREATOR.createFromParcel(). * @param p Parcel object to write the bitmap data into */ public void writeToParcel(Parcel p, int flags) { checkRecycled("Can't parcel a recycled bitmap"); if (!nativeWriteToParcel(mNativePtr, mIsMutable, mDensity, p)) { throw new RuntimeException("native writeToParcel failed"); } }
extractAlpha()
获取原bitmap的alpha通道数据最为新的bitmap。
/** * Returns a new bitmap that captures the alpha values of the original. * This may be drawn with Canvas.drawBitmap(), where the color(s) will be * taken from the paint that is passed to the draw call. * * @return new bitmap containing the alpha channel of the original bitmap. */ @CheckResult public Bitmap extractAlpha() { return extractAlpha(null, null); }
#
和另外一个bitmap比较二者是否相同。 /** * Given another bitmap, return true if it has the same dimensions, config, * and pixel data as this bitmap. If any of those differ, return false. * If other is null, return false. */ public boolean sameAs(Bitmap other) { checkRecycled("Can't call sameAs on a recycled bitmap!"); if (this == other) return true; if (other == null) return false; if (other.isRecycled()) { throw new IllegalArgumentException("Can't compare to a recycled bitmap!"); } return nativeSameAs(mNativePtr, other.mNativePtr); }
prepareToDraw()
绘制准备:重建该bitmap相关联的缓存来绘制。在可清除的bitmap中,此方法会尝试确保像素已经被解码。
/** * Rebuilds any caches associated with the bitmap that are used for * drawing it. In the case of purgeable bitmaps, this call will attempt to * ensure that the pixels have been decoded. * If this is called on more than one bitmap in sequence, the priority is * given in LRU order (i.e. the last bitmap called will be given highest * priority). * * For bitmaps with no associated caches, this call is effectively a no-op, * and therefore is harmless. */ public void prepareToDraw() { checkRecycled("Can't prepareToDraw on a recycled bitmap!"); // Kick off an update/upload of the bitmap outside of the normal // draw path. nativePrepareToDraw(mNativePtr); }
CompressFormat
bitmap压缩格式:JPEG,PNG,WEBP(谷歌推出的图片格式,小体积高质量,豆瓣电影的海报使用的此格式)
/** * Specifies the known formats a bitmap can be compressed into */ public enum CompressFormat { JPEG (0), PNG (1), WEBP (2); CompressFormat(int nativeInt) { this.nativeInt = nativeInt; } final int nativeInt; }
compress(CompressFormat format, int quality, OutputStream stream)
压缩bitmap。
/** * Write a compressed version of the bitmap to the specified outputstream. * If this returns true, the bitmap can be reconstructed by passing a * corresponding inputstream to BitmapFactory.decodeStream(). Note: not * all Formats support all bitmap configs directly, so it is possible that * the returned bitmap from BitmapFactory could be in a different bitdepth, * and/or may have lost per-pixel alpha (e.g. JPEG only supports opaque * pixels). * * @param format The format of the compressed image * @param quality Hint to the compressor, 0-100. 0 meaning compress for * small size, 100 meaning compress for max quality. Some * formats, like PNG which is lossless, will ignore the * quality setting * @param stream The outputstream to write the compressed data. * @return true if successfully compressed to the specified stream. */ public boolean compress(CompressFormat format, int quality, OutputStream stream) { checkRecycled("Can't compress a recycled bitmap"); // do explicit check before calling the native method if (stream == null) { throw new NullPointerException(); } if (quality < 0 || quality > 100) { throw new IllegalArgumentException("quality must be 0..100"); } Trace.traceBegin(Trace.TRACE_TAG_RESOURCES, "Bitmap.compress"); boolean result = nativeCompress(mNativePtr, format.nativeInt, quality, stream, new byte[WORKING_COMPRESS_STORAGE]); Trace.traceEnd(Trace.TRACE_TAG_RESOURCES); return result; }
BitmapFactory
inMutable
配置bitmap是否可修改
/** * If set, decode methods will always return a mutable Bitmap instead of * an immutable one. This can be used for instance to programmatically apply * effects to a Bitmap loaded through BitmapFactory. */ @SuppressWarnings({"UnusedDeclaration"}) // used in native code public boolean inMutable;
inJustDecodeBounds
如果设置为true,不获取图片,不分配内存,但会返回图片的高度宽度信息。
/** * 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. */ public boolean inJustDecodeBounds;
inSampleSize
图片缩放倍数
/** * 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 <= 1 is treated the same as 1. Note: the * decoder uses a final value based on powers of 2, any other value will * be rounded down to the nearest power of 2. */ public int inSampleSize;
inDither, @deprecated
抖动解码
/** * @deprecated As of {@link android.os.Build.VERSION_CODES#N}, this is * ignored. * * In {@link android.os.Build.VERSION_CODES#M} and below, if dither is * true, the decoder will attempt to dither the decoded image. */ public boolean inDither;
inDensity
用于位图的像素压缩比。
/** * The pixel density to use for the bitmap. This will always result * in the returned bitmap having a density set for it (see * {@link Bitmap#setDensity(int) Bitmap.setDensity(int)}). In addition, * if {@link #inScaled} is set (which it is by default} and this * density does not match {@link #inTargetDensity}, then the bitmap * will be scaled to the target density before being returned. * * <p>If this is 0, * {@link BitmapFactory#decodeResource(Resources, int)}, * {@link BitmapFactory#decodeResource(Resources, int, android.graphics.BitmapFactory.Options)}, * and {@link BitmapFactory#decodeResourceStream} * will fill in the density associated with the resource. The other * functions will leave it as-is and no density will be applied. * * @see #inTargetDensity * @see #inScreenDensity * @see #inScaled * @see Bitmap#setDensity(int) * @see android.util.DisplayMetrics#densityDpi */ public int inDensity;
inTargetDensity
用于目标位图的像素压缩比(要生成的位图)
/** * The pixel density of the destination this bitmap will be drawn to. * This is used in conjunction with {@link #inDensity} and * {@link #inScaled} to determine if and how to scale the bitmap before * returning it. * * <p>If this is 0, * {@link BitmapFactory#decodeResource(Resources, int)}, * {@link BitmapFactory#decodeResource(Resources, int, android.graphics.BitmapFactory.Options)}, * and {@link BitmapFactory#decodeResourceStream} * will fill in the density associated the Resources object's * DisplayMetrics. The other * functions will leave it as-is and no scaling for density will be * performed. * * @see #inDensity * @see #inScreenDensity * @see #inScaled * @see android.util.DisplayMetrics#densityDpi */ public int inTargetDensity;
inScreenDensity
当前屏幕的像素密度
/** * The pixel density of the actual screen that is being used. This is * purely for applications running in density compatibility code, where * {@link #inTargetDensity} is actually the density the application * sees rather than the real screen density. * * <p>By setting this, you * allow the loading code to avoid scaling a bitmap that is currently * in the screen density up/down to the compatibility density. Instead, * if {@link #inDensity} is the same as {@link #inScreenDensity}, the * bitmap will be left as-is. Anything using the resulting bitmap * must also used {@link Bitmap#getScaledWidth(int) * Bitmap.getScaledWidth} and {@link Bitmap#getScaledHeight * Bitmap.getScaledHeight} to account for any different between the * bitmap's density and the target's density. * * <p>This is never set automatically for the caller by * {@link BitmapFactory} itself. It must be explicitly set, since the * caller must deal with the resulting bitmap in a density-aware way. * * @see #inDensity * @see #inTargetDensity * @see #inScaled * @see android.util.DisplayMetrics#densityDpi */ public int inScreenDensity;
inScaled
设置为true时进行图片压缩,从inDensity到inTargetDensity
/** * When this flag is set, if {@link #inDensity} and * {@link #inTargetDensity} are not 0, the * bitmap will be scaled to match {@link #inTargetDensity} when loaded, * rather than relying on the graphics system scaling it each time it * is drawn to a Canvas. * * <p>BitmapRegionDecoder ignores this flag, and will not scale output * based on density. (though {@link #inSampleSize} is supported)</p> * * <p>This flag is turned on by default and should be turned off if you need * a non-scaled version of the bitmap. Nine-patch bitmaps ignore this * flag and are always scaled. * * <p>If {@link #inPremultiplied} is set to false, and the image has alpha, * setting this flag to true may result in incorrect colors. */ public boolean inScaled;
inPurgeable
当存储Pixel的内存空间在系统内存不足时是否可以被回收
/** * @deprecated As of {@link android.os.Build.VERSION_CODES#LOLLIPOP}, this is * ignored. * * In {@link android.os.Build.VERSION_CODES#KITKAT} and below, if this * is set to true, then the resulting bitmap will allocate its * pixels such that they can be purged if the system needs to reclaim * memory. In that instance, when the pixels need to be accessed again * (e.g. the bitmap is drawn, getPixels() is called), they will be * automatically re-decoded. * * <p>For the re-decode to happen, the bitmap must have access to the * encoded data, either by sharing a reference to the input * or by making a copy of it. This distinction is controlled by * inInputShareable. If this is true, then the bitmap may keep a shallow * reference to the input. If this is false, then the bitmap will * explicitly make a copy of the input data, and keep that. Even if * sharing is allowed, the implementation may still decide to make a * deep copy of the input data.</p> * * <p>While inPurgeable can help avoid big Dalvik heap allocations (from * API level 11 onward), it sacrifices performance predictability since any * image that the view system tries to draw may incur a decode delay which * can lead to dropped frames. Therefore, most apps should avoid using * inPurgeable to allow for a fast and fluid UI. To minimize Dalvik heap * allocations use the {@link #inBitmap} flag instead.</p> * * <p class="note"><strong>Note:</strong> This flag is ignored when used * with {@link #decodeResource(Resources, int, * android.graphics.BitmapFactory.Options)} or {@link #decodeFile(String, * android.graphics.BitmapFactory.Options)}.</p> */ @Deprecated public boolean inPurgeable;
inInputShareable
inPurgeable为true情况下才生效,是否可以共享一个InputStream
/** * @deprecated As of {@link android.os.Build.VERSION_CODES#LOLLIPOP}, this is * ignored. * * In {@link android.os.Build.VERSION_CODES#KITKAT} and below, this * field works in conjuction with inPurgeable. If inPurgeable is false, * then this field is ignored. If inPurgeable is true, then this field * determines whether the bitmap can share a reference to the input * data (inputstream, array, etc.) or if it must make a deep copy. */ @Deprecated public boolean inInputShareable;
inPreferQualityOverSpeed
为true则优先保证Bitmap质量其次是解码速度。
/** * @deprecated As of {@link android.os.Build.VERSION_CODES#N}, this is * ignored. The output will always be high quality. * * In {@link android.os.Build.VERSION_CODES#M} and below, if * inPreferQualityOverSpeed is set to true, the decoder will try to * decode the reconstructed image to a higher quality even at the * expense of the decoding speed. Currently the field only affects JPEG * decode, in the case of which a more accurate, but slightly slower, * IDCT method will be used instead. */ public boolean inPreferQualityOverSpeed;
decodeFile(String pathName, Options opts)
从文件读取图片
/** * Decode a file path into a bitmap. If the specified file name is null, * or cannot be decoded into a bitmap, the function returns null. * * @param pathName complete path name for the file to be decoded. * @param opts null-ok; Options that control downsampling and whether the * image should be completely decoded, or just is size returned. * @return The decoded bitmap, or null if the image data could not be * decoded, or, if opts is non-null, if opts requested only the * size be returned (in opts.outWidth and opts.outHeight) */ public static Bitmap decodeFile(String pathName, Options opts) { Bitmap bm = null; InputStream stream = null; try { stream = new FileInputStream(pathName); bm = decodeStream(stream, null, opts); } catch (Exception e) { /* do nothing. If the exception happened on open, bm will be null. */ Log.e("BitmapFactory", "Unable to decode stream: " + e); } finally { if (stream != null) { try { stream.close(); } catch (IOException e) { // do nothing here } } } return bm; }
decodeResource
从res资源文件读取图片。
加载的图片可能会经过缩放,该缩放目前是放在 java 层做的,效率比较低,而且需要消耗 java 层的内存。因此,如果大量使用该接口加载图片,容易导致OOM错误
/** * Synonym for opening the given resource and calling * {@link #decodeResourceStream}. * * @param res The resources object containing the image data * @param id The resource id of the image data * @param opts null-ok; Options that control downsampling and whether the * image should be completely decoded, or just is size returned. * @return The decoded bitmap, or null if the image data could not be * decoded, or, if opts is non-null, if opts requested only the * size be returned (in opts.outWidth and opts.outHeight) */ public static Bitmap decodeResource(Resources res, int id, Options opts) { Bitmap bm = null; InputStream is = null; try { final TypedValue value = new TypedValue(); is = res.openRawResource(id, value); bm = decodeResourceStream(res, value, is, null, opts); } catch (Exception e) { /* do nothing. If the exception happened on open, bm will be null. If it happened on close, bm is still valid. */ } finally { try { if (is != null) is.close(); } catch (IOException e) { // Ignore } } if (bm == null && opts != null && opts.inBitmap != null) { throw new IllegalArgumentException("Problem decoding into existing bitmap"); } return bm; }
decodeByteArray
从数组读取图片
/** * Decode an immutable bitmap from the specified byte array. * * @param data byte array of compressed image data * @param offset offset into imageData for where the decoder should begin * parsing. * @param length the number of bytes, beginning at offset, to parse * @param opts null-ok; Options that control downsampling and whether the * image should be completely decoded, or just is size returned. * @return The decoded bitmap, or null if the image data could not be * decoded, or, if opts is non-null, if opts requested only the * size be returned (in opts.outWidth and opts.outHeight) */ public static Bitmap decodeByteArray(byte[] data, int offset, int length, Options opts) { if ((offset | length) < 0 || data.length < offset + length) { throw new ArrayIndexOutOfBoundsException(); } Bitmap bm; Trace.traceBegin(Trace.TRACE_TAG_GRAPHICS, "decodeBitmap"); try { bm = nativeDecodeByteArray(data, offset, length, opts); if (bm == null && opts != null && opts.inBitmap != null) { throw new IllegalArgumentException("Problem decoding into existing bitmap"); } setDensityFromOptions(bm, opts); } finally { Trace.traceEnd(Trace.TRACE_TAG_GRAPHICS); } return bm; }
decodeStream(InputStream is, Rect outPadding, Options opts)
从输入流读取图片。
不会对所加载的图片进行缩放,相比之下占用内存少,效率更高。
/** * Decode an input stream into a bitmap. If the input stream is null, or * cannot be used to decode a bitmap, the function returns null. * The stream's position will be where ever it was after the encoded data * was read. * * @param is The input stream that holds the raw data to be decoded into a * bitmap. * @param outPadding If not null, return the padding rect for the bitmap if * it exists, otherwise set padding to [-1,-1,-1,-1]. If * no bitmap is returned (null) then padding is * unchanged. * @param opts null-ok; Options that control downsampling and whether the * image should be completely decoded, or just is size returned. * @return The decoded bitmap, or null if the image data could not be * decoded, or, if opts is non-null, if opts requested only the * size be returned (in opts.outWidth and opts.outHeight) * * <p class="note">Prior to {@link android.os.Build.VERSION_CODES#KITKAT}, * if {@link InputStream#markSupported is.markSupported()} returns true, * <code>is.mark(1024)</code> would be called. As of * {@link android.os.Build.VERSION_CODES#KITKAT}, this is no longer the case.</p> */ public static Bitmap decodeStream(InputStream is, Rect outPadding, Options opts) { // we don't throw in this case, thus allowing the caller to only check // the cache, and not force the image to be decoded. if (is == null) { return null; } Bitmap bm = null; Trace.traceBegin(Trace.TRACE_TAG_GRAPHICS, "decodeBitmap"); try { if (is instanceof AssetManager.AssetInputStream) { final long asset = ((AssetManager.AssetInputStream) is).getNativeAsset(); bm = nativeDecodeAsset(asset, outPadding, opts); } else { bm = decodeStreamInternal(is, outPadding, opts); } if (bm == null && opts != null && opts.inBitmap != null) { throw new IllegalArgumentException("Problem decoding into existing bitmap"); } setDensityFromOptions(bm, opts); } finally { Trace.traceEnd(Trace.TRACE_TAG_GRAPHICS); } return bm; }
- Android 从源码分析Bitmap和BitmapFactory常用API
- Bitmap和BitmapFactory的一些api
- Android图形图像处理之Bitmap和BitmapFactory
- Android入门——Bitmap和BitmapFactory
- Bitmap和BitmapFactory
- Android——Bitmap及其BitmapFactory的常用方法
- 初学Android,图形图像之使用Bitmap和BitmapFactory(二十四)
- 【Android开发】图形图像处理技术-Bitmap和BitmapFactory类
- android的Bitmap和BitmapFactory类的使用
- 初学Android,图形图像之使用Bitmap和BitmapFactory(二十四)
- android BitmapFactory的OutOfMemoryError: bitmap ...
- Android图片之Bitmap、BitmapFactory
- Bitmap和BitmapFactory对象使用
- Android中一些常用类的常用方法(Math、Random、Color、Paint、Canvas、Bitmap、BitmapFactory)
- Android 4K高清图片解码显示(2)BitmapFactory常用Bitmap的解码方法
- android下载网络图片,BitmapFactory创建bitmap
- Android graphics学习笔记(4) - Bitmap&BitmapFactory
- android BitmapFactory.Options 优化bitmap图像
- Class 'org.apache.commons.dbcp.BasicDataSource' not found
- [昨日实践]RHEL5.X安装JDK1.7.0_80
- css cursor 鼠标指针样式总结
- springboot+dubbo配置走过的坑
- java培训学习为什么一直备受瞩目?
- Android 从源码分析Bitmap和BitmapFactory常用API
- makefile中命令前@
- 解析CIDR表示的IP段表示的范围
- 【Scikit-Learn 中文文档】特征提取
- 关闭和恢复adb
- [昨日实践]win2003下安装mysql5.5.57
- locate命令使用实例
- Mysql高阶功法
- python基础-进程互斥锁、线程互斥锁