Shimon Shnitzer
Shimon Shnitzer

Reputation: 183

Can BitmapFactory.decodeFile handle .ICO (Windows icons) files?

I am working on Android. Trying to display the "favicon" (aka "shortcut icon") or web pages.

So I already have the code to get the URL of this icon from any website, and download it onto my Android.

Now I am trying to make a Bitmap out of it, but always get null as a result.

The code:

String src = String.format("file:///data/data/com.intuitiveui.android/files/%s",prefName);
// prefName is "facebook.ico", and I do see tht file in my DDMS file browser. It's
// a valid icon file.

Bitmap res = BitmapFactory.decodeFile(src);
// This returns null

TIA

Upvotes: 0

Views: 6796

Answers (6)

user10428958
user10428958

Reputation:

I was also stuck with this since Picasso didn't seem to parse .ico files. Surprisingly however, the solution is fairly simple.

InputStream in = new java.net.URL("https://" + domain + "/favicon.ico").openStream();
Bitmap b = BitmapFactory.decodeStream(in);

For me, this solution works with most of the websites but produces an empty bitmap whenever the size of the icon file is exceptionally low.

Upvotes: 0

cmoaciopm
cmoaciopm

Reputation: 2256

No accepted answer util now, I will share my findings here.

Windows .ico file format is a little complicated, it might contains one or more small images at multiple sizes and color depths, such that they may be scaled appropriately. Refer ICO_(file_format)

So when using unix "file" command to check the icon file type, you might get the following result:

  • a.ico : MS Windows icon resource - 1 icon, 32x32
  • b.ico : MS Windows icon resource - 9 icons, 256x256

Note a.ico and b.ico contains different number of icons.

I tried to use BitmapFactory.decodeFile to decode these icons.

  • Two Android devices with Android 4.3 can only decode a.ico, but can not decode b.ico.
  • Devices with Android 4.4 or later can decode both a.ico and b.ico.

As I only have limited Android devices, I can't give any conclusion. Maybe anyone else could help.

So if you really want to decode .ico files, you may try:

  • Create .ico files with only 1 image/picture in it
  • Write your own .ico decoder or 3rd library like image4j

Upvotes: 0

David Webb
David Webb

Reputation: 193714

The WebView component has a getFavicon() method so it's definitely possible to decode ICO files in Android. You could have a look at the Android source to see how ICO files are parsed. I've had a quick look but can't find the relevant part.

Alternatively, you should be use the SDK to get favicons for you. However, I've had a quick try and can't get it to work.

For what it's worth here's my test code, noting again that this doesn't work:

    String url = "http://stackoverflow.com";
    WebView wv = new WebView(this);
    wv.setWebViewClient(new WebViewClient() {
        @Override
        public void onPageFinished(WebView view, String url) {
            Log.i("HelloAndroid","Loaded " + url);              
            Log.i("HelloAndroid","Icon " + (view.getFavicon() == null ? "not" : "") + " found");
        }

    });
    WebIconDatabase wid = WebIconDatabase.getInstance();
    wid.requestIconForPageUrl(url, new WebIconDatabase.IconListener() {
        public void onReceivedIcon(String url, Bitmap icon) {
            Log.i("HelloAndroid","Found Icon for " + url);
        }
    });
    wv.loadUrl("http://stackoverflow.com");
    Log.i("HelloAndroid","Loading " + url);

The problem may be down to the fact that I'm not adding the WebView to a visible View. If you do get this to work I'd be interested to hear what you did.

So sorry for giving two half complete answers, but I thought it was worth posting what I found.

Upvotes: 1

artsylar
artsylar

Reputation: 2678

SKIA library provides decoder class for ICO file. I was able to display an ICO file in the emulator. Haven't tried it yet in an actual android device though.

Bitmap bmap = BitmapFactory.decodeFile("/sdcard/vlc.ico");

Upvotes: 2

diexsie
diexsie

Reputation: 77

I had a similar problem. BitmapFactory.decode decoded *.ico on emulator but not on my Galaxy S. Solution for me was:

                ByteArrayOutputStream bos = new ByteArrayOutputStream();
                int read=0;
                while((read = inputStream.read()) != -1){
                     bos.write(read);
                }

                byte[] ba = bos.toByteArray(); 
                Bitmap icon = BitmapFactory.decodeByteArray(ba, 0, ba.length);//new FlushedInputStream(inputStream));

Upvotes: 1

CommonsWare
CommonsWare

Reputation: 1007099

Here is a list of the supported Android media formats. ICO is not among them. You might be able to find a Java-based ICO decoder, though.

Upvotes: 4

Related Questions