-1

Now I am using this code to read an icon image from disk:

  String fullImagePath = imageDiskPath + localIconUrl;
            String extensionName = FilenameUtils.getExtension(localIconUrl);
            BufferedImage img;
            if("ico".equals(extensionName)){
                img = Imaging.getAllBufferedImages(new File(fullImagePath)).get(0);
            }else{
                img = ImageIO.read(new File(fullImagePath));
            }

            if(img == null){
                log.error("read image return home,url:" + fullImagePath);
                return null;
            }
            ByteArrayOutputStream os = new ByteArrayOutputStream();

            ImageIO.write(img, extensionName, os);
            byte[] array = os.toByteArray();
            if(ArrayUtils.isEmpty(array)){
                log.error("array is null");
                return null;
            }

but when I read an icon image,the result ByteArrayOutputStream is null. This is the debug output:

enter image description here

Am I doing wrong? what should I do to make it read an icon and convert to bas64 successfully? I am using this package to read the icon:

api group: 'org.apache.commons', name: 'commons-imaging', version: '1.0-alpha2'

I have also tried this way:

img = Imaging.getBufferedImage(new File(fullImagePath));

still not work.

Dolphin
  • 29,069
  • 61
  • 260
  • 539
  • 2
    ImageIO only supports a very small number of image formats out-of-the-box and I don't believe ICO is one of them unfortunately. For example, do the PNG images in your data folder load successfully (PNG is supported)? – stridecolossus Jun 08 '21 at 15:03
  • if I want to read icon, what should i do?@stridecolossus – Dolphin Jun 08 '21 at 15:09
  • If you do a quick search you'll find many posts where people wanted to load ICO using ImageIO, unfortunately there is no simple solution as far as I can tell. Your options are either to convert the icons to something that is supported (PNG, JPEG, etc) or use a different third-party library. – stridecolossus Jun 08 '21 at 15:14
  • 1
    *if I want to read icon, what should i do* - Did you search this site/web? I went to google and did a search on "java read ico file" and found some hits that pointed back to this site. The answers suggest you need a 3rd party package. – camickr Jun 08 '21 at 15:15
  • I have searched, but there is not have a simple way to handle icon image. I am thinking what should I do to make it easier and simple.@camickr – Dolphin Jun 08 '21 at 15:18
  • 1
    Does this answer your question? [How to read an ico format picture in java?](https://stackoverflow.com/questions/11400707/how-to-read-an-ico-format-picture-in-java) – Silvio Mayolo Jun 08 '21 at 15:24
  • Base64 has nothing to do with icons or images! Base64 is just a textual representation of bytes. You dont have to do anything Image-Related here. Simply convert to File content (in bytes) to Base64. You can then use the resulting Base64-String in an `` – Felix Jun 08 '21 at 16:03
  • I read all content from internet tell that image file -> BufferedImage -> ByteArrayOutputStream -> Base64. @codeflush.dev I should do file -> base64? – Dolphin Jun 08 '21 at 16:09

1 Answers1

1

Base64 has nothing exactly to do with images or more specifically icons. Base64 is a textual representation of bytes.

Whenever you see an img-Tag in HTML using a Base64-src like this:

<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==" alt="Red dot" />

This is simply the raw-bytes (as if it was an file on your local filesystem) encoded as an Base64-String.

You can convert any file to Base64 using this method:

    public static String fileToBase64(Path filePath) throws IOException {
        try (InputStream in = Files.newInputStream(filePath, StandardOpenOption.READ)) {
            final ByteArrayOutputStream bos = new ByteArrayOutputStream();

            try (OutputStream out = Base64.getEncoder().wrap(bos)) {
                in.transferTo(out);
            }

            return bos.toString(StandardCharsets.UTF_8);
        }
    }

Let's say you have a local .ico file at /Users/youruser/Downloads/MyIcon.ico which you want to place in an <img>-Tag using Base64:

    public static void main(String[] args) throws IOException {
        final String fullImagePath = "/Users/youruser/Downloads/MyIcon.ico";
        final String base64 = fileToBase64(Paths.get(fullImagePath));

        System.out.println(base64);
    }

On your console, you will see the raw-bytes of the image encoded as Base64. Just for the example, lets say the output you saw was iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==

You then take that Base64-String and build your <img>-Tag out of it:

<img src="data:image/x-icon;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==" />

The prefix (data:image/x-icon;base64,) is important (highly simplified):

  • data - Tells the browser that this is not an URL
  • image/x-icon - Tells the browser the type of image (in this example, .ico, for png use image/png)
  • base64,THE_BASE_64_STRING - Tells the browser to interpret the data as base64

The code I showed uses only the Standard-Library of Java 8+ and the following imports:

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
import java.util.Base64;
Felix
  • 2,256
  • 2
  • 15
  • 35