@RequiresApi(api = Build.VERSION_CODES.GINGERBREAD_MR1) @Override public Point init(Context context, Uri uri) throws Exception { Log.w(TAG, "Init!"); if (!PartAuthority.isLocalUri(uri)) { passthrough = new SkiaImageRegionDecoder(); return passthrough.init(context, uri); } MasterSecret masterSecret = KeyCachingService.getMasterSecret(context); if (masterSecret == null) { throw new IllegalStateException("No master secret available..."); } InputStream inputStream = PartAuthority.getAttachmentStream(context, masterSecret, uri); this.bitmapRegionDecoder = BitmapRegionDecoder.newInstance(inputStream, false); inputStream.close(); return new Point(bitmapRegionDecoder.getWidth(), bitmapRegionDecoder.getHeight()); }
@Override public BitmapRegionDecoder intercept(Chain chain) throws IOException { final Uri uri = chain.uri(); BitmapRegionDecoder decoder = chain.chain(uri); if (decoder != null){ return decoder; } if (UriUtil.isNetworkUri(uri)){ if (BuildConfig.DEBUG) { Log.d("NetworkInterceptor", "从我这加载"); } File file = processFile(uri.toString()); try { //InputStream inputStream = processBitmap(uri.toString()); return BitmapRegionDecoder.newInstance(new FileInputStream(file),false); } catch (IOException e) { //e.printStackTrace(); return Interceptors.fixJPEGDecoder(file,e); } } return null; }
public static BitmapRegionDecoder fixJPEGDecoder(File file, IOException e) throws IOException { if (file == null || !file.exists()){ throw e; } Bitmap bitmap = BitmapFactory.decodeFile(file.getAbsolutePath(),new BitmapFactory.Options()); if (bitmap == null) { if (BuildConfig.DEBUG) { Log.d(TAG, "加载缓存失败:" + file.getAbsolutePath()); } throw e; } ByteArrayOutputStream baos = new ByteArrayOutputStream(); bitmap.compress(Bitmap.CompressFormat.PNG, 85, baos); BitmapRegionDecoder decoder = BitmapRegionDecoder.newInstance(baos.toByteArray(),0,baos.size(),false); bitmap.recycle(); if (BuildConfig.DEBUG) { Log.d(TAG, "fixJPEGDecoder: 从此处修复Bitmap"); } return decoder; }
@Override public BitmapRegionDecoder intercept(Chain chain) throws IOException { final Uri uri = chain.uri(); BitmapRegionDecoder decoder = chain.chain(uri); if (decoder != null){ return decoder; } if (UriUtil.isLocalFileUri(uri)){ File file = new File(uri.getPath()); if (BuildConfig.DEBUG) { Log.d("FileInterceptor", "从我这加载"); } try { return BitmapRegionDecoder.newInstance(new FileInputStream(file.toString()),false); } catch (IOException e) { return Interceptors.fixJPEGDecoder(file,e); } } return null; }
public static BitmapRegionDecoder createBitmapRegionDecoder( ThreadPool.JobContext jc, byte[] bytes, int offset, int length, boolean shareable) { if (offset < 0 || length <= 0 || offset + length > bytes.length) { throw new IllegalArgumentException(String.format( "offset = %s, length = %s, bytes = %s", offset, length, bytes.length)); } try { return BitmapRegionDecoder.newInstance( bytes, offset, length, shareable); } catch (Throwable t) { Log.w(TAG, t); return null; } }
private static Bitmap decodeRegion(BitmapRegionDecoder decoder, Rect rect, BitmapFactory.Options options) { Bitmap bitmap = null; options.inPreferredConfig = Constants.PREFERRED_CONFIG; if (options.inPreferredConfig == Bitmap.Config.RGB_565) { options.inDither = true; } synchronized (sDecodeLock) { bitmap = decoder.decodeRegion(rect, options); } if (options.inBitmap != null) { if (bitmap != options.inBitmap) { Log.d("LocalRunnable", "decodeRegion inBitmap failed"); options.inBitmap.recycle(); } else { Log.d("LocalRunnable", "decodeRegion inBitmap success"); } } return bitmap; }
public TileImage getTileImage() { if (mIsGif) { return null; } BitmapFactory.Options options = new BitmapFactory.Options(); options.inJustDecodeBounds = true; BitmapFactory.decodeFile(this.mFilePath, options); int width = options.outWidth; int height = options.outHeight; if (width <= 0 || height <= 0) { return null; } try { BitmapRegionDecoder bitmapRegionDecoder = BitmapRegionDecoder.newInstance(this.mFilePath, false); return TileImage.newInstance(width, height, OrientationInfoUtility.getOrientation(this.mFilePath), bitmapRegionDecoder); } catch (IOException e) { e.printStackTrace(); } return null; }
public static BitmapRegionDecoder createBitmapRegionDecoder( JobContext jc, byte[] bytes, int offset, int length, boolean shareable) { if (offset < 0 || length <= 0 || offset + length > bytes.length) { throw new IllegalArgumentException(String.format( "offset = %s, length = %s, bytes = %s", offset, length, bytes.length)); } try { return BitmapRegionDecoder.newInstance( bytes, offset, length, shareable); } catch (Throwable t) { Log.w(TAG, t); return null; } }
private void updateFullImage(Path path, Future<BitmapRegionDecoder> future) { ImageEntry entry = mImageCache.get(path); if (entry == null || entry.fullImageTask != future) { BitmapRegionDecoder fullImage = future.get(); if (fullImage != null) fullImage.recycle(); return; } entry.fullImageTask = null; entry.fullImage = future.get(); if (entry.fullImage != null) { if (path == getPath(mCurrentIndex)) { updateTileProvider(entry); mPhotoView.notifyImageChange(0); } } updateImageRequests(); }
private void updateTileProvider(ImageEntry entry) { ScreenNail screenNail = entry.screenNail; BitmapRegionDecoder fullImage = entry.fullImage; if (screenNail != null) { if (fullImage != null) { mTileProvider.setScreenNail(screenNail, fullImage.getWidth(), fullImage.getHeight()); mTileProvider.setRegionDecoder(fullImage); } else { int width = screenNail.getWidth(); int height = screenNail.getHeight(); mTileProvider.setScreenNail(screenNail, width, height); } } else { mTileProvider.clear(); } }
/** * Initialisiert und erzeugt einen Tile-Cache als LRU-Cache. * * @param inputStream Stream zur Bilddatei (nur JPEG und PNG) * @param cacheCallback Callback, wenn ein Tile nach einem Cache-Miss generiert und im Cache gespeichert wurde. * @throws IOException Wird geworfen, wenn BitmapRegionDecoder nicht instanziiert werden kann (falls das Bild * weder JPEG noch PNG ist, oder bei einem anderen IO-Fehler) */ public CachedImage(InputStream inputStream, CachedImage.CacheMissResolvedCallback cacheCallback) throws IOException { // Tilecache erzeugen durch Aufruf des LruCache<String, Bitmap>-Konstruktors super(calculateCacheSize()); // Callback setzen cacheMissResolvedCallback = cacheCallback; // BitmapRegionDecoder instanziieren. Wirft bei nicht unterstütztem Format (andere als JPEG und PNG) // eine IOException. regionDecoder = BitmapRegionDecoder.newInstance(inputStream, true); if (regionDecoder == null) { throw new IOException("BitmapRegionDecoder could not create instance for unknown reasons"); } }
ViewportWithCache(Point sceneSize, String filepath) throws IOException { mSceneSize = sceneSize; mVisibleViewport = new Viewport(); mVisibleViewport.CONFIG = DEFAULT_CONFIG; mCachedBitmap = null; mCachedWindow = null; mDecoder = BitmapRegionDecoder.newInstance(filepath, false); // TODO Create the sample image, should calculate DOWN_SAMPLE_SHIFT here Options opts = new Options(); opts.inPreferredConfig = DEFAULT_CONFIG; opts.inSampleSize = (1 << DOWN_SAMPLE_SHIFT); mSampledBitmap = BitmapFactory.decodeFile(filepath, opts); }
public static BitmapRegionDecoder createBitmapRegionDecoder( JobContext jc, byte[] bytes, int offset, int length, boolean shareable) { if (offset < 0 || length <= 0 || offset + length > bytes.length) { throw new IllegalArgumentException(String.format( "offset = %s, length = %s, bytes = %s", offset, length, bytes.length)); } try { return BitmapRegionDecoder.newInstance( bytes, offset, length, shareable); } catch (Throwable t) { WLog.w(TAG, t); return null; } }
/** * Loads cropped bitmap from the disk. * @param region Region to be cropped * @param imageWidth Width of original image * @param imageHeight Height of original image * @param rotation rotation applied to width and height * @param imagePath Path to the image on disk. * @param opts Options for loading the image * @return */ public static Bitmap loadCroppedBitmap( Rect region, int imageWidth, int imageHeight, int rotation, String imagePath, BitmapFactory.Options opts){ Bitmap bmap = null; try { BitmapRegionDecoder decoder = BitmapRegionDecoder.newInstance(imagePath, false); // inversely rotate the crop region to undo the rotation applied to image width and height int invRotation = (-rotation + 360) %360; Rect rect = applyRotation(invRotation, imageWidth, imageHeight, region); // Load the cropped bitmap bmap = decoder.decodeRegion(rect, opts); } catch (IOException e) { e.printStackTrace(); } return bmap; }
public void buildBlocksFromImage(InputStream imageStream) { this.originalImageInputStream = imageStream; BitmapRegionDecoder brp = null; try { brp = BitmapRegionDecoder.newInstance(imageStream, false); } catch (IOException e) { e.printStackTrace(); } for (int row = 0; row < this.rowCount; row++) { for (int col = 0; col < this.columnCount; col++) { int left = col * subdivisionWidth, top = row * subdivisionWidth; int right = left + subdivisionWidth, bottom = top + subdivisionWidth; Bitmap region = brp.decodeRegion(new Rect(left, top, right, bottom), null); RgbColor averageColor = calculateAverageColor(region); Block bestBlock = Block.bestMatchedBlock(averageColor); this.setBlockAtIndices(row, col, bestBlock); } } return; }
public void buildBlocksFromImage(InputStream imageStream) { this.originalImageInputStream = imageStream; BitmapRegionDecoder brp = null; try { brp = BitmapRegionDecoder.newInstance(imageStream, false); } catch (IOException e) { e.printStackTrace(); } for(int row = 0;row<this.rowCount;row++) { for(int col=0;col<this.columnCount; col++) { int left = col*subdivisionWidth, top = row*subdivisionWidth; int right = left + subdivisionWidth, bottom = top + subdivisionWidth; Bitmap region = brp.decodeRegion(new Rect(left, top, right, bottom), null); RgbColor averageColor = calculateAverageColor(region); Block bestBlock = Block.bestMatchedBlock(averageColor); this.setBlockAtIndices(row, col, bestBlock); } } return; }
private Bitmap readBitmap (final int scalePercentage, final Rect cropRect) throws IOException { if (100 % scalePercentage != 0) throw new IllegalArgumentException("scalePercentage " + scalePercentage + " is not a int ratio."); final Options opts = new Options(); opts.inPurgeable = true; opts.inInputShareable = true; opts.inSampleSize = 100 / scalePercentage; if (cropRect != null) { final BitmapRegionDecoder dec = BitmapRegionDecoder.newInstance(openFileDescriptor().getFileDescriptor(), true); try { return dec.decodeRegion(cropRect, opts); } finally { dec.recycle(); } } return BitmapFactory.decodeFileDescriptor(openFileDescriptor().getFileDescriptor(), null, opts); }
/** * Set the Background bitmap * * @param inputStream InputStream to the raw data of the bitmap */ public void setBitmap(InputStream inputStream) throws IOException { FlushedInputStream fixedInput = new FlushedInputStream(inputStream); BitmapFactory.Options opt = new BitmapFactory.Options(); decoder = BitmapRegionDecoder.newInstance(fixedInput, false); fixedInput.reset(); // Grab the bounds of the background bitmap opt.inPreferredConfig = DEFAULT_CONFIG; opt.inJustDecodeBounds = true; GameLog.d(TAG, "Decode inputStream for Background Bitmap"); BitmapFactory.decodeStream(fixedInput, null, opt); fixedInput.reset(); backgroundSize.set(opt.outWidth, opt.outHeight); GameLog.d(TAG, "Background Image: w=" + opt.outWidth + " h=" + opt.outHeight); // Create the low resolution background opt.inJustDecodeBounds = false; opt.inSampleSize = 1 << sampleSize; lowResBitmap = BitmapFactory.decodeStream(fixedInput, null, opt); GameLog.d(TAG, "Low Res Image: w=" + lowResBitmap.getWidth() + " h=" + lowResBitmap.getHeight()); // Initialize cache if (cachedBitmap.getState() == CacheState.NOT_INITIALIZED) { synchronized (cachedBitmap) { cachedBitmap.setState(CacheState.IS_INITIALIZED); } } }
@Before public void setUp() throws Exception { final Random random = new Random(); random.setSeed(RANDOM_SEED); mEncodedBytes = new byte[ENCODED_BYTES_LENGTH]; random.nextBytes(mEncodedBytes); mPooledByteBuffer = new TrivialPooledByteBuffer(mEncodedBytes); mBitmapPool = mock(BitmapPool.class); mArtDecoder = new ArtDecoder(mBitmapPool, 1, new Pools.SynchronizedPool(1)); mByteBufferRef = CloseableReference.of(mPooledByteBuffer); mEncodedImage = new EncodedImage(mByteBufferRef); mEncodedImage.setImageFormat(DefaultImageFormats.JPEG); mBitmap = MockBitmapFactory.create(); doReturn(mBitmap).when(mBitmapPool).get(MockBitmapFactory.DEFAULT_BITMAP_SIZE); mBitmapFactoryDefaultAnswer = new Answer<Bitmap>() { @Override public Bitmap answer(InvocationOnMock invocation) throws Throwable { final BitmapFactory.Options options = (BitmapFactory.Options) invocation.getArguments()[2]; options.outWidth = MockBitmapFactory.DEFAULT_BITMAP_WIDTH; options.outHeight = MockBitmapFactory.DEFAULT_BITMAP_HEIGHT; verifyBitmapFactoryOptions(options); return options.inJustDecodeBounds ? null : mBitmap; } }; whenBitmapFactoryDecodeStream().thenAnswer(mBitmapFactoryDefaultAnswer); mBitmapRegionDecoder = mock(BitmapRegionDecoder.class); whenBitmapRegionDecoderNewInstance().thenReturn(mBitmapRegionDecoder); ByteBuffer buf = mArtDecoder.mDecodeBuffers.acquire(); mTempStorage = buf.array(); mArtDecoder.mDecodeBuffers.release(buf); }
public static Bitmap cropImage(String path, int top, int left, int right, int bottom) throws IOException { // only accept file path. if(path.startsWith("file:/")) { path = path.substring("file:/".length()); } BitmapRegionDecoder regionDecoder = BitmapRegionDecoder.newInstance(path, false); Rect rect = new Rect(left, top, right, bottom); return regionDecoder.decodeRegion(rect, new BitmapFactory.Options()); }
@TargetApi(Build.VERSION_CODES.N) private Palette getHotseatPalette() { WallpaperManager wallpaperManager = WallpaperManager.getInstance(this); if (AndroidVersion.isAtLeastNougat) { try (ParcelFileDescriptor fd = wallpaperManager .getWallpaperFile(WallpaperManager.FLAG_SYSTEM)) { BitmapRegionDecoder decoder = BitmapRegionDecoder .newInstance(fd.getFileDescriptor(), false); int height = decoder.getHeight(); Rect decodeRegion = new Rect(0, (int) (height * (1f - HOTSEAT_FRACTION)), decoder.getWidth(), height); Bitmap bitmap = decoder.decodeRegion(decodeRegion, null); decoder.recycle(); if (bitmap != null) { return Palette.from(bitmap).clearFilters().generate(); } } catch (IOException | NullPointerException e) { e.printStackTrace(); } } Bitmap wallpaper = ((BitmapDrawable) wallpaperManager.getDrawable()).getBitmap(); return Palette.from(wallpaper) .setRegion(0, (int) (wallpaper.getHeight() * (1f - HOTSEAT_FRACTION)), wallpaper.getWidth(), wallpaper.getHeight()) .clearFilters() .generate(); }
@TargetApi(Build.VERSION_CODES.N) private Palette getStatusBarPalette() { WallpaperManager wallpaperManager = WallpaperManager.getInstance(this); int statusBarHeight = getResources() .getDimensionPixelSize(R.dimen.status_bar_height); if (AndroidVersion.isAtLeastNougat) { try (ParcelFileDescriptor fd = wallpaperManager .getWallpaperFile(WallpaperManager.FLAG_SYSTEM)) { BitmapRegionDecoder decoder = BitmapRegionDecoder .newInstance(fd.getFileDescriptor(), false); Rect decodeRegion = new Rect(0, 0, decoder.getWidth(), statusBarHeight); Bitmap bitmap = decoder.decodeRegion(decodeRegion, null); decoder.recycle(); if (bitmap != null) { return Palette.from(bitmap).clearFilters().generate(); } } catch (IOException | NullPointerException e) { e.printStackTrace(); } } Bitmap wallpaper = ((BitmapDrawable) wallpaperManager.getDrawable()).getBitmap(); return Palette.from(wallpaper) .setRegion(0, 0, wallpaper.getWidth(), statusBarHeight) .clearFilters() .generate(); }
@Override public BitmapRegionDecoder chain(Uri uri) throws IOException{ if (mIndex >= mInterceptors.size()) { return null; } RealInterceptorChain next = new RealInterceptorChain(mInterceptors,mIndex+1,uri); Interceptor interceptor = mInterceptors.get(mIndex); return interceptor.intercept(next); }
public Bitmap getBitmapWith(InputStream inputStream, Rect rect) { try { BitmapRegionDecoder bitmapRegionDecoder = BitmapRegionDecoder.newInstance(inputStream, false); BitmapFactory.Options options = new BitmapFactory.Options(); options.inPreferredConfig = Bitmap.Config.RGB_565; Bitmap bitmap = bitmapRegionDecoder.decodeRegion(rect, options); return bitmap; } catch (IOException e) { e.printStackTrace(); } 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 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(); } }
/** * While there are decoders in the map, wait until each is available before acquiring, * recycling and removing it. After this is called, any call to {@link #acquire()} will * block forever, so this call should happen within a write lock, and all calls to * {@link #acquire()} should be made within a read lock so they cannot end up blocking on * the semaphore when it has no permits. */ private synchronized void recycle() { while (!decoders.isEmpty()) { BitmapRegionDecoder decoder = acquire(); decoder.recycle(); decoders.remove(decoder); } }
private synchronized BitmapRegionDecoder getNextAvailable() { for (Map.Entry<BitmapRegionDecoder, Boolean> entry : decoders.entrySet()) { if (!entry.getValue()) { entry.setValue(true); return entry.getKey(); } } return null; }
private synchronized boolean markAsUnused(BitmapRegionDecoder decoder) { for (Map.Entry<BitmapRegionDecoder, Boolean> entry : decoders.entrySet()) { if (decoder == entry.getKey()) { if (entry.getValue()) { entry.setValue(false); return true; } else { return false; } } } return false; }
public static BitmapRegionDecoder createBitmapRegionDecoder( ThreadPool.JobContext jc, String filePath, boolean shareable) { try { return BitmapRegionDecoder.newInstance(filePath, shareable); } catch (Throwable t) { Log.w(TAG, t); return null; } }
public static BitmapRegionDecoder createBitmapRegionDecoder( ThreadPool.JobContext jc, FileDescriptor fd, boolean shareable) { try { return BitmapRegionDecoder.newInstance(fd, shareable); } catch (Throwable t) { Log.w(TAG, t); return null; } }
public static BitmapRegionDecoder createBitmapRegionDecoder( ThreadPool.JobContext jc, InputStream is, boolean shareable) { try { return BitmapRegionDecoder.newInstance(is, shareable); } catch (Throwable t) { // We often cancel the creating of bitmap region decoder, // so just log one line. Log.w(TAG, "requestCreateBitmapRegionDecoder: " + t); return null; } }
public static SimpleBitmapRegionDecoderWrapper newInstance( InputStream is, boolean isShareable) { try { BitmapRegionDecoder d = BitmapRegionDecoder.newInstance(is, isShareable); if (d != null) { return new SimpleBitmapRegionDecoderWrapper(d); } } catch (IOException e) { Log.w("BitmapRegionTileSource", "getting decoder failed", e); return null; } return null; }
@Override public Point init(Context context, Uri uri) throws Exception { InputStream inputStream = context.getContentResolver().openInputStream(uri); decoder = BitmapRegionDecoder.newInstance(inputStream, false); options = new BitmapFactory.Options(); boolean use8BitColor = Settings.getInstance(context).use8BitColor(); options.inPreferredConfig = use8BitColor ? Bitmap.Config.ARGB_8888 : Bitmap.Config.RGB_565; return new Point(this.decoder.getWidth(), this.decoder.getHeight()); }
@TargetApi(10) private Bitmap decodeRegionCrop(ImageViewTouch cropImage) { int width = initWidth > initHeight ? initHeight : initWidth; int screenWidth = DemoApplication.getApp().getScreenWidth(); float scale = cropImage.getScale() / getImageRadio(); RectF rectf = cropImage.getBitmapRect(); int left = -(int) (rectf.left * width / screenWidth / scale); int top = -(int) (rectf.top * width / screenWidth / scale); int right = left + (int) (width / scale); int bottom = top + (int) (width / scale); Rect rect = new Rect(left, top, right, bottom); InputStream is = null; System.gc(); Bitmap croppedImage = null; try { ByteArrayOutputStream baos = new ByteArrayOutputStream(); oriBitmap.compress(Bitmap.CompressFormat.JPEG, 100, baos); is = new ByteArrayInputStream(baos.toByteArray()); BitmapRegionDecoder decoder = BitmapRegionDecoder.newInstance(is, false); croppedImage = decoder.decodeRegion(rect, new BitmapFactory.Options()); } catch (Throwable e) { } finally { IOUtil.closeStream(is); } return croppedImage; }
public TileImage getTileImage() { if (mIsGif) { return null; } InputStream inputStream = getInputStream(); if (inputStream != null) { BitmapFactory.Options options = new BitmapFactory.Options(); options.inJustDecodeBounds = true; BitmapFactory.decodeStream(inputStream, null, options); closeSilently(inputStream); int width = options.outWidth; int height = options.outHeight; if (width <= 0 || height <= 0) { return null; } inputStream = getInputStream(); try { BitmapRegionDecoder bitmapRegionDecoder = BitmapRegionDecoder.newInstance(inputStream, false); closeSilently(inputStream); inputStream = getInputStream(); int orientation = OrientationInfoUtility.getOrientation(inputStream); closeSilently(inputStream); return TileImage.newInstance(width, height, orientation, bitmapRegionDecoder); } catch (IOException e) { e.printStackTrace(); } } return null; }
public static TileImage newInstance(int width, int height, @OrientationInfoUtility.ORIENTATION_ROTATE int orientation, BitmapRegionDecoder bitmapRegionDecoder) { TileImage image = new TileImage(); image.mWidth = width; image.mHeight = height; image.mOrientation = orientation; image.mBitmapRegionDecoder = bitmapRegionDecoder; return image; }