Android: PNG Transparency Failing with BitmapFactory.decodeStream(...) and Assets Folder
Asked Answered
F

2

9

I am using the following method to pull a PNG file from the assets folder in my Android application:

public static Bitmap getBitmapFromAssets(Context context, String fileName) {
        try {
            AssetManager assetManager = context.getAssets();
            InputStream inputStream = assetManager.open(fileName);
            Bitmap bitmap = BitmapFactory.decodeStream(inputStream);
            return bitmap;
        }
        catch(Exception ex) {
            ex.printStackTrace();
            return null;
        }
    }

I am then setting the source of an ImageView, in the item of a GridView, to that Bitmap.

Here is the layout XML in question:

<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/containingLayout"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:orientation="horizontal"
    android:gravity="center_horizontal"
    android:background="@android:color/transparent"
    android:padding="0dp"
    android:layout_margin="0dp"
>
    <ImageView
        android:id="@+id/ivPackageIcon"
        style="@style/smLargeGridItemPackageIconStyle"
    />
</LinearLayout>

And the style referred to in that XML is:

<style name="smLargeGridItemPackageIconStyle">
        <item name="android:scaleType">fitXY</item>
        <item name="android:layout_width">100dp</item>
        <item name="android:layout_height">142dp</item>
        <item name="android:layout_margin">5dp</item>
        <item name="android:background">@android:color/transparent</item>
    </style>

Here is the code that sets the source of the ImageView:

ImageView ivPackageIcon = (ImageView)containingView.findViewById(R.id.ivPackageIcon);
        if(ivPackageIcon != null) {
            Bitmap coverImage = getBitmapFromAssets(containingView.getContext(), "myimage.png");
            ivPackageIcon.setImageBitmap(coverImage);
        }

The PNG image has some transparent areas, but for some reason when the image is displayed in my GridView, the transparent areas come through as black.

To preempt some questions: No, the background of the Activity, ImageView, GridView, and GridView item are not black. As a matter of fact, no matter what the background colors are set to, the transparent parts of the image always come through as black.

Consider this, though...If I place the PNG image in the drawable folder and set the ImageView as follows, the transparency is perfect:

ivPackageIcon.setImageResource(R.drawable.myimage);

I'm pretty sure that I'm using the decodeStream(...) method incorrectly somehow, but I don't know what I'm doing wrong. I even modified my original method to set some options as shown here:

public static Bitmap getBitmapFromAssets(Context context, String fileName) {
        try {
            AssetManager assetManager = context.getAssets();
            InputStream inputStream = assetManager.open(fileName);

            BitmapFactory.Options options = new BitmapFactory.Options();
            options.inDither = true;
            options.inPreferredConfig = Config.ARGB_8888;

            Bitmap bitmap = BitmapFactory.decodeStream(inputStream, null, options);
            return bitmap;
        }
        catch(Exception ex) {
            ex.printStackTrace();
            return null;
        }
    }

But that gave me the same poor result.

Any ideas, anyone?

Thank you.

Few answered 1/2, 2012 at 7:3 Comment(1)
Seems like you're losing your alpha channel. Can you dump the pixels in the Bitmap object (after decoding) and check that you have the correct alpha values in transparent areas? Use Bitmap.getPixels().Langford
E
0

Instead this, try:

ImageView img=new ImageView(this);
        Drawable d = Drawable.createFromStream(getAssets().open(path_in_assets), null);
        img.setImageDrawable(d);
Exmoor answered 4/6, 2013 at 18:57 Comment(1)
fyi, Android Studio throws an error message on the above. It suggests adding the code inside a try/catch block to be able to handle any IOExceptions.Delivery
I
0

In case your image is made out of application resource and it is placed under res/drawable/ instead of one of the specific resolution folders (e.g. res/drawable-hdpi)

The android compiler is optimizing the PNG so the transparent pixels are made white (or black in case of GIFF files)

Resolution: move your PNG file to res/drawable-hdpi or one of the other drawable folders, and you should be OK.

Ivetteivetts answered 31/3, 2015 at 12:56 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.