Java使用Tinify实现图片无损压缩(4M无损压缩到1M)的方法

 更新时间:2024年08月16日 08:53:19   作者:小明爱吃火锅  
在当今的数字化时代,图片已成为网站、应用和社交媒体中不可或缺的元素,然而,大尺寸的图片不仅会增加页面或者客户端加载时间,还会占用大量的存储空间,本文将详细介绍如何利用Tinify压缩图片,并将其上传至OSS,重点介绍图片压缩实现方式,需要的朋友可以参考下

引言

在当今的数字化时代,图片已成为网站、应用和社交媒体中不可或缺的元素。然而,大尺寸的图片不仅会增加页面或者客户端加载时间,还会占用大量的存储空间。为了解决这个问题,可以使用图片压缩工具来减小图片的尺寸,然后再将压缩后的图片上传至对象存储服务(如阿里云OSS)。本文将详细介绍如何利用Tinify压缩图片,并将其上传至OSS,重点介绍图片压缩实现方式。

一、Tinify简介

1.1 图片压缩的重要性

随着互联网的普及,图片已成为信息传递的重要载体。然而,大尺寸、高分辨率的图片会占用大量带宽和存储空间,导致网站加载速度变慢。通过压缩图片,可以有效减小文件大小,提高网站性能。

1.2 Tinify概述

Tinify是一个基于云的图片压缩服务,它能够显著减小图片的文件大小,同时保持图片的高质量。Tin义提供了丰富的API,可以轻松集成到各种项目中。而且还是对外免费开放使用的。

1.3 Tinify的使用方式

Tinify提供了两种主要的图片压缩方式:

第一种:源文件直接上传

直接获取表单请求的MultipartFile文件,也就是可以从缓冲区(带二进制字符串)上传图像,并获取压缩的图像数据。

byte[] sourceData = Files.readAllBytes(Paths.get("unoptimized.jpg"));
byte[] resultData = Tinify.fromBuffer(sourceData).toBuffer();

这种适合OSS上传,推荐,缺点是会先把压缩之后的图片保存到服务器,在上传到oss,可以在上传之后,删除图片。

第二种:图片URL上传

只需可以提供一个URL到您的图像,而不必上传它,这种更适合图片查询展示的时候进行压缩,压缩之后可以在Source对象中获取新的图片URL。

Source source = Tinify.fromUrl("https://cdn.tinypng.com/images/panda-happy.png");
source.toFile("optimized.jpg");

二、OSS简介

阿里云OSS(Object Storage Service)是一种海量、安全、低成本、高可靠的云存储服务。用户可以通过RESTful API在任何时间、任何地点、以任何互联网设备访问OSS上的数据。OSS提供了丰富的功能,如文件上传、下载、删除、共享等,非常适合用于存储和管理图片。这里就不多介绍了,只要做过图片上传,相信大家都知道。

三、实现流程

通过上面Tinify压缩API的介绍,可以看到使用Tinify进行图片压缩也是比较容易整合的,只要在上传OSS前对图片进行压缩,在获取压缩后最新图片进行上传,对原有代码改造也不多。具体流程如下:

3.1 检查文件大小

判断上传的图片文件大小是否超过500KB。如果未超过,则不进行压缩,这一块可以根据自己业务进行处理。

3.2 设置Tinify API密钥

使用Tinify.setKey(API_KEY)方法设置Tinify的API密钥。

3.3 压缩图片

使用Tinify.fromBuffer(file.getBytes())方法从文件字节流创建Tinify的Source对象。

使用source.toFile(file.getOriginalFilename())方法将压缩后的图片保存到服务器。

读取服务器中压缩后的图片输入流,并将其转换为MultipartFile对象。

3.4 清理临时文件

删除服务器上临时保存的压缩源文件。

完整实现流程图如下:

四、实现代码

4.1 引入依赖

首先,需要在项目中引入Tinify和阿里云OSS的依赖。

<!-- Tinify -->
<dependency>
    <groupId>com.tinify</groupId>
    <artifactId>tinify</artifactId>
    <version>RELEASE</version>
</dependency>

<!-- 阿里云OSS -->
<dependency>
    <groupId>com.aliyun.oss</groupId>
    <artifactId>aliyun-sdk-oss</artifactId>
<!-- 阿里云OSS -->
<dependency>
    <groupId>com.aliyun.oss</groupId>
    <artifactId>aliyun-sdk-oss</artifactId>
    <version>3.14.1</version>
</dependency>

4.2 配置Tinify API密钥

在使用Tinify之前,需要先注册一个账号并获取API密钥,主要是获取对应的apiKey,这里可以到官网直接申请。

public class TinifyConfig {
    public static final String API_KEY = "your_tinify_api_key";
}

4.3 实现图片压缩和上传功能

以下是实现图片压缩和上传至OSS的核心代码:

import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.tinify.Tinify;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.UUID;

public class ImageUploader {

    private static final String dir = "your_upload_directory/";

    /**
     * 图片上传
     *
     * @param file 源文件
     * @return 压缩后图片的URL
     * @throws IOException
     */
    public String upload(MultipartFile file) {
        String endpoint = OSSClientConstants.endpointMap.get("lden");
        OSS ossClient = new OSSClientBuilder().build(endpoint, OSSClientConstants.ACCESS_KEY_ID, OSSClientConstants.ACCESS_KEY_SECRET);
        try {
            String name = file.getOriginalFilename();
            String prefix = name.substring(name.lastIndexOf("."));  // 获取文件后缀
            String filename = dir + UUID.randomUUID() + prefix;  // 上传的文件路径和文件名

            // 压缩图片
            InputStream is = compressPic(file);
            
            // 上传阿里OSS
            ossClient.putObject(bucket, filename, is);
            
             // 返回图片上传URL
            return ("https://your_cdn/" + filename);
        } catch (Exception e) {
            logger.error("上传发生错误", e);
            return null;
        } finally {
            ossClient.shutdown();
        }
    }

    /**
     * Tinify压缩图片
     *
     * @param file 源文件
     * @return 压缩图片流
     * @throws IOException
     */
    public InputStream compressPic(MultipartFile file) throws IOException {
        InputStream is = file.getInputStream();
        // 小于 500kb不压缩,这块业务可以自己决定
        if (file.getSize() > 500 * 1024) {
            //  设置Tinify的API密钥
            Tinify.setKey(TinifyConfig.API_KEY);
            // 从MultipartFile创建Tinify的Source对象,压缩图片
            Source source = Tinify.fromBuffer(file.getBytes());
            // 压缩之后保存到服务器
            source.toFile(file.getOriginalFilename());
            // 读取服务器中压缩图片输入流
            byte[] bytes = Files.readAllBytes(Paths.get(file.getOriginalFilename()));
            is = convertToMultipartFile(bytes, file.getOriginalFilename()).getInputStream();
            // 删除压缩源文件
            Files.deleteIfExists(Paths.get(file.getOriginalFilename()));
        }
        return is;
    }
}

4.4 压缩效果验证

程序运行之后,查看日志,可以对比压缩前后图片大小,可以看到4M图片压缩之后变成了1M。

或者直接对比压缩前后两张图片的大小,更加直观说明。

原图片:

压缩之后图片:

4.5 注意事项

  • API密钥安全:请确保Tinify的API密钥和OSS的访问密钥安全,不要泄露给他人,可以统一保存到安全的配置文件或数据库中。
  • 异常处理:在实际应用中,需要对可能出现的异常进行详细处理,以确保程序的健壮性。
  • 文件命名:为了避免文件名冲突,可以使用UUID生成唯一的文件名。
  • 压缩图片删除:为了避免占用服务器内存,可以在压缩之后删除临时保存的压缩源文件。

五、总结

通过本文的介绍,了解了如何利用Tinify压缩图片,并将其上传至阿里云OSS。这种方法不仅可以减小图片的文件大小,提高页面加载速度,还可以节省存储空间。希望本文的内容对有所帮助,能够优化Web应用中的图片管理。

以上就是Java使用Tinify实现图片无损压缩的方法的详细内容,更多关于Java Tinify图片压缩的资料请关注脚本之家其它相关文章!

相关文章

  • Springboot集成shiro之登录拦截/权限控制方式

    Springboot集成shiro之登录拦截/权限控制方式

    文章介绍了Shiro框架的的配置和使用,包括添加依赖、配置ShiroConfig、创建realm、配置安全管理器、配置过滤器和权限控制,还介绍了配置ehcache缓存、自定义加密和处理404重定向等问题,总结了Shiro框架中的常用配置和解决常见问题的方法
    2026-05-05
  • java保留小数的四种实现方法

    java保留小数的四种实现方法

    这篇文章主要为大家详细介绍了java保留小数的四种实现方法,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2016-11-11
  • Spring Boot整合elasticsearch的详细步骤

    Spring Boot整合elasticsearch的详细步骤

    这篇文章主要介绍了Spring Boot整合elasticsearch的详细步骤,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-04-04
  • SpringBoot整合SpringAI配置多平台API密钥的解决方案

    SpringBoot整合SpringAI配置多平台API密钥的解决方案

    本文介绍了如何在SpringBoot项目中整合SpringAI配置平台API密钥,包括添加依赖、配置文件、配置属性类及核心配置类等,通过动态切换不同AI平台,实现统一接口调用,此外,支持YAML配置和环境变量,便于灵活配置和扩展新平台,需要的朋友可以参考下
    2026-05-05
  • 一文盘点SpringBoot中常用跨域处理方案

    一文盘点SpringBoot中常用跨域处理方案

    跨域是浏览器为了保障安全而遵循的一种规则,是同源策略的一部分,本文将为大家整理了SpringBoot中常用跨域处理的方法,需要的小伙伴可以了解下
    2025-08-08
  • Spring @Transaction 注解执行事务的流程

    Spring @Transaction 注解执行事务的流程

    这篇文章主要介绍了Spring @Transaction 注解执行事务的流程,Spring 是如何开启事务的?又是如何进行提交事务和关闭事务的,本文给大家详细介绍,需要的朋友可以参考下
    2021-06-06
  • SpringBoot+MyBatis实现动态字段更新的三种方法

    SpringBoot+MyBatis实现动态字段更新的三种方法

    字段更新是指在数据库表中修改特定列的值的操作,这种操作可以通过多种方式进行,具体取决于业务需求和技术环境,本文给大家介绍了在Spring Boot和MyBatis中,实现动态更新不固定字段的三种方法,需要的朋友可以参考下
    2025-04-04
  • SpringMVC访问静态资源的方法

    SpringMVC访问静态资源的方法

    本篇文章主要介绍了SpringMVC访问静态资源的方法,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-02-02
  • 在Spring 中使用@Aspect 控制自定义注解的操作

    在Spring 中使用@Aspect 控制自定义注解的操作

    这篇文章主要介绍了在Spring 中使用@Aspect 控制自定义注解的操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2021-01-01
  • Netty分布式客户端处理接入事件handle源码解析

    Netty分布式客户端处理接入事件handle源码解析

    这篇文章主要为大家介绍了Netty源码分析客户端流程处理接入事件handle创建,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-03-03

最新评论