Created
November 9, 2017 10:40
-
-
Save davemorrissey/1f247d415e21ed10fddfd7fee49b4ff3 to your computer and use it in GitHub Desktop.
Subsampling Scale Image View Input Stream Decoder
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.davemorrissey.labs.subscaleview.decoder.inputstream; | |
import android.content.Context; | |
import android.graphics.Bitmap; | |
import android.graphics.Bitmap.Config; | |
import android.graphics.BitmapFactory; | |
import android.graphics.BitmapRegionDecoder; | |
import android.net.Uri; | |
import com.davemorrissey.labs.subscaleview.decoder.DecoderFactory; | |
import com.davemorrissey.labs.subscaleview.decoder.ImageDecoder; | |
import com.davemorrissey.labs.subscaleview.decoder.ImageRegionDecoder; | |
import java.io.InputStream; | |
import java.lang.reflect.InvocationTargetException; | |
public class InputStreamImageDecoder implements ImageDecoder { | |
public static class Factory implements DecoderFactory<InputStreamImageDecoder> { | |
private final InputStream inputStream; | |
private final Config bitmapConfig; | |
public Factory(InputStream inputStream) { | |
this(inputStream, null); | |
} | |
public Factory(InputStream inputStream, Config bitmapConfig) { | |
this.inputStream = inputStream; | |
this.bitmapConfig = bitmapConfig; | |
} | |
@Override | |
public InputStreamImageDecoder make() throws IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException { | |
return new InputStreamImageDecoder(inputStream, bitmapConfig); | |
} | |
} | |
private final InputStream inputStream; | |
private final Config bitmapConfig; | |
private InputStreamImageDecoder(InputStream inputStream, Config bitmapConfig) { | |
this.inputStream = inputStream; | |
if (bitmapConfig == null) { | |
this.bitmapConfig = Config.RGB_565; | |
} else { | |
this.bitmapConfig = bitmapConfig; | |
} | |
} | |
@Override | |
public Bitmap decode(Context context, Uri uri) throws Exception { | |
BitmapFactory.Options options = new BitmapFactory.Options(); | |
options.inPreferredConfig = bitmapConfig; | |
return BitmapFactory.decodeStream(inputStream, null, options); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.davemorrissey.labs.subscaleview.decoder.inputstream; | |
import android.content.Context; | |
import android.graphics.Bitmap; | |
import android.graphics.Bitmap.Config; | |
import android.graphics.BitmapFactory; | |
import android.graphics.BitmapRegionDecoder; | |
import android.graphics.Point; | |
import android.graphics.Rect; | |
import android.net.Uri; | |
import com.davemorrissey.labs.subscaleview.decoder.DecoderFactory; | |
import com.davemorrissey.labs.subscaleview.decoder.ImageRegionDecoder; | |
import java.io.InputStream; | |
import java.lang.reflect.InvocationTargetException; | |
/** | |
* Default implementation of {@link ImageRegionDecoder} | |
* using Android's {@link BitmapRegionDecoder}, based on the Skia library. This | |
* works well in most circumstances and has reasonable performance due to the cached decoder instance, | |
* however it has some problems with grayscale, indexed and CMYK images. | |
*/ | |
public class InputStreamImageRegionDecoder implements ImageRegionDecoder { | |
public static class Factory implements DecoderFactory<InputStreamImageRegionDecoder> { | |
private final InputStream inputStream; | |
private final Config bitmapConfig; | |
public Factory(InputStream inputStream) { | |
this(inputStream, null); | |
} | |
public Factory(InputStream inputStream, Config bitmapConfig) { | |
this.inputStream = inputStream; | |
this.bitmapConfig = bitmapConfig; | |
} | |
@Override | |
public InputStreamImageRegionDecoder make() throws IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException { | |
return new InputStreamImageRegionDecoder(inputStream, bitmapConfig); | |
} | |
} | |
private BitmapRegionDecoder decoder; | |
private final Object decoderLock = new Object(); | |
private final InputStream inputStream; | |
private final Config bitmapConfig; | |
private InputStreamImageRegionDecoder(InputStream inputStream, Config bitmapConfig) { | |
this.inputStream = inputStream; | |
if (bitmapConfig == null) { | |
this.bitmapConfig = Config.RGB_565; | |
} else { | |
this.bitmapConfig = bitmapConfig; | |
} | |
} | |
@Override | |
public Point init(Context context, Uri uri) throws Exception { | |
decoder = BitmapRegionDecoder.newInstance(inputStream, false); | |
return new Point(decoder.getWidth(), decoder.getHeight()); | |
} | |
@Override | |
public Bitmap decodeRegion(Rect sRect, int sampleSize) { | |
synchronized (decoderLock) { | |
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; | |
} | |
} | |
@Override | |
public boolean isReady() { | |
return decoder != null && !decoder.isRecycled(); | |
} | |
@Override | |
public void recycle() { | |
decoder.recycle(); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class MyActivity { | |
@Override | |
protected void onCreate(@Nullable Bundle savedInstanceState) { | |
try { | |
InputStream is = getAssets().open("card.png", AssetManager.ACCESS_RANDOM); | |
SubsamplingScaleImageView view = findViewById(id.imageView); | |
view.setBitmapDecoderFactory(new InputStreamImageDecoder.Factory(is)); | |
view.setRegionDecoderFactory(new InputStreamImageRegionDecoder.Factory(is)); | |
view.setImage(ImageSource.asset("dummy")); | |
} catch (Exception e) { | |
// ... | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment