I downloaded data from google.com/favicon.ico and saved it in a file "icon.png" using the following:

URL url=new URL("http://www.google.com/favicon.ico");
InputStream ss=url.openStream();
byte bytes[]=new byte[100000];
int offset = 0;
int numRead = 0;
while (offset < bytes.length && (numRead=ss.read(bytes, offset, bytes.length-offset)) >= 0) {
   offset += numRead;
}
FileOutputStream out=new FileOutputStream("icon.png");
out.write(bytes);

Now, icon.png opens normally and shows the google icon. The catch is that when I try to set it as an icon in Qt Jambi, it fails to show up, whereas if I download some icons the normal way, they get loaded properly. My question is that is there any difference between the two ?

Dani AI

Generated

was right that the favicon you grabbed isn’t necessarily a PNG. A key extra detail: ICO files can contain multiple images and, since Windows Vista, may embed PNG-encoded images inside the .ico container. Some image loaders (or older plugin builds) only handle the older BMP-style ICO entries, so an ICO that embeds a PNG can open in some viewers but fail in others. (axialis.com)

Quick checks and a safe download pattern

  • Make sure you save the bytes you actually read (don’t write a fixed-size buffer wholesale). Use a streaming copy that writes only the bytes returned by read(). For example:
try (InputStream in = url.openStream();
     OutputStream out = new FileOutputStream("favicon.ico")) {
    byte[] buf = new byte[8192];
    int n;
    while ((n = in.read(buf)) != -1) {
        out.write(buf, 0, n);
    }
}
  • Save as .ico (not .png) while testing: Qt’s QImageReader probes suffixes and plugins first, so the filename can influence which plugin is tried. If autodetection fails, force a content-based check. (doc.qt.io)

Programmatic fixes (portable)

  • If you need a PNG at runtime, convert the ICO on the fly with a Java library that explicitly supports Vista-style (PNG-embedded) ICOs, for example image4j or Apache Commons Imaging. A minimal flow: decode the ICO to BufferedImages, pick the desired size, then write a PNG with ImageIO. (image4j.sourceforge.net)

Troubleshooting checklist

  • Inspect the file header/magic bytes to confirm ICO vs PNG.
  • If a library fails, try a different ICO reader (some handle PNG-in-ICO, others don’t).
  • Converting to PNG before handing the image to Qt is the most portable fix across platforms and plugin sets.

References: image4j, Apache Commons Imaging, Qt QImageReader docs, and Vista‑icon notes. (image4j.sourceforge.net)

Recommended Answers

All 10 Replies

The problem is in your assumption that a favicon for a site is always a PNG image, which isn't the case. Normally sites use a ICO image format, which is a different image format than PNG or BMP. Read more here.

To confirm this, try downloading the Daniweb favicon and setting it up in Qt Jambi, it should work (assuming Jambi supports BMP). The same shouldn't work with Yahoo, Microsoft or any other sites' favicon.

Thanks.

I found a favicon at the url : http://www.daniweb.com/favicon.ico The extension suggests that it also is an ico image. I tried ..../favicon.jpeg and ..../favicon.png but tha pages don't exist.

In the plugins directory of QtJambi, inside the iamgeformats folder, I found th following:

1.
2.
3.
4.
5.
6.

So, perhaps support for the ico format is there, I think. I think, I found a link which says that this may be a bug :
Any way in which I can get png format of favicons and display them. Any java library that does that ?

The extension suggests that it also is an ico image

Codecs don't work based on extensions, I can very well have a PNG with extension WTH and it would open up just fine in applications which support PNG.

Anyways, I personally don't know of any converters but you can try picking up ideas from .

Thanks. But favicons are dynamically loaded. I will need to convert them at the time the website is loading. Since the application is platform-independent, it will be difficult to utilize these tools to convert the images.

Perhaps, I can upload these images to a site like convertico.com and download the converted image from there. Is it possible to do that ? Any resources where I can learn the method ?

Would you be using favicons from existing domains or favicons stored locally? If you would be using existing favicons, use the google ICO to PNG converter. http://www.google.com/s2/favicons?domain=daniweb.com

If you want to convert local files, you would have to find some online service like the one you mentioned. Unless the site exposes a programmatic public API, directly using the service might be a bit of pain in the neck along with other implications like taking prior permission of the site owner.

Thanks a ton ! Really, it solved a great headache. I just wanted favicons for existing domains, the sites that I open in my browser. But this google ICO to PNG convertor, I didn't find any documentation,etc on the net. Any link where the entire gamut of google's image conversion facilities is documented.

I don't think there is any need for a documentation nor one exists I guess. You simply need to dynamically create a URL based on your requirement with a URL template like "" + yourDomain and read by the connection opened. Anyways, since I've a bit of free time, I've written a throw-away code which works; feel free to modify it as you see fit.

package pkg;

public class IcoConverterTest {

    public static void main(final String[] args) {
        if(args == null || args.length < 2) {
            System.out.println("pkg.IcoConverterTest <domain> <outdir> <optional-file-name>");
            return;
        }
        final String domain = args[0].trim();
        final String outdir = args[1].trim();
        final String fileName = args.length > 2 ? args[2].trim() : "favicon.png";
        new IcoConverter().convertFor(domain, outdir, fileName);
    }

}

class IcoConverter {

    public static final String CONVERTER_SERVICE = "";

    public void convertFor(final String domain, final String outdir, final String filename) {
        InputStream is = null;
        OutputStream os = null;
        try {
            try {
                final byte[] buf = new byte[4 * 1024]; // 4kB
                is = new URL(MessageFormat.format(CONVERTER_SERVICE, domain)).openStream();
                os = new FileOutputStream(new File(new File(outdir), filename));
                int size = -1;
                while((size = is.read(buf)) != -1) {
                    os.write(buf, 0, size);
                }
            } finally {
                if(is != null)  is.close();
                if(os != null)  os.close();
            }
        } catch(Exception e) {
            throw new RuntimeException("ICO to PNG conversion failed!", e);
        }
    }

}

There are a couple of gotachs when using this service, you can read about them in this discussion.

Thanks a lot for the code. I actually meant if there were any more such services that google offers (like ICO to other formats apart from PNG). I mean this is some kind of service that's not well publicized (doesn't show up on google). Where should one look for such services of google ? The link is also unintuitive (s2 ?)

I actually meant if there were any more such services that google offers (like ICO to other formats apart from PNG). I mean this is some kind of service that's not well publicized (doesn't show up on google). Where should one look for such services of google ?

Unfortunately I don't have an answer for that; I guess it's one of those "oooh, cool stuff" things.

thanks

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.