private InputStream prepareInputStream(final InputStream is) throws IOException { InputStream src = new FlushedInputStream(is); if (!src.markSupported()) { src = manager.getBuffersPool().bufferize(src, IMAGES_BUFFER_SIZE); } return src; }
void writeBitmapToDisk(final Bitmap bitmap) throws IOException { EnhancedResponseCache cache = (EnhancedResponseCache) manager.getImagesResponseCache(); OutputStream output = new FileOutputStream(cache.getLocalPath(url)); output = manager.getBuffersPool().bufferize(output, IMAGES_BUFFER_SIZE); try { final int quality = 100; bitmap.compress(Bitmap.CompressFormat.PNG, quality, output); } finally { IoUtils.closeQuietly(output); } }
/** * @param is image input stream * @return sampling factor * @throws IOException if error happens */ private int resolveSampleFactor(final InputStream is, final BitmapFactory.Options options) throws IOException { if (!is.markSupported()) { throw new IllegalStateException("Input stream does not support marks!"); } options.inJustDecodeBounds = true; int result = 1; try { MarkableInputStream markableStream = new MarkableInputStream(is); // Thanks to Square guys :) long mark = markableStream.savePosition(BOUNDS_INFO_MARK); doStreamDecode(markableStream, options); result = ImagesManager.calculateSampleFactor( options.outWidth, options.outHeight, getRequiredWidth(), getRequiredHeight()); markableStream.reset(mark); } finally { options.inJustDecodeBounds = false; } return result; }
/** * Store image to the disk cache. If max allowed size is set image may be rescaled on disk. * * @throws IOException if error happens */ public void storeToDisk() throws IOException { if (manager.isPresentOnDisk(url)) { return; } if (!hasAllowedSize()) { IoUtils.consumeStream(getRemoteInputStream(), manager.getBuffersPool()); return; } ImageResult result = decodeStream(getRemoteInputStream(), true); if (result.getType() == ImageSourceType.NETWORK && result.getBitmap() != null) { // image was scaled writeBitmapToDisk(result.getBitmap()); } }
/** * @param manager images manager instance * @param url image URL * @param maxRelativeSize max allowed size of an image relatively to screen size, negative value * means allowed size will be ignored */ ImageRequest(final ImagesManager manager, final String url, final float maxRelativeSize) { this.manager = manager; this.url = url; if (maxRelativeSize < 0) { maxAllowedWidth = -1; maxAllowedHeight = -1; } else { DisplayMetrics metrics = manager.getContext().getResources().getDisplayMetrics(); maxAllowedWidth = (int) (metrics.widthPixels * maxRelativeSize); maxAllowedHeight = (int) (metrics.heightPixels * maxRelativeSize); } }
private ImageResult decodeStream(final InputStream is, boolean onlyIfNeedsRescale) throws IOException { final BitmapFactory.Options options = createBitmapOptions(); final InputStream src = prepareInputStream(is); try { ImageResult result = new ImageResult(); result.setType(manager.isPresentOnDisk(url) ? ImageSourceType.DISK : ImageSourceType.NETWORK); // get scale factor options.inSampleSize = resolveSampleFactor(src, options); if (options.inSampleSize > 1 || !onlyIfNeedsRescale) { // actually decode result.setBitmap(doStreamDecode(src, options)); } else { // consume input in order to cache it IoUtils.consumeStream(src, manager.getBuffersPool()); } if (manager.debug) { Log.d(TAG, "Image decoded: " + result); } return result; } catch (final OutOfMemoryError e) { // wrap OOM in IO final IOException wrapped = new IOException("out of memory for " + getKey()); wrapped.initCause(e); throw wrapped; } finally { recycle(options); src.close(); } }
URLConnection newUrlConnection() throws IOException { UrlConnectionBuilderFactory builderFactory = BeansManager.get(manager.getContext()) .getContainer() .getBean( ImagesManager.CONNECTION_BUILDER_FACTORY_NAME, UrlConnectionBuilderFactory.class); return builderFactory .newUrlConnectionBuilder() .setUrl(url) .setCacheManagerName(ImagesManager.CACHE_BEAN_NAME) .create(); }
private void recycle(final BitmapFactory.Options options) { manager.getBuffersPool().release(options.inTempStorage); }
private BitmapFactory.Options createBitmapOptions() { BitmapFactory.Options options = new BitmapFactory.Options(); options.inTempStorage = manager.getBuffersPool().get(IMAGES_BUFFER_SIZE); options.inPreferredConfig = format; return options; }