AndroidImageInfo.java 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. package com.jme3.asset;
  2. import android.graphics.Bitmap;
  3. import android.graphics.BitmapFactory;
  4. import android.graphics.Matrix;
  5. import com.jme3.texture.Image;
  6. import com.jme3.texture.Image.Format;
  7. import java.io.IOException;
  8. import java.io.InputStream;
  9. import java.util.logging.Level;
  10. import java.util.logging.Logger;
  11. /**
  12. * <code>AndroidImageInfo</code> is set in a jME3 image via the {@link Image#setEfficentData(java.lang.Object) }
  13. * method to retrieve a {@link Bitmap} when it is needed by the renderer.
  14. * User code may extend <code>AndroidImageInfo</code> and provide their own implementation of the
  15. * {@link AndroidImageInfo#loadBitmap()} method to acquire a bitmap by their own means.
  16. *
  17. * @author Kirill Vainer
  18. */
  19. public class AndroidImageInfo {
  20. private static final Logger logger = Logger.getLogger(AndroidImageInfo.class.getName());
  21. protected AssetInfo assetInfo;
  22. protected Bitmap bitmap;
  23. protected Format format;
  24. public AndroidImageInfo(AssetInfo assetInfo) {
  25. this.assetInfo = assetInfo;
  26. }
  27. public Bitmap getBitmap(){
  28. if (bitmap == null || bitmap.isRecycled()){
  29. try {
  30. loadBitmap();
  31. } catch (IOException ex) {
  32. // If called first inside AssetManager, the error will propagate
  33. // correctly. Assuming that if the first calls succeeds
  34. // then subsequent calls will as well.
  35. throw new AssetLoadException("Failed to load image " + assetInfo.getKey(), ex);
  36. }
  37. }
  38. return bitmap;
  39. }
  40. public void notifyBitmapUploaded() {
  41. // Default function is to recycle the bitmap.
  42. if (bitmap != null && !bitmap.isRecycled()) {
  43. bitmap.recycle();
  44. bitmap = null;
  45. logger.log(Level.INFO, "Bitmap was deleted. ");
  46. }
  47. }
  48. public Format getFormat(){
  49. return format;
  50. }
  51. /**
  52. * Loads the bitmap directly from the asset info, possibly updating
  53. * or creating the image object.
  54. */
  55. protected void loadBitmap() throws IOException{
  56. InputStream in = null;
  57. try {
  58. in = assetInfo.openStream();
  59. bitmap = BitmapFactory.decodeStream(in);
  60. if (bitmap == null) {
  61. throw new IOException("Failed to load image: " + assetInfo.getKey().getName());
  62. }
  63. } finally {
  64. if (in != null) {
  65. in.close();
  66. }
  67. }
  68. switch (bitmap.getConfig()) {
  69. case ALPHA_8:
  70. format = Image.Format.Alpha8;
  71. break;
  72. case ARGB_4444:
  73. format = Image.Format.ARGB4444;
  74. break;
  75. case ARGB_8888:
  76. format = Image.Format.RGBA8;
  77. break;
  78. case RGB_565:
  79. format = Image.Format.RGB565;
  80. break;
  81. default:
  82. // This should still work as long
  83. // as renderer doesn't check format
  84. // but just loads bitmap directly.
  85. format = null;
  86. }
  87. TextureKey texKey = (TextureKey) assetInfo.getKey();
  88. if (texKey.isFlipY()) {
  89. // Flip the image, then delete the old one.
  90. Matrix flipMat = new Matrix();
  91. flipMat.preScale(1.0f, -1.0f);
  92. Bitmap newBitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), flipMat, false);
  93. bitmap.recycle();
  94. bitmap = newBitmap;
  95. if (bitmap == null) {
  96. throw new IOException("Failed to flip image: " + texKey);
  97. }
  98. }
  99. }
  100. }