diff options
Diffstat (limited to 'engine/src/android/com/jme3/asset/AndroidImageInfo.java')
-rw-r--r-- | engine/src/android/com/jme3/asset/AndroidImageInfo.java | 101 |
1 files changed, 101 insertions, 0 deletions
diff --git a/engine/src/android/com/jme3/asset/AndroidImageInfo.java b/engine/src/android/com/jme3/asset/AndroidImageInfo.java new file mode 100644 index 0000000..c8eb539 --- /dev/null +++ b/engine/src/android/com/jme3/asset/AndroidImageInfo.java @@ -0,0 +1,101 @@ +package com.jme3.asset; + +import android.graphics.Bitmap; +import android.graphics.BitmapFactory; +import android.graphics.Matrix; +import com.jme3.texture.Image; +import com.jme3.texture.Image.Format; +import java.io.IOException; +import java.io.InputStream; + +/** + * <code>AndroidImageInfo</code> is set in a jME3 image via the {@link Image#setEfficientData(java.lang.Object)} + * method to retrieve a {@link Bitmap} when it is needed by the renderer. + * User code may extend <code>AndroidImageInfo</code> and provide their own implementation of the + * {@link AndroidImageInfo#loadBitmap()} method to acquire a bitmap by their own means. + * + * @author Kirill Vainer + */ +public class AndroidImageInfo { + + protected AssetInfo assetInfo; + protected Bitmap bitmap; + protected Format format; + + public AndroidImageInfo(AssetInfo assetInfo) { + this.assetInfo = assetInfo; + } + + public Bitmap getBitmap(){ + if (bitmap == null || bitmap.isRecycled()){ + try { + loadBitmap(); + } catch (IOException ex) { + // If called first inside AssetManager, the error will propagate + // correctly. Assuming that if the first calls succeeds + // then subsequent calls will as well. + throw new AssetLoadException("Failed to load image " + assetInfo.getKey(), ex); + } + } + return bitmap; + } + + + + public Format getFormat(){ + return format; + } + + /** + * Loads the bitmap directly from the asset info, possibly updating + * or creating the image object. + */ + protected void loadBitmap() throws IOException{ + InputStream in = null; + try { + in = assetInfo.openStream(); + bitmap = BitmapFactory.decodeStream(in); + if (bitmap == null) { + throw new IOException("Failed to load image: " + assetInfo.getKey().getName()); + } + } finally { + if (in != null) { + in.close(); + } + } + + switch (bitmap.getConfig()) { + case ALPHA_8: + format = Image.Format.Alpha8; + break; + case ARGB_4444: + format = Image.Format.ARGB4444; + break; + case ARGB_8888: + format = Image.Format.RGBA8; + break; + case RGB_565: + format = Image.Format.RGB565; + break; + default: + // This should still work as long + // as renderer doesn't check format + // but just loads bitmap directly. + format = null; + } + + TextureKey texKey = (TextureKey) assetInfo.getKey(); + if (texKey.isFlipY()) { + // Flip the image, then delete the old one. + Matrix flipMat = new Matrix(); + flipMat.preScale(1.0f, -1.0f); + Bitmap newBitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), flipMat, false); + bitmap.recycle(); + bitmap = newBitmap; + + if (bitmap == null) { + throw new IOException("Failed to flip image: " + texKey); + } + } + } +} |