android.graphics.BitmapRegionDecoder# isRecycled ( ) 源码实例Demo

下面列出了android.graphics.BitmapRegionDecoder# isRecycled ( ) 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。


/**
 * Acquire a read lock to prevent decoding overlapping with recycling, then check the pool still
 * exists and acquire a decoder to load the requested region. There is no check whether the pool
 * currently has decoders, because it's guaranteed to have one decoder after {@link #init(Context, Uri)}
 * is called and be null once {@link #recycle()} is called. In practice the view can't call this
 * method until after {@link #init(Context, Uri)}, so there will be no blocking on an empty pool.
 */
@Override
@NonNull
public Bitmap decodeRegion(@NonNull Rect sRect, int sampleSize) {
    debug("Decode region " + sRect + " on thread " + Thread.currentThread().getName());
    if (sRect.width() < imageDimensions.x || sRect.height() < imageDimensions.y) {
        lazyInit();
    }
    decoderLock.readLock().lock();
    try {
        if (decoderPool != null) {
            BitmapRegionDecoder decoder = decoderPool.acquire();
            try {
                // Decoder can't be null or recycled in practice
                if (decoder != null && !decoder.isRecycled()) {
                    BitmapFactory.Options options = new BitmapFactory.Options();
                    options.inSampleSize = sampleSize;
                    options.inPreferredConfig = bitmapConfig;
                    Bitmap bitmap = decoder.decodeRegion(sRect, options);
                    if (bitmap == null) {
                        throw new RuntimeException("Skia image decoder returned null bitmap - image format may not be supported");
                    }
                    return bitmap;
                }
            } finally {
                if (decoder != null) {
                    decoderPool.release(decoder);
                }
            }
        }
        throw new IllegalStateException("Cannot decode region after decoder has been recycled");
    } finally {
        decoderLock.readLock().unlock();
    }
}
 

/**
 * Acquire a read lock to prevent decoding overlapping with recycling, then check the pool still
 * exists and acquire a decoder to load the requested region. There is no check whether the pool
 * currently has decoders, because it's guaranteed to have one decoder after {@link #init(Context, Uri)}
 * is called and be null once {@link #recycle()} is called. In practice the view can't call this
 * method until after {@link #init(Context, Uri)}, so there will be no blocking on an empty pool.
 */
@Override
@NonNull
public Bitmap decodeRegion(@NonNull Rect sRect, int sampleSize) {
    debug("Decode region " + sRect + " on thread " + Thread.currentThread().getName());
    if (sRect.width() < imageDimensions.x || sRect.height() < imageDimensions.y) {
        lazyInit();
    }
    decoderLock.readLock().lock();
    try {
        if (decoderPool != null) {
            BitmapRegionDecoder decoder = decoderPool.acquire();
            try {
                // Decoder can't be null or recycled in practice
                if (decoder != null && !decoder.isRecycled()) {
                    BitmapFactory.Options options = new BitmapFactory.Options();
                    options.inSampleSize = sampleSize;
                    options.inPreferredConfig = bitmapConfig;
                    Bitmap bitmap = decoder.decodeRegion(sRect, options);
                    if (bitmap == null) {
                        throw new RuntimeException("Skia image decoder returned null bitmap - image format may not be supported");
                    }
                    return bitmap;
                }
            } finally {
                if (decoder != null) {
                    decoderPool.release(decoder);
                }
            }
        }
        throw new IllegalStateException("Cannot decode region after decoder has been recycled");
    } finally {
        decoderLock.readLock().unlock();
    }
}
 

/**
 * Acquire a read lock to prevent decoding overlapping with recycling, then check the pool still
 * exists and acquire a decoder to load the requested region. There is no check whether the pool
 * currently has decoders, because it's guaranteed to have one decoder after {@link #init(Context, Uri)}
 * is called and be null once {@link #recycle()} is called. In practice the view can't call this
 * method until after {@link #init(Context, Uri)}, so there will be no blocking on an empty pool.
 */
@Override
@NonNull
public Bitmap decodeRegion(@NonNull Rect sRect, int sampleSize) {
    debug("Decode region " + sRect + " on thread " + Thread.currentThread().getName());
    if (sRect.width() < imageDimensions.x || sRect.height() < imageDimensions.y) {
        lazyInit();
    }
    decoderLock.readLock().lock();
    try {
        if (decoderPool != null) {
            BitmapRegionDecoder decoder = decoderPool.acquire();
            try {
                // Decoder can't be null or recycled in practice
                if (decoder != null && !decoder.isRecycled()) {
                    BitmapFactory.Options options = new BitmapFactory.Options();
                    options.inSampleSize = sampleSize;
                    options.inPreferredConfig = bitmapConfig;
                    Bitmap bitmap = decoder.decodeRegion(sRect, options);
                    if (bitmap == null) {
                        throw new RuntimeException("Skia image decoder returned null bitmap - image format may not be supported");
                    }
                    return bitmap;
                }
            } finally {
                if (decoder != null) {
                    decoderPool.release(decoder);
                }
            }
        }
        throw new IllegalStateException("Cannot decode region after decoder has been recycled");
    } finally {
        decoderLock.readLock().unlock();
    }
}
 

/**
 * Acquire a read lock to prevent decoding overlapping with recycling, then check the pool still
 * exists and acquire a decoder to load the requested region. There is no check whether the pool
 * currently has decoders, because it's guaranteed to have one decoder after {@link #init(Context, Uri)}
 * is called and be null once {@link #recycle()} is called. In practice the view can't call this
 * method until after {@link #init(Context, Uri)}, so there will be no blocking on an empty pool.
 */
@Override
public Bitmap decodeRegion(Rect sRect, int sampleSize) {
    debug("Decode region " + sRect + " on thread " + Thread.currentThread().getName());
    if (sRect.width() < imageDimensions.x || sRect.height() < imageDimensions.y) {
        lazyInit();
    }
    decoderLock.readLock().lock();
    try {
        if (decoderPool != null) {
            BitmapRegionDecoder decoder = decoderPool.acquire();
            try {
                // Decoder can't be null or recycled in practice
                if (decoder != null && !decoder.isRecycled()) {
                    BitmapFactory.Options options = new BitmapFactory.Options();
                    options.inSampleSize = sampleSize;
                    options.inPreferredConfig = bitmapConfig;
                    Bitmap bitmap = decoder.decodeRegion(sRect, options);
                    if (bitmap == null) {
                        throw new RuntimeException("Skia image decoder returned null bitmap - image format may not be supported");
                    }
                    return bitmap;
                }
            } finally {
                if (decoder != null) {
                    decoderPool.release(decoder);
                }
            }
        }
        throw new IllegalStateException("Cannot decode region after decoder has been recycled");
    } finally {
        decoderLock.readLock().unlock();
    }
}
 

@Override
@NonNull
public Bitmap decodeRegion(@NonNull Rect sRect, int sampleSize) {
    debug("Decode region " + sRect + " on thread " + Thread.currentThread().getName());
    if (sRect.width() < imageDimensions.x || sRect.height() < imageDimensions.y) {
        lazyInit();
    }
    decoderLock.readLock().lock();
    try {
        if (decoderPool != null) {
            BitmapRegionDecoder decoder = decoderPool.acquire();
            try {
                // Decoder can't be null or recycled in practice
                if (decoder != null && !decoder.isRecycled()) {
                    BitmapFactory.Options options = new BitmapFactory.Options();
                    options.inSampleSize = sampleSize;
                    options.inPreferredConfig = bitmapConfig;
                    Bitmap bitmap = decoder.decodeRegion(sRect, options);
                    if (bitmap == null) {
                        throw new RuntimeException(
                                "null bitmap - image format may not be supported");
                    }
                    return bitmap;
                }
            } finally {
                if (decoder != null) {
                    decoderPool.release(decoder);
                }
            }
        }
        throw new IllegalStateException("Cannot decode region after decoder has been recycled");
    } finally {
        decoderLock.readLock().unlock();
    }
}
 

/**
 * Acquire a read lock to prevent decoding overlapping with recycling, then check the pool still
 * exists and acquire a decoder to load the requested region. There is no check whether the pool
 * currently has decoders, because it's guaranteed to have one decoder after {@link #init(Context, Uri)}
 * is called and be null once {@link #recycle()} is called. In practice the view can't call this
 * method until after {@link #init(Context, Uri)}, so there will be no blocking on an empty pool.
 */
@Override
@NonNull
public Bitmap decodeRegion(@NonNull Rect sRect, int sampleSize) {
    debug("Decode region " + sRect + " on thread " + Thread.currentThread().getName());
    if (sRect.width() < imageDimensions.x || sRect.height() < imageDimensions.y) {
        lazyInit();
    }
    decoderLock.readLock().lock();
    try {
        if (decoderPool != null) {
            BitmapRegionDecoder decoder = decoderPool.acquire();
            try {
                // Decoder can't be null or recycled in practice
                if (decoder != null && !decoder.isRecycled()) {
                    BitmapFactory.Options options = new BitmapFactory.Options();
                    options.inSampleSize = sampleSize;
                    options.inPreferredConfig = bitmapConfig;
                    // If that is not set, some PNGs are read with a ColorSpace of code "Unknown" (-1),
                    // which makes resizing buggy (generates a black picture)
                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
                        options.inPreferredColorSpace = ColorSpace.get(ColorSpace.Named.SRGB);

                    Bitmap bitmap = decoder.decodeRegion(sRect, options);
                    if (bitmap == null) {
                        throw new RuntimeException("Skia image decoder returned null bitmap - image format may not be supported");
                    }
                    return bitmap;
                }
            } finally {
                if (decoder != null) {
                    decoderPool.release(decoder);
                }
            }
        }
        throw new IllegalStateException("Cannot decode region after decoder has been recycled");
    } finally {
        decoderLock.readLock().unlock();
    }
}
 

/**
 * Acquire a read lock to prevent decoding overlapping with recycling, then check the pool still
 * exists and acquire a decoder to load the requested region. There is no check whether the pool
 * currently has decoders, because it's guaranteed to have one decoder after {@link #init(Context, Uri)}
 * is called and be null once {@link #recycle()} is called. In practice the view can't call this
 * method until after {@link #init(Context, Uri)}, so there will be no blocking on an empty pool.
 */
@Override
@NonNull
public Bitmap decodeRegion(@NonNull Rect sRect, int sampleSize) {
    debug("Decode region " + sRect + " on thread " + Thread.currentThread().getName());
    if (sRect.width() < imageDimensions.x || sRect.height() < imageDimensions.y) {
        lazyInit();
    }
    decoderLock.readLock().lock();
    try {
        if (decoderPool != null) {
            BitmapRegionDecoder decoder = decoderPool.acquire();
            try {
                // Decoder can't be null or recycled in practice
                if (decoder != null && !decoder.isRecycled()) {
                    BitmapFactory.Options options = new BitmapFactory.Options();
                    options.inSampleSize = sampleSize;
                    options.inPreferredConfig = bitmapConfig;
                    Bitmap bitmap = decoder.decodeRegion(sRect, options);
                    if (bitmap == null) {
                        throw new RuntimeException("Skia image decoder returned null bitmap - image format may not be supported");
                    }
                    return bitmap;
                }
            } finally {
                if (decoder != null) {
                    decoderPool.release(decoder);
                }
            }
        }
        throw new IllegalStateException("Cannot decode region after decoder has been recycled");
    } finally {
        decoderLock.readLock().unlock();
    }
}
 

@Override
protected Bitmap doInBackground(Void... params) {
    try {
        if (decoderRef != null && tileRef != null && viewRef != null) {
            final BitmapRegionDecoder decoder = decoderRef.get();
            final Object decoderLock = decoderLockRef.get();
            final Tile tile = tileRef.get();
            final SubsamplingScaleImageView view = viewRef.get();
            if (decoder != null && decoderLock != null && tile != null && view != null && !decoder.isRecycled()) {
                synchronized (decoderLock) {
                    BitmapFactory.Options options = new BitmapFactory.Options();
                    options.inSampleSize = tile.sampleSize;
                    options.inPreferredConfig = Config.RGB_565;
                    options.inDither = true;
                    Bitmap bitmap = decoder.decodeRegion(view.fileSRect(tile.sRect), options);
                    int rotation = view.getRequiredRotation();
                    if (rotation != 0) {
                        Matrix matrix = new Matrix();
                        matrix.postRotate(rotation);
                        bitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
                    }
                    return bitmap;
                }
            } else if (tile != null) {
                tile.loading = false;
            }
        }
    } catch (Exception e) {
        Log.e(TAG, "Failed to decode tile", e);
    }
    return null;
}
 

/**
 * Acquire a read lock to prevent decoding overlapping with recycling, then check the pool still
 * exists and acquire a decoder to load the requested region. There is no check whether the pool
 * currently has decoders, because it's guaranteed to have one decoder after {@link #init(Context, Uri)}
 * is called and be null once {@link #recycle()} is called. In practice the view can't call this
 * method until after {@link #init(Context, Uri)}, so there will be no blocking on an empty pool.
 */
@Override
@NonNull
public Bitmap decodeRegion(@NonNull Rect sRect, int sampleSize) {
    debug("Decode region " + sRect + " on thread " + Thread.currentThread().getName());
    if (sRect.width() < imageDimensions.x || sRect.height() < imageDimensions.y) {
        lazyInit();
    }
    decoderLock.readLock().lock();
    try {
        if (decoderPool != null) {
            BitmapRegionDecoder decoder = decoderPool.acquire();
            try {
                // Decoder can't be null or recycled in practice
                if (decoder != null && !decoder.isRecycled()) {
                    BitmapFactory.Options options = new BitmapFactory.Options();
                    options.inSampleSize = sampleSize;
                    options.inPreferredConfig = bitmapConfig;
                    Bitmap bitmap = decoder.decodeRegion(sRect, options);
                    if (bitmap == null) {
                        throw new RuntimeException("Skia image decoder returned null bitmap - image format may not be supported");
                    }
                    return bitmap;
                }
            } finally {
                if (decoder != null) {
                    decoderPool.release(decoder);
                }
            }
        }
        throw new IllegalStateException("Cannot decode region after decoder has been recycled");
    } finally {
        decoderLock.readLock().unlock();
    }
}
 
源代码10 项目: Tok-Android   文件: ClipImgActivity.java

private Bitmap createClippedBitmap() {
    //if (mSampleSize <= 1) {
    // TODO has problem, this method is not useful on some picture
    //    return mClipImageView.clip();
    //}

    final float[] matrixValues = mClipImageView.getClipMatrixValues();
    final float scale = matrixValues[Matrix.MSCALE_X];
    final float transX = matrixValues[Matrix.MTRANS_X];
    final float transY = matrixValues[Matrix.MTRANS_Y];

    final Rect border = mClipImageView.getClipBorder();
    final float cropX = ((-transX + border.left) / scale) * mSampleSize;
    final float cropY = ((-transY + border.top) / scale) * mSampleSize;
    final float cropWidth = (border.width() / scale) * mSampleSize;
    final float cropHeight = (border.height() / scale) * mSampleSize;

    final RectF srcRect = new RectF(cropX, cropY, cropX + cropWidth, cropY + cropHeight);
    final Rect clipRect = getRealRect(srcRect);

    final BitmapFactory.Options ops = new BitmapFactory.Options();
    final Matrix outputMatrix = new Matrix();

    outputMatrix.setRotate(mDegree);
    if (mMaxWidth > 0 && cropWidth > mMaxWidth) {
        ops.inSampleSize = findBestSample((int) cropWidth, mMaxWidth);

        final float outputScale = mMaxWidth / (cropWidth / ops.inSampleSize);
        outputMatrix.postScale(outputScale, outputScale);
    }

    BitmapRegionDecoder decoder = null;
    try {
        decoder = BitmapRegionDecoder.newInstance(mInput, false);
        final Bitmap source = decoder.decodeRegion(clipRect, ops);
        recycleImageViewBitmap();
        return Bitmap.createBitmap(source, 0, 0, source.getWidth(), source.getHeight(),
            outputMatrix, false);
    } catch (Exception e) {
        return mClipImageView.clip();
    } finally {
        if (decoder != null && !decoder.isRecycled()) {
            decoder.recycle();
        }
    }
}
 
源代码11 项目: clip-image   文件: ClipImageActivity.java

private Bitmap createClippedBitmap() {
    if (mSampleSize <= 1) {
        return mClipImageView.clip();
    }

    // 获取缩放位移后的矩阵值
    final float[] matrixValues = mClipImageView.getClipMatrixValues();
    final float scale = matrixValues[Matrix.MSCALE_X];
    final float transX = matrixValues[Matrix.MTRANS_X];
    final float transY = matrixValues[Matrix.MTRANS_Y];

    // 获取在显示的图片中裁剪的位置
    final Rect border = mClipImageView.getClipBorder();
    final float cropX = ((-transX + border.left) / scale) * mSampleSize;
    final float cropY = ((-transY + border.top) / scale) * mSampleSize;
    final float cropWidth = (border.width() / scale) * mSampleSize;
    final float cropHeight = (border.height() / scale) * mSampleSize;

    // 获取在旋转之前的裁剪位置
    final RectF srcRect = new RectF(cropX, cropY, cropX + cropWidth, cropY + cropHeight);
    final Rect clipRect = getRealRect(srcRect);

    final BitmapFactory.Options ops = new BitmapFactory.Options();
    final Matrix outputMatrix = new Matrix();

    outputMatrix.setRotate(mDegree);
    // 如果裁剪之后的图片宽高仍然太大,则进行缩小
    if (mMaxWidth > 0 && cropWidth > mMaxWidth) {
        ops.inSampleSize = findBestSample((int) cropWidth, mMaxWidth);

        final float outputScale = mMaxWidth / (cropWidth / ops.inSampleSize);
        outputMatrix.postScale(outputScale, outputScale);
    }

    // 裁剪
    BitmapRegionDecoder decoder = null;
    try {
        decoder = BitmapRegionDecoder.newInstance(mInput, false);
        final Bitmap source = decoder.decodeRegion(clipRect, ops);
        recycleImageViewBitmap();
        return Bitmap.createBitmap(source, 0, 0, source.getWidth(), source.getHeight(), outputMatrix, false);
    } catch (Exception e) {
        return mClipImageView.clip();
    } finally {
        if (decoder != null && !decoder.isRecycled()) {
            decoder.recycle();
        }
    }
}