SkiaImageDecoder.java 3.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  1. package com.davemorrissey.labs.subscaleview.decoder;
  2. import android.content.ContentResolver;
  3. import android.content.Context;
  4. import android.content.pm.PackageManager;
  5. import android.content.res.Resources;
  6. import android.graphics.Bitmap;
  7. import android.graphics.BitmapFactory;
  8. import android.net.Uri;
  9. import android.text.TextUtils;
  10. import java.io.InputStream;
  11. import java.util.List;
  12. /**
  13. * Default implementation of {@link com.davemorrissey.labs.subscaleview.decoder.ImageDecoder}
  14. * using Android's {@link android.graphics.BitmapFactory}, based on the Skia library. This
  15. * works well in most circumstances and has reasonable performance, however it has some problems
  16. * with grayscale, indexed and CMYK images.
  17. */
  18. public class SkiaImageDecoder implements ImageDecoder {
  19. private static final String FILE_PREFIX = "file://";
  20. private static final String ASSET_PREFIX = FILE_PREFIX + "/android_asset/";
  21. private static final String RESOURCE_PREFIX = ContentResolver.SCHEME_ANDROID_RESOURCE + "://";
  22. @Override
  23. public Bitmap decode(Context context, Uri uri) throws Exception {
  24. String uriString = uri.toString();
  25. BitmapFactory.Options options = new BitmapFactory.Options();
  26. Bitmap bitmap;
  27. options.inPreferredConfig = Bitmap.Config.RGB_565;
  28. if (uriString.startsWith(RESOURCE_PREFIX)) {
  29. Resources res;
  30. String packageName = uri.getAuthority();
  31. if (context.getPackageName().equals(packageName)) {
  32. res = context.getResources();
  33. } else {
  34. PackageManager pm = context.getPackageManager();
  35. res = pm.getResourcesForApplication(packageName);
  36. }
  37. int id = 0;
  38. List<String> segments = uri.getPathSegments();
  39. int size = segments.size();
  40. if (size == 2 && segments.get(0).equals("drawable")) {
  41. String resName = segments.get(1);
  42. id = res.getIdentifier(resName, "drawable", packageName);
  43. } else if (size == 1 && TextUtils.isDigitsOnly(segments.get(0))) {
  44. try {
  45. id = Integer.parseInt(segments.get(0));
  46. } catch (NumberFormatException ignored) {
  47. }
  48. }
  49. bitmap = BitmapFactory.decodeResource(context.getResources(), id, options);
  50. } else if (uriString.startsWith(ASSET_PREFIX)) {
  51. String assetName = uriString.substring(ASSET_PREFIX.length());
  52. bitmap = BitmapFactory.decodeStream(context.getAssets().open(assetName), null, options);
  53. } else if (uriString.startsWith(FILE_PREFIX)) {
  54. bitmap = BitmapFactory.decodeFile(uriString.substring(FILE_PREFIX.length()), options);
  55. } else {
  56. InputStream inputStream = null;
  57. try {
  58. ContentResolver contentResolver = context.getContentResolver();
  59. inputStream = contentResolver.openInputStream(uri);
  60. bitmap = BitmapFactory.decodeStream(inputStream, null, options);
  61. } finally {
  62. if (inputStream != null) {
  63. try { inputStream.close(); } catch (Exception e) { }
  64. }
  65. }
  66. }
  67. if (bitmap == null) {
  68. throw new RuntimeException("Skia image region decoder returned null bitmap - image format may not be supported");
  69. }
  70. return bitmap;
  71. }
  72. }