用Java将ico格式转 PNG/JPG等格式

简介: 用Java将ico格式转 PNG/JPG等格式

一. 什么是ico图标?
ico是一种图标格式,大量应用于网站,各个软件的logo或图标展示。

我们在进入某个网站或网页,它们上方标题左侧各自都带有logo图标。

这就是favicon.ico图标,它可以让浏览器的收藏夹中除显示相应的标题外,还可以用图标的方式区别不同的网站。

二. ico图标的特点
一张ico图标里,有可能只有一张或包含多张的图片信息,图片的清晰度越来越高。

三. 用Java来处理ico, 并转换成其他格式图片
做这种ico格式的图片转换功能,并不是特别容易,是有区别于普通图片格式转换,我经过不断尝试,调试,得到了一个自己还比较满意的结果。

我们在看代码之前,还是先看看我自己对这个功能的需求理解:

i. 需要有工具类能够读取ico的图片流。

ii. 对ico进行放大操作,尽可能地解决图片因为放大而出现模糊及毛刺。

iii. 能够将ico图片转换成其他格式的图片保存。

为了实现以上的3点功能,我需要借助这三个优秀的jar来实现此功能:

image4j.jar 主要读取ico图片
java-image-scaling-0.8.6.jar 主要缩放,修改图片大小
filters-2.0.235-1.jar 是image-scaling的依赖包
3.1 image4j.jar 主要读取ico图片
JDK没有提供读取ico图片的相关工具类,所以我们需要先解决读取ico格式的图片问题。

这里我找了相关的jar, 经过测试,image4j.jar中能读取。

image4j.jar中涉及的主要类:ICODecoder类

上面标记的四个方法中, 返回的是为什么是List集合?这里回到ICO的特点中来说,一张ICO图片包含一张或多张图片信息(取到图片后,看到图片主要是清晰度不同)
下面我是从发送http请求,从响应的图片流解析ICO图片

/**

 * 获取ICO图片
 * @param surl
 * @return
 */
public static List<ICOImage> getICOImageByUrl(String surl) {
    HttpURLConnection httpURLConnection = null;
    List<ICOImage> list = new ArrayList<>();
    try {
        URL url = new URL(surl);
            // https证书
            checkQuietly();
            httpURLConnection = (HttpURLConnection) url.openConnection();
            httpURLConnection.setInstanceFollowRedirects(false);
            httpURLConnection.setRequestMethod("GET");
            httpURLConnection.setConnectTimeout(30000);
            httpURLConnection.setReadTimeout(30000);
            httpURLConnection.setDoOutput(true);
            httpURLConnection.setRequestProperty("User-Agent", "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.2; Trident/4.0; .NET CLR 1.1.4322; .NET CLR 2.0.50727; .NET CLR 3.0.04506.30; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729)");
            httpURLConnection.setRequestProperty("Charset", "UTF-8");
            httpURLConnection.setRequestProperty("Accept", "*/*");
            httpURLConnection.setRequestProperty("content-type","image/x-icon");
            // 创建连接
            httpURLConnection.connect();
            if (httpURLConnection.getResponseCode() == 200) {
                InputStream in = httpURLConnection.getInputStream();
                list = ICODecoder.readExt(in);  // 从响应结果集中获取ico图片流
                return list;
            }
    }catch (Exception e) {
        e.printStackTrace();
    }finally {
        if(httpURLConnection != null){
            httpURLConnection.disconnect();
        }
    }
    return list;
}

/**
//代码效果参考:http://www.zidongmutanji.com/bxxx/152148.html

  • 配置https证书
    */
    public static void checkQuietly() {

      try {
          HttpsURLConnection
                  .setDefaultHostnameVerifier(new HostnameVerifier() {
                      public boolean verify(String hostname,
                                            SSLSession session) {
                          return true;
                      }
                  });
          SSLContext context = SSLContext.getInstance("TLS");
          context.init(null, new X509TrustManager[] { new X509TrustManager() {
              public void checkClientTrusted(X509Certificate[] chain,
                                             String authType) throws CertificateException {
              }
    
              public void checkServerTrusted(X509Certificate[] chain,
                                             String authType) throws CertificateException {
              }
    
              public X509Certificate[] getAcceptedIssuers() {
                  return new X509Certificate[0];
              }
          } }, new SecureRandom());
          HttpsURLConnection.setDefaultSSLSocketFactory(context
                  .getSocketFactory());
      } catch (Exception e) {
          e.printStackTrace();
      }
    

    }
    //代码效果参考:http://www.zidongmutanji.com/bxxx/451200.html

3.2 java-image-scaling-0.8.6.jar 主要缩放,修改图片大小
由于ICO图标的像素大小(宽高)都比较小,再获取到图片后, 需要调整大小。如果采用普通方式去调整大小的话,图片会模糊,而且会出现类似马赛克的图像噪点。这样的效果并不理想。

下面的方法就是对ICO图片进行放大到80x80像素,在转换成PNG,并转换成base64,以便保存。

/**

 * 处理ICOImage图片
 */
public static String hadleICOImage(ICOImage icoImage) throws IOException {
    ResampleOp resampleOp = new ResampleOp(80,80);
    resampleOp.setUnsharpenMask(AdvancedResizeOp.UnsharpenMask.Oversharpened);
    BufferedImage bi = resampleOp.filter(icoImage.getImage(), null);
    BufferedImage result = null;
    /* 新生成结果图片 */
    result = new BufferedImage(80, 80,
            BufferedImage.TYPE_INT_RGB);
    Graphics2D g = result.createGraphics();
    g.setColor(Color.WHITE);
    g.drawImage(bi.getScaledInstance(80,80, Image.SCALE_SMOOTH), 0, 0, null);
    ByteArrayOutputStream bos = new ByteArrayOutputStream();
    ImageIO.write(result, PNG, bos);
    BASE64Encoder encoder = new BASE64Encoder();
    return encoder.encode(bos.toByteArray()).replaceAll("\n", "").replaceAll("\r", "").trim();
}

3.2 实现ICO转PNG
从调用getICOImageByUrl()获取List这样一个list集合,获取最后一张,并实现转换。

List icoImages = getICOImageByUrl(url);
// 取最后一张最清晰的图片出来
ICOImage icoImage = icoImages.get(icoImages.size() - 1);
// 处理图片(转换大小,图片格式)并保存
hadleICOImage(icoImage);

相关文章
|
1月前
|
JSON 前端开发 Java
震惊!图文并茂——Java后端如何响应不同格式的数据给前端(带源码)
文章介绍了Java后端如何使用Spring Boot框架响应不同格式的数据给前端,包括返回静态页面、数据、HTML代码片段、JSON对象、设置状态码和响应的Header。
133 1
震惊!图文并茂——Java后端如何响应不同格式的数据给前端(带源码)
|
4月前
|
Java 编译器 开发者
Java演进问题之Truffle处理不同编程语言的源代码或中间格式如何解决
Java演进问题之Truffle处理不同编程语言的源代码或中间格式如何解决
|
3月前
|
缓存 Java 数据处理
|
3月前
|
Java
Java模拟文件发送给服务器,服务器将文件转发给其他用户,并保存到服务器本地,其他用户可以接收,并保存到本地磁盘,支持各种文件格式,并解决通信中服务器怎么区分客户端发来的文件类型
Java模拟文件发送给服务器,服务器将文件转发给其他用户,并保存到服务器本地,其他用户可以接收,并保存到本地磁盘,支持各种文件格式,并解决通信中服务器怎么区分客户端发来的文件类型
|
5月前
|
Java C语言
Java微信语音amr格式转mp3格式
Java微信语音amr格式转mp3格式
|
5月前
|
Java
使用java文件过滤器输出制定格式文件路径
使用java文件过滤器输出制定格式文件路径
|
6月前
|
网络安全 流计算 Python
实时计算 Flink版操作报错合集之Flink sql-client 针对kafka的protobuf格式数据建表,报错:java.lang.ClassNotFoundException 如何解决
在使用实时计算Flink版过程中,可能会遇到各种错误,了解这些错误的原因及解决方法对于高效排错至关重要。针对具体问题,查看Flink的日志是关键,它们通常会提供更详细的错误信息和堆栈跟踪,有助于定位问题。此外,Flink社区文档和官方论坛也是寻求帮助的好去处。以下是一些常见的操作报错及其可能的原因与解决策略。
125 1
|
6月前
|
消息中间件 关系型数据库 网络安全
实时计算 Flink版操作报错合集之Flink sql-client 针对kafka的protobuf格式数据建表,报错:java.lang.ClassNotFoundException 如何解决
实时计算Flink版作为一种强大的流处理和批处理统一的计算框架,广泛应用于各种需要实时数据处理和分析的场景。实时计算Flink版通常结合SQL接口、DataStream API、以及与上下游数据源和存储系统的丰富连接器,提供了一套全面的解决方案,以应对各种实时计算需求。其低延迟、高吞吐、容错性强的特点,使其成为众多企业和组织实时数据处理首选的技术平台。以下是实时计算Flink版的一些典型使用合集。
213 1
|
5月前
|
Java
JAVA读取EMF文件并转化为PNG,JPG,GIF格式
JAVA读取EMF文件并转化为PNG,JPG,GIF格式
353 0
|
6月前
|
Java 编译器 程序员
Java基础语法之基本语法格式
本文主要复习了Java的基础语法,包括类的定义、方法、主方法、注释和关键字等内容,旨在帮助读者巩固Java学习中的重要概念。