JAVA将图片的base64转成PDF的base64字符串

本文介绍了一种将图片的Base64编码转换为PDF的Base64编码的方法,通过生成二维码图片,将其转换为PDF并编码,适用于需要在不同格式间转换的应用场景。
由于需求需要的是PDF的base64,所以中转了一下,比价麻烦了,代码如下:
/**
 * Description: 将图片的base64转成PDF的base64编码
 * @param  qrCodeUrl  需要转成二维码的URL字符串
 * @Author zhanglifeng
 * Create Date: 2020年3月30日 下午8:25:37
 */
public String imageBase64ToPdfBase64(String qrCodeUrl,String custOrderNbr){
    String bas64ImageStr="";//图片的base64编码
    String pdfBase64 = "";//PDF的base64编码

    try{
        //1.根据微厅返回的请求参数生成二维码 base64 编码
        bas64ImageStr = QrcodeUtils.encoderQRCodeToBase64(qrCodeUrl, "png", 10);
        bas64ImageStr = bas64ImageStr.replaceAll("\r|\n", "");

        //2.获取要存储文件的路径,即获取src资源文件编译后的路径(即classes路径)
        String url = this.getClass().getClassLoader().getResource("").getPath();
        //对路劲进行拼接添加
        String serviceImgPath = url + "serviceImg/";//服务器上存放二维码图片的路径
        String servicePdfPath = url + "servicePdf/";//服务器上存放二维码PDF的路径

        //3.判断服务器是否存在此文件夹,不存在则新建
        File file1 =new File(serviceImgPath);
        File file2 =new File(servicePdfPath);
        if(!file1.exists()  && !file1.isDirectory()) {
            file1.mkdir();
        }
        if(!file2.exists()  && !file2.isDirectory()) {
            file2.mkdir();
        }
        //4.二维码图片的文件名字和最终保存的二维码文件路径
        String fileImageName = custOrderNbr+"_phone.png";//二维码图片路径名字
        String filePdfName = custOrderNbr+"_phone.pdf";//PDF图片路径名字
        String lastImagePath = serviceImgPath+fileImageName;//最终二维码图片存放的路径
        String lastPdfPath = servicePdfPath+filePdfName;//最终二维码PDF存放的路径

        //5.首先保存二维码图片
        Base64ToImage(bas64ImageStr,lastImagePath);

        //6.然后把二维码图片转成PDF二维码文件进行储存
        ImagePdf.image2pdf(lastImagePath,lastPdfPath);

        //7.最后将PDF转成base64,PDF的base64才是最终能推送到签字版的
        File file3 =new File(lastPdfPath);
        pdfBase64 = PDFToBase64(file3);
        pdfBase64 = pdfBase64.replaceAll("\r|\n", "");

        //8.需要删除创建的临时文件
        File imagefile = new File(lastImagePath);
        if(imagefile.exists()){
            imagefile.delete();
        }
        File pdffile = new File(lastPdfPath);
        if(pdffile.exists()){
            pdffile.delete();
        }

    }catch (Exception e){
        e.printStackTrace();
    }
    return pdfBase64;
}

 

下面是直接转成图片的base64代码:

/**
 * Description: 将图片的base64字符串,直接供前台展示
 * @param  qrCodeUrl   需要转成二维码的URL
 * @Author zhanglifeng
 * Create Date: 2020年3月30日 下午8:25:37
 */
public String imageBase64ToPdfBase64(String qrCodeUrl,String custOrderNbr){
    String bas64ImageStr="";//图片的base64编码

    try{
        //1.根据微厅返回的请求参数生成二维码 base64 编码
        bas64ImageStr = QrcodeUtils.encoderQRCodeToBase64(qrCodeUrl, "png", 10);
        bas64ImageStr = bas64ImageStr.replaceAll("\r|\n", "");

    }catch (Exception e){
        e.printStackTrace();
    }
    return bas64ImageStr;
}

下面是二维码工具类:

/**
 * @Date: 2020/3/27 17:38
 * @Author: Lifeng.Zhang
 * @Description: 二维码处理工具类
 */
public class QrcodeUtils {

    /**
     * 根据参数生成二维码base64编码
     *  容错率默认M,二维码内容支持大小为10
     * @param content 存储内容
     * @param imgType 图片类型
     * @param imgSize 二维码图片大小像素
     * @param qrWidth 二维码 像素宽度  此值的60倍为图片大小  即:qrWidth*60(约等于) <=imgSize(需要微调)
     * @return String
     */
    public static String encoderQRCodeToBase64(String content, String imgType, int imgSize,int qrWidth) {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        try {
            BufferedImage image = encoderQRCodeFixSize(content, imgType, imgSize, qrWidth);
            if (image == null) {
                return "";
            }
            ImageIO.write(image, imgType, baos);
            return Base64.encodeBytes(baos.toByteArray());
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                baos.flush();
                baos.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return "";
    }

    /**
     * 生成二维码(QRCode)图片的公共方法
     * 生成后的效果需要微调 imgSize 及qrWidth来达到最佳图片效果
     * 如:imgSize=244时,qrWidth=4
     *
     * @param content 存储内容
     * @param imgType 图片类型
     * @param imgSize 二维码图片大小像素
     * @param qrWidth 二维码 像素宽度  此值的60倍为图片大小  即:qrWidth*60(约等于) <=imgSize(需要微调)
     * @return BufferedImage
     */
    public static BufferedImage encoderQRCodeFixSize(String content, String imgType, int imgSize, int qrWidth) {
        BufferedImage bufImg = null;
        try {
            Qrcode qrcodeHandler = new Qrcode();
            // 设置二维码排错率,可选L(7%)、M(15%)、Q(25%)、H(30%),排错率越高可存储的信息越少,但对二维码清晰度的要求越小
            qrcodeHandler.setQrcodeErrorCorrect('M');
            //以字符串存
            qrcodeHandler.setQrcodeEncodeMode('B');
            // 设置设置二维码尺寸,取值范围1-40,值越大尺寸越大,可存储的信息越大
            qrcodeHandler.setQrcodeVersion(6);
            // 获得内容的字节数组,设置编码格式
            byte[] contentBytes = content.getBytes("UTF-8");
            // 图片尺寸
            bufImg = new BufferedImage(imgSize, imgSize, BufferedImage.TYPE_INT_RGB);
            Graphics2D gs = bufImg.createGraphics();
            // 设置背景颜色
            gs.setBackground(Color.WHITE);
            gs.clearRect(0, 0, imgSize, imgSize);

            // 设定图像颜色> BLACK
            gs.setColor(Color.BLACK);
            // 设置偏移量,不设置可能导致解析出错
            int pixoff = 7;
            // 输出内容> 二维码
            if (contentBytes.length > 0 && contentBytes.length < 2048) {
                boolean[][] codeOut = qrcodeHandler.calQrcode(contentBytes);
                for (int i = 0; i < codeOut.length; i++) {
                    for (int j = 0; j < codeOut.length; j++) {
                        if (codeOut[j][i]) {
                            gs.fillRect(j * qrWidth + pixoff, i * qrWidth + pixoff, qrWidth, qrWidth);
                        }
                    }
                }
            } else {
                throw new Exception("QRCode content bytes length = " + contentBytes.length + " not in [0, 800].");
            }
            gs.dispose();
            bufImg.flush();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return bufImg;
    }

    /**
     * 根据参数生成二维码base64编码
     *
     * @param content
     * @param imgType
     * @param size
     * @return
     * @see
     */
    public static String encoderQRCodeToBase64(String content, String imgType, int size) {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        try {
            BufferedImage image = encoderQRCode(content, imgType, size, 10);
            if (image == null) {
                return "";
            }
            ImageIO.write(image, imgType, baos);
            return Base64.encodeBytes(baos.toByteArray());
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                baos.flush();
                baos.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return "";
    }

    /**
     * 生成二维码(QRCode)图片
     *
     * @param content 存储内容
     * @param imgType 图片类型
     * @param size    二维码尺寸
     */
    public static BufferedImage encoderQRCode(String content, String imgType, int size, int margin) {
        try {
            BufferedImage bufImg = encoderQRCodeCommon(content, imgType, size);
            int newWidth = bufImg.getWidth() + margin;
            int newHeight = bufImg.getHeight() + margin;
            BufferedImage newImage = new BufferedImage(newWidth, newHeight, BufferedImage.TYPE_INT_RGB);
            Graphics2D gs = newImage.createGraphics();
            gs.setColor(Color.white);
            gs.fillRect(0, 0, newWidth, newHeight);
            gs.drawImage(bufImg, margin / 2, margin / 2, null);
            return newImage;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 生成二维码(QRCode)图片的公共方法
     *
     * @param content 存储内容
     * @param imgType 图片类型
     * @param size    二维码尺寸  0到40
     * @return BufferedImage
     */
    private static BufferedImage encoderQRCodeCommon(String content, String imgType, int size) {
        BufferedImage bufImg = null;
        try {
            Qrcode qrcodeHandler = new Qrcode();
            // 设置二维码排错率,可选L(7%)、M(15%)、Q(25%)、H(30%),排错率越高可存储的信息越少,但对二维码清晰度的要求越小
            qrcodeHandler.setQrcodeErrorCorrect('L');
            //以字符串存
            qrcodeHandler.setQrcodeEncodeMode('B');
            // 设置设置二维码尺寸,取值范围1-40,值越大尺寸越大,可存储的信息越大
            qrcodeHandler.setQrcodeVersion(6);
            // 获得内容的字节数组,设置编码格式
            byte[] contentBytes = content.getBytes("utf-8");
            // 图片尺寸
            int imgSize = 67 + 12 * (size - 1);
            bufImg = new BufferedImage(imgSize, imgSize, BufferedImage.TYPE_INT_RGB);
            Graphics2D gs = bufImg.createGraphics();
            // 设置背景颜色
            gs.setBackground(Color.WHITE);
            gs.clearRect(0, 0, imgSize, imgSize);

            // 设定图像颜色> BLACK
            gs.setColor(Color.BLACK);
            // 设置偏移量,不设置可能导致解析出错
            int pixoff = 5;
            // 输出内容> 二维码
            if (contentBytes.length > 0 && contentBytes.length < 2000) {
                boolean[][] codeOut = qrcodeHandler.calQrcode(contentBytes);
                for (int i = 0; i < codeOut.length; i++) {
                    for (int j = 0; j < codeOut.length; j++) {
                        if (codeOut[j][i]) {
                            gs.fillRect(j * 4 + pixoff, i * 4 + pixoff, 4, 4);
                        }
                    }
                }
            } else {
                throw new Exception("QRCode content bytes length = " + contentBytes.length + " not in [0, 800].");
            }
            gs.dispose();
            bufImg.flush();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return bufImg;
    }
}

 

 

<think>我们有一个Base64编码的字符串,需要将其解码成二进制数据,然后保存为图片文件。 同时,我们还需要确保保存图片的目录存在,如果不存在则创建目录。 参考之前的PDF文件生成中的目录处理方式,这里同样适用。 步骤: 1. 定义Base64字符串图片输出路径(包含目录和文件名)。 2. 检查输出路径的父目录是否存在,如果不存在则创建(使用Java NIO的Files.createDirectories)。 3. 将Base64字符串解码为字节数组(使用java.util.Base64解码器)。 4. 将字节数组写入到指定的图片文件。 注意:Base64字符串可能是标准的(如以"data:image/png;base64,"开头),也可能没有前缀。如果包含前缀,需要先去除前缀再解码。 但是,根据引用[2]中的描述,我们保存为图片时,Base64字符串应该是纯的Base64编码数据。如果包含MIME类型前缀,需要先去除。 例如:一个典型的带前缀的Base64字符串是: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUA...FII=" 我们需要去除前缀,只保留逗号后面的部分。 然而,用户提供的Base64字符串可能带前缀也可能不带,所以我们需要判断并处理。 但是,用户的问题中没有明确说明是否带前缀,所以我们可以提供两种方式: a) 如果用户确保传入的是纯Base64字符串,则直接解码。 b) 如果字符串包含前缀,则先分离出真正的Base64编码部分。 为了通用性,我们可以检查字符串是否以"data:image"开头,如果是,则提取逗号之后的部分。 实现步骤: 1. 如果base64String以"data:image"开头,则找到第一个逗号的位置,然后截取逗号后面的部分。 2. 否则,直接使用整个字符串。 然后,将截取后的字符串进行Base64解码。 另外,图片文件的扩展名可以根据Base64字符串的前缀中的MIME类型来确定,但用户可能已经指定了输出路径的扩展名。所以,我们按照用户指定的输出路径扩展名来保存。 如果用户没有指定扩展名,我们可以尝试从Base64字符串中解析MIME类型,但这里我们假设用户已经指定了正确的扩展名(如.jpg, .png等)。 因此,我们主要关注目录创建和文件写入。 代码实现:</think>### Java实现Base64字符串图片文件并自动创建目录 以下是将Base64编码字符串转换为图片文件并自动创建目录的完整Java实现方案: ```java import java.io.FileOutputStream; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.util.Base64; public class Base64ToImageConverter { public static void main(String[] args) { // 示例Base64字符串(实际使用时替换为您的数据) String base64Image = "iVBORw0KGgoAAAANSUhEUgAAAAUA..."; // 实际Base64字符串长得多 // 目标图片路径(可包含多级目录) String outputPath = "images/profile/avatar.png"; convertBase64ToImage(base64Image, outputPath); } public static void convertBase64ToImage(String base64String, String outputPath) { try { // 1. 提取并创建目标目录 Path outputDir = Paths.get(outputPath).getParent(); if (outputDir != null && !Files.exists(outputDir)) { Files.createDirectories(outputDir); System.out.println("目录创建成功: " + outputDir); } // 2. 处理Base64前缀(如果存在) String pureBase64 = base64String; if (base64String.contains(",")) { pureBase64 = base64String.split(",")[1]; } // 3. 解码Base64并写入文件 byte[] imageBytes = Base64.getDecoder().decode(pureBase64); try (FileOutputStream fos = new FileOutputStream(outputPath)) { fos.write(imageBytes); } System.out.println("图片保存成功: " + outputPath); } catch (Exception e) { System.err.println("转换失败: " + e.getMessage()); e.printStackTrace(); } } } ``` #### 关键功能解析 1. **目录自动创建**: ```java Path outputDir = Paths.get(outputPath).getParent(); if (outputDir != null && !Files.exists(outputDir)) { Files.createDirectories(outputDir); // 创建多级目录 } ``` - 自动处理多级目录创建(如`images/profile/`) - 使用Java NIO的`Files.createDirectories()`确保线程安全[^1] 2. **Base64数据处理**: ```java // 处理常见的数据URI前缀 if (base64String.contains(",")) { pureBase64 = base64String.split(",")[1]; } byte[] imageBytes = Base64.getDecoder().decode(pureBase64); ``` - 自动去除`data:image/png;base64,`等前缀 - 使用Java 8+内置的Base64解码器[^2] 3. **文件写入**: ```java try (FileOutputStream fos = new FileOutputStream(outputPath)) { fos.write(imageBytes); // 二进制写入 } ``` - 使用try-with-resources确保流自动关闭 - 支持常见图片格式:PNG、JPG、GIF等 #### 常见场景处理 1. **带前缀的Base64字符串**: ```java // 输入示例 String base64WithPrefix = "data:image/jpeg;base64,/9j/4AAQSkZJRgABA..."; ``` - 代码自动提取`/9j/4AAQSkZJRgABA...`纯编码部分 2. **不同图片格式支持**: | 文件扩展名 | MIME类型前缀 | 处理方式 | |------------|--------------|----------| | .png | image/png | 自动识别 | | .jpg | image/jpeg | 自动识别 | | .gif | image/gif | 自动识别 | 3. **错误处理增强**: ```java // 添加格式验证 if (!base64String.matches("^[a-zA-Z0-9+/=]+$")) { throw new IllegalArgumentException("无效的Base64格式"); } ``` #### 实际应用扩展 1. **结合Spring Boot接收上传**: ```java @PostMapping("/upload") public String uploadImage(@RequestParam String base64Data) { String filePath = "uploads/" + UUID.randomUUID() + ".png"; convertBase64ToImage(base64Data, filePath); return "保存成功: " + filePath; } ``` 2. **图片元数据提取**: ```java // 获取图片尺寸 BufferedImage image = ImageIO.read(new File(outputPath)); int width = image.getWidth(); int height = image.getHeight(); ``` 3. **Base64验证优化**: ```java // 检查Base64长度有效性 if (pureBase64.length() % 4 != 0) { throw new IllegalArgumentException("Base64长度无效"); } ```
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值