Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 8889385
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 14, 20262026-06-14T22:14:59+00:00 2026-06-14T22:14:59+00:00

Edit one: Changes made based on Joseph’s answer: In bytesToDrawable(byte[] imageBytes): Changed the following

  • 0

Edit one:

Changes made based on Joseph’s answer:

In bytesToDrawable(byte[] imageBytes):

Changed the following : Using BitmapDrawable(Resources res, Bitmap bitmap) instead of BitmapDrawable(Bitmap bitmap):

return new BitmapDrawable(ApplicationConstants.ref_currentActivity.getResources(),BitmapFactory.decodeByteArray(imageBytes, 0, imageBytes.length, options));

This is the result of that change: Slightly Different Problem:

enter image description here

Question:

If I’m using the new constructor for bitmap drawable and it scales images for the required target density, do I need to use my calculateSampleSize method still?


Original Question:

Hi friends,

My application is module based and thus images specific to that module are only loaded from the jar(module) that contains them, and not from the main application.

Each module has its own ModularImageLoader – which basically allows me to fetch Drawables based on the name of the image found in the jar.

The constructor takes in the zipFile(Module A) and a list of filesnames(any file ending with “.png” from the zip).

Research Conducted:

I have used the following: Link to Developer Page on Loading bitmaps efficiently

Initially I was creating images sized for each density, but now I just have one set of image icons sized 96×96.

If the screen density is less than xhdpi, I load smaller sampled sizes of the 96×96 image – as 36×36(for ldpi), 48×48(for mdpi), 72×72(for hdpi). Otherwise I just return the 96×96 image. (Look at method calculateSampleSize() and bytesToDrawable())

I think its easier to understand the concept with the code: So here’s ModularImageLoader

Code:

public class ModularImageLoader
{
    public static HashMap<String, Drawable> moduleImages = new HashMap<String, Drawable>();
    public static int reqHeight = 0;
    public static int reqWidth = 0;
    public ModularImageLoader(ZipFile zip, ArrayList<String> fileNames)
    {
         float sdpi = ApplicationConstants.ref_currentActivity.getResources().getDisplayMetrics().density;
         if(sdpi == 0.75)
         {
            reqHeight = 36;
            reqWidth = 36;
         }
         else if(sdpi == 1.0)
         {
            reqHeight = 48;
            reqWidth = 48;
         }
         else if (sdpi == 1.5)
         {
            reqHeight = 72;
            reqWidth = 72;
         }
         else if (sdpi == 2.0)
         {
            reqHeight = 96;
            reqWidth = 96;
          }
          String names = "";
          for(String fileName : fileNames)
          {
            names += fileName + " ";
          }
          createByteArrayImages(zip, fileNames);
     }

public static Drawable findImageByName(String imageName)
{
    Drawable drawableToReturn = null;
    for (Entry<String, Drawable> ent : moduleImages.entrySet())
    {
        if(ent.getKey().equals(imageName))
        {
            drawableToReturn = ent.getValue();
        }
    }
    return drawableToReturn;
}
private static void createByteArrayImages(ZipFile zip, ArrayList<String> fileNames)
{
    InputStream in = null;
    byte [] temp = null;
    int nativeEndBufSize = 0;
    for(String fileName : fileNames)
    {
        try
        {
            in = zip.getInputStream(zip.getEntry(fileName));
            nativeEndBufSize = in.available();
            temp = toByteArray(in,nativeEndBufSize);

            // get rid of .png
            fileName = fileName.replace(".png", "");
            fileName = fileName.replace("Module Images/", "");
            moduleImages.put(fileName, bytesToDrawable(temp));
        }
        catch(Exception e)
        {
            System.out.println("getImageBytes() threw an exception: " + e.toString());
            e.printStackTrace();
        }
    }
    try
    {
        in.close();
    }
    catch (IOException e)
    {
        System.out.println("Unable to close inputStream!");
        e.toString();
        e.printStackTrace();
    }
}
public static byte[] toByteArray(InputStream is, int length) throws IOException 
{
    ByteArrayOutputStream buffer = new ByteArrayOutputStream();
    int l;
    byte[] data = new byte[length];
    while ((l = is.read(data, 0, data.length)) != -1) 
    {
      buffer.write(data, 0, l);
    }
    buffer.flush();
    return buffer.toByteArray();
}
public static Drawable bytesToDrawable(byte[] imageBytes)
{
    try
    {
        BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true;
        int imageHeight = options.outHeight;
        int imageWidth = options.outWidth;

        BitmapFactory.decodeByteArray(imageBytes, 0, imageBytes.length, options);
        String imageType = options.outMimeType;
        Log.d("ImageInfo : ", "Height:" + imageHeight +",Width:" +imageWidth + ",Type:" + imageType);

        options.inJustDecodeBounds = false;
        //Calculate sample size
        options.inSampleSize = calculateSampleSize(options);
        return new BitmapDrawable(BitmapFactory.decodeByteArray(imageBytes, 0, imageBytes.length, options));
    }
    catch(Exception e)
    {
        Message.errorMessage("Module Loading Error", "The images in this module are too large to load onto cell memory. Please contact your administrator",
                "Source of error: ModularImageLoader - bytesToDrawable method", e.toString());
        return null;
    }
}
public static int calculateSampleSize(BitmapFactory.Options options)
{
    // raw height and width of the image itself
    int sampleSize = 1;
    int height = options.outHeight;
    int width = options.outWidth;
    if(height > reqHeight || width > reqWidth)
    {
        if(width > height)
        {
            sampleSize = Math.round((float)height / (float)reqHeight);
        }
        else
        {
            sampleSize = Math.round((float)width / (float)reqWidth);
        }
    }
    return sampleSize;
}
}

Problem:

The image below shows 4 running emulators, these are their specifications and how I set them in the eclipse AVD:

LDPI: density 120, Skin QVGA
MDPI: density 160, Skin HVGA
HDPI: density 240, Skin WVGA800
XHDPI:density 320, Skin 800×1280

Image Showing Problem:

enter image description here

Question:

Based on the code – in the XHDPI window, why is the contacts image so tiny? The News image is also 96×96 (Except its loaded from the main application – so its under res>XHDPI).
The thing is, I see it loading fine for MDPI screens and HDPI screens, but its weird for the rest. Any ideas?

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-14T22:15:00+00:00Added an answer on June 14, 2026 at 10:15 pm

    ldpi – 36×36
    mdpi – 48×48
    hdpi – 72×72
    xhdpi – 96×96

    It would be great if these were all pure multiples of each other as the bitmap factory handles sample size in integers and therefore the sample size needs to be a whole number (no trailing decimals to be fully accurate).

    The solution:

    Before I started sampling, I had 1 image for “every” screen type, and if that image had a pressed state, I’d have 2 separate images for that.

    Therefore for one image – I actually needed 4 in the application, and if that image had pressed states – one image would need 8 images.

    My main aim was to cut down on the number of images, so that I don’t overload the bitmap heap allocation and possibly throw a out of memory exception, I’ve seen this exception thrown for me, when my bitmap size is perfectly reasonable (I believe its something to do with the number of images on the heap as well as their respective images sizes (correct me if I’m wrong please..)) and I wanted to of course, cut down on my module size.

    So I decided on this:
    Have 2 images for each image – one in size 72 and one in size 96 – this way I’d have the icons I needed for screens with xhdpi and hdpi density, and I could sample(simply) down to ldpi and mdpi when required.

    72/2 = 36
    96/2 = 48

    This way I’d only have 2 images for every image and worst case, if that image had pressed states, I’d have 4 images.
    That’s cutting down the image size bank by almost 50% and making my modules a lot smaller. I noticed a change in module size from 525 kb to about 329.

    This really was what I was aiming for.

    Thanks everyone for all the help! If anyone has any questions, please feel free to leave comments and I will get back to you as soon as I can.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

Is there any external library using which one can edit and save XML files
I have following function in one Activity public void AppExit() { Editor edit =
On one of my packages, which was adapted from another using Save-As and edit,
I'm using a text file to save the changes made by a user on
I have 2 customer views one for create and one for edit. I am
I am creating a login register page which contains two edit text boxes(one for
[edit] So I used one of the javascript tooltips suggested below. I got the
EDIT I'm looking for the actual one or two liner that does what the
Edit 4/4/12 I STILL HAVE ONE QUESTION: I solved my issue but it adds
edit: I completely rewrote the question as the original one didn't clearly explain my

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.