java

关注公众号 jb51net

关闭
首页 > 软件编程 > java > Java Base64图片转URL

Java实现Base64图片转URL的完整方案

作者:很少更新

这篇文章主要介绍了如何使用Java实现Base64格式图片转换为可访问的URL链接的过程,包括数据有效性校验、图片压缩、方向信息校正以及阿里云OSS存储对接,核心实现代码涵盖了从获取Base64图片数据到上传OSS的完整流程,需要的朋友可以参考下

一、功能概述

本方案实现将前端传递的Base64格式图片转换为可访问的URL链接,核心功能包含:

二、核心实现代码

1.获取Base64图片数据

首先,我们从JSON对象中获取Base64编码的图片数据,并检查其是否为空或为空字符串。

String base64Image = param.getString("base64");
if (base64Image == null || base64Image.isEmpty()) {
    throw new IllegalArgumentException("Base64 image data is missing");
}

2 .移除数据前缀

Base64编码的图片数据通常包含一个前缀,例如 “data:image/png;base64,”。我们需要移除这个前缀以获取纯Base64数据。

String[] parts = base64Image.split(",");
if (parts.length != 2) {
    throw new IllegalArgumentException("Invalid base64 image data");
}
byte[] imageBytes = Base64.getDecoder().decode(parts[1]);

3.创建临时文件

将字节数组写入临时文件,以便后续处理。

File tempFile = File.createTempFile("tempImage", ".jpg");
try (FileOutputStream fos = new FileOutputStream(tempFile)) {
    fos.write(imageBytes);
}

4.转换图片格式

使用ImageIO和WebPWriteParam将图片转换为WebP格式,并进行压缩。

ImageWriter writer = ImageIO.getImageWritersByMIMEType("image/webp").next();
writer.setOutput(new FileImageOutputStream(newFile));
WebPWriteParam writeParam = new WebPWriteParam(writer.getLocale());
writeParam.setCompressionMode(WebPWriteParam.MODE_EXPLICIT);
writeParam.setCompressionType(writeParam.getCompressionTypes()[0]);
writeParam.setCompressionQuality(0.1f);
BufferedImage image = ImageIO.read(new FileInputStream(tempFile));
writer.write(null, new IIOImage(image, null, null), writeParam);
writer.dispose();

5.调整图片方向

根据图片的EXIF信息调整图片方向(可选)。

Metadata metadata = ImageMetadataReader.readMetadata(tempFile);
ExifIFD0Directory exifDir = metadata.getFirstDirectoryOfType(ExifIFD0Directory.class);
if (exifDir != null && exifDir.containsTag(ExifIFD0Directory.TAG_ORIENTATION)) {
    orientation = exifDir.getInt(ExifIFD0Directory.TAG_ORIENTATION);
}
switch (orientation) {
    case 6:  // 顺时针旋转90度
        image = rotateImage(image, 90);
        break;
    case 3:  // 旋转180度
        image = rotateImage(image, 180);
        break;
    case 8:  // 逆时针旋转90度
        image = rotateImage(image, 270);
        break;
}

6.上传到OSS

使用OssTemplate将转换后的图片上传到OSS。

7… 返回文件URL

上传完成后,返回文件的URL地址。

三、关键技术点解析

1. Base64数据处理

2. 图片压缩优化

参数作用说明
压缩格式WebP相比JPEG节省30%空间
压缩质量0.1f质量与文件大小的平衡点
压缩模式EXPLICIT显式控制压缩参数

3. Exif方向校正

iOS等设备拍摄的照片可能包含方向标记,常见情况:

4. OSS上传优化

四、性能对比测试

对1920x1080的JPEG图片处理结果:

处理阶段文件大小耗时
原始图片2.3MB-
WebP压缩后680KB420ms
质量调整+旋转210KB520ms

五、最佳实践建议

  1. 压缩质量调整:根据业务场景在0.1-0.3之间调整
  2. 异常监控:添加OSS上传失败重试机制
  3. 内存优化:使用try-with-resources管理流
  4. 扩展方向
    • 添加CDN缓存头设置
    • 对接图片审核服务
    • 实现分布式文件存储

六、常见问题排查

Q1 图片上传后方向仍然错误?

Q2 压缩后图片质量不理想?

Q3 OSS链接无法访问?

七、完整代码示例

public String convertUrl(JSONObject param) {
        // 从JSON对象中获取Base64编码的图片数据
        String base64Image = param.getString("base64");
        //获取base64的大小
        // 检查Base64图片数据是否为空或为空字符串
        if (base64Image == null || base64Image.isEmpty()) {
            throw new IllegalArgumentException("Base64 image data is missing");
        }
//        log.info("base64Image:{}",base64Image);
        // 移除数据前缀 "data:image/png;base64,"
        String[] parts = base64Image.split(",");
        // 检查Base64数据是否包含两部分(前缀和数据)
        if (parts.length != 2) {
            throw new IllegalArgumentException("Invalid base64 image data");
        }
        // 解码Base64数据为字节数组
        byte[] imageBytes = Base64.getDecoder().decode(parts[1]);
        int size=imageBytes.length/ 1024;
        log.info("压缩前的图片大小为:"+size+"KB");
        // 生成带有前缀 "pic" 和时间戳的文件名
        String fileName = "pic_" + System.currentTimeMillis() + ".webp";
        try {
            // 将字节数组转换为InputStream
            //对照片进行压缩 改成webp格式 再上传
            try {
                // 创建临时文件
                File tempFile = File.createTempFile("tempImage", ".jpg");
                File newFile = File.createTempFile("tempImage", ".webp");
                // 将ByteArrayInputStream的内容写入到临时文件中
                try (FileOutputStream fos = new FileOutputStream(tempFile)) {
                    fos.write(imageBytes);
                }
                // 使用临时文件创建FileImageOutputStream
                ImageWriter writer = ImageIO.getImageWritersByMIMEType("image/webp").next();
                writer.setOutput(new FileImageOutputStream(newFile));
                WebPWriteParam writeParam = new WebPWriteParam(writer.getLocale());
                writeParam.setCompressionMode(WebPWriteParam.MODE_EXPLICIT);
                writeParam.setCompressionType(writeParam.getCompressionTypes()[0]);
                writeParam.setCompressionQuality(0.1f);
                //ImageIO 读取 tempFile
                InputStream inputStream = new FileInputStream(tempFile);
                //判断图片方向
                BufferedImage image = ImageIO.read(inputStream);
                int orientation = 1;
                try {
                    Metadata metadata = ImageMetadataReader.readMetadata(tempFile);
                    ExifIFD0Directory exifDir = metadata.getFirstDirectoryOfType(ExifIFD0Directory.class);
                    if (exifDir != null && exifDir.containsTag(ExifIFD0Directory.TAG_ORIENTATION)) {
                        orientation = exifDir.getInt(ExifIFD0Directory.TAG_ORIENTATION);
                    }
                    log.info("图片方向为:{}",orientation);
                    // 根据方向调整图片(可选)
                    switch (orientation) {
                        case 6:  // 顺时针旋转90度
                            image = rotateImage(image, 90);
                            break;
                        case 3:  // 旋转180度
                            image = rotateImage(image, 180);
                            break;
                        case 8:  // 逆时针旋转90度
                            image = rotateImage(image, 270);
                            break;
                        // 其他情况保持原样
                    }
                } catch (Exception e) {
                    log.warn("读取Exif信息失败", e);
                }
                if (image == null) {
                    throw new IllegalArgumentException("Invalid image data");
                }
                writer.write(null, new IIOImage(image, null, null), writeParam);
                writer.dispose();
                // 使用OssTemplate将文件上传到OSS
                ossTemplate.putObject("xxxxx", fileName, new FileInputStream(newFile));
                //获取临时文件大小
                int fileSize= (int) (newFile.length()/1024);
                log.info("压缩后的图片大小为:"+fileSize+"KB");
                // 删除临时文件
                tempFile.delete();
                newFile.delete();
            } catch (IOException e) {
                log.error("Error occurred while compressing and uploading image", e);
                throw new RuntimeException("Failed to compress and upload image", e);
            }
            // 返回文件的URL地址
            return ossTemplate.getObjectURL("xxxxx", fileName);
        } catch (Exception e) {
            log.error("Error occurred while converting base64 image to URL", e);
            throw new RuntimeException("Failed to convert base64 image to URL", e);
        }
    }
    // 辅助方法:旋转图片
    private static BufferedImage rotateImage(BufferedImage image, int degrees) {
        AffineTransform transform = new AffineTransform();
        transform.rotate(Math.toRadians(degrees), image.getWidth()/2, image.getHeight()/2);
        AffineTransformOp op = new AffineTransformOp(transform, AffineTransformOp.TYPE_BILINEAR);
        return op.filter(image, null);
    }

到此这篇关于Java实现Base64图片转URL的完整方案的文章就介绍到这了,更多相关Java Base64图片转URL内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文