Java图片合成、base64转换

本文介绍了一种使用Java合并身份证正反面图片的方法,并将其调整尺寸后合成一张新图片。合成后的图片能够被重新编码为Base64字符串,便于在网络中传输。文章还提供了具体的代码实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

主要是工作中用到要将客户上传的身份证正反面照片从数据库中取出来(格式为base64字符串,竟然是将图片保存在数据库里面的),合成成为一张图片,然后再转码为base64,调用第三方接口把合成图片的base64传过去。(后面就不知道他们拿去干什么了)

  • 图片合成
参考: 使用Java合并图片 ,写了一个图片合成的例子,可以优化的地方还有很多。仅供参考。
图片尺寸缩放(压缩),网上很多都是使用老版本的 JPEGImageEncoder类的方法,这个方法是sun公司私有方法,IDE没有设置的话可能找不到这个类。现在采用的是ImageIO类的方法,可以正常输出图片。
import java.awt.Graphics;
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;

import javax.imageio.ImageIO;

public class CompositePhotograph
{
/**
* @描述: 合成图片
* @param face 身份证正面
* @param back 身份证反面
* @param fileName 合成图片文件名
* @return
* @throws IOException
*/
public static File compositePhoto(File face , File back ,String fileName) throws IOException{
BufferedImage b1 = ImageIO.read(face);
BufferedImage b2 = ImageIO.read(back);
//根据两张图片得到合成图片的宽高
int width = b1.getWidth()<b2.getWidth() ? b1.getWidth() : b2.getWidth();
int height = b1.getHeight() + b2.getHeight();
//合成的图片
BufferedImage cp = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
Graphics g = cp.getGraphics();
g.drawImage(b1,0,0,null);//上部分
g.drawImage(b2,0,b1.getHeight(),null);//下部分
//检查文件
File f = new File(fileName);
if(f.exists()){
f.delete();
f.createNewFile();
}else{
f.createNewFile();
}
//输出图片
ImageIO.write(cp, "jpg", f);
return f;
}

/**
* @描述: 改变图片尺寸,按给出的width,等比例缩放高
* @param bi 需要改变的图片
* @param fileName 生成的新图片的文件名
* @param width 修改的宽
* @return
* @throws IOException
*/
public static File resize(File source,String fileName,int width) throws IOException{
Image img = ImageIO.read(source);//原图片文件
int srcW = img.getWidth(null);
int srcH = img.getHeight(null);
double x = (double)width/(double)srcW;//缩放比例
int height = (int) (srcH * x);//缩放后的高
//新图片
BufferedImage newImg = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
//缩放后的图片
Image tag = img.getScaledInstance(width, height, Image.SCALE_SMOOTH);
newImg.getGraphics().drawImage(tag, 0, 0, null);//绘制到画板上
File f = new File(fileName);
if(f.exists()){
f.delete();
f.createNewFile();
}else{
f.createNewFile();
}
/* 输出到文件流 ,网上很多都是这种写法,这是已经过时了的写法,现在都使用ImageIO.write()来输出压缩后的文件了
FileOutputStream out = new FileOutputStream(f);
JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out);
encoder.encode(tag);
out.flush();
out.close();
*/
//写入文件
ImageIO.write(newImg, "jpg", f);
return f;
}
}



  • base64编码转换
在读取BufferedInputStream输入流的内容的时候,使用了这个byte[] bytes = new byte[bis.available()];bis.read(bytes);一次性将文件内容全部读取出来。之前试过使用while( (count=bis.read(bytes)) != -1 ){ strBuilder.append(bytes); }来分步读取,但是读取出来的结果不对,也没有去探究原因//TODO 待查吧。
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

import org.apache.commons.codec.DecoderException;
import org.apache.commons.codec.binary.Base64;

public class DENcode
{
//读写尺寸
private final static int SIZE = 1024*10;

/**
* @描述: 将文件编码为base64格式
* @param f 要编码的文件
* @return
* @throws IOException
*/
public String encode(File f) throws IOException{
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(f));//将文件转换成流
byte[] bytes = new byte[bis.available()];//记录二进制数组,大小为bis读取不阻塞长度
bis.read(bytes);//一次性全部读取
bis.close();
Base64 b = new Base64();
byte[] encodeFile = b.encode(bytes);//编码
return new String(encodeFile);
}

/**
* @描述: 将base64解码为图片文件
* @param base64Str base64编码字符串
* @param fileName 转换成的图片文件名
* @return
* @throws DecoderException
* @throws IOException
*/
public File decode(String base64Str,String fileName) throws DecoderException, IOException{
//使用apache的编解码类
Base64 b = new Base64();
byte[] by = b.decode(base64Str);
//调整异常数据
for(int i=0;i<by.length;++i){
if(by[i]<0){
by[i]+=256;
}
}
File df = new File(fileName);
//删除旧文件,防止写入时有垃圾数据
if(df.exists()){
df.delete();
}else{
df.createNewFile();
}
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(df),SIZE);
bos.write(by);
bos.flush();
bos.close();
return df;
}

}



  • 一个小demo,实现前面的业务逻辑

import java.io.File;
import java.io.IOException;

import org.apache.commons.codec.DecoderException;

import composite_photograph.CompositePhotograph;
import ende_code.DENcode;

public class Photograph
{
public static void main(String[] args) throws DecoderException, IOException
{
System.out.println("开始");

String fan = "base64字符串1";

String zheng = "base64字符串2";

DENcode denCode = new DENcode();
File fanF = denCode.decode(fan, "resources/fan.jpg");
File zhengF = denCode.decode(zheng, "resources/zheng.jpg");
File reFanF = CompositePhotograph.resize(fanF, "resources/reFan.jpg", 500);
File reZhengF = CompositePhotograph.resize(zhengF, "resources/reZheng.jpg", 500);
File cpF = CompositePhotograph.compositePhoto(reZhengF, reFanF,"resources/cp.jpg");
String cpStr = denCode.encode(cpF);
System.out.println("完成");
}
}

Java中,可以使用Apache PDFBox库来处理PDF文件,并结合其他工具库如Bouncy Castle用于Base64解码,然后利用ImageIO来将解码后的数据转换图片。以下是一个简单的步骤概述: 1. 添加依赖:首先需要在项目中引入Apache PDFBox和Bouncy Castle库。如果你使用Maven,可以在pom.xml文件中添加以下依赖: ```xml <dependency> <groupId>org.apache.pdfbox</groupId> <artifactId>pdfbox</artifactId> <version>2.0.24</version> </dependency> <dependency> <groupId>org.bouncycastle</groupId> <artifactId>bcpkix-jdk15on</artifactId> <version>1.78</version> </dependency> ``` 2. 解码Base64:创建一个函数来解码Base64字符串,通常会使用`Base64.getDecoder().decode()`方法。 ```java import java.util.Base64; public byte[] decodeBase64(String base64String) { return Base64.getDecoder().decode(base64String); } ``` 3. 打开PDF并提取图像:使用PDFBox打开PDF文件,找到包含图像的页面,然后获取图像数据。 ```java import org.apache.pdfbox.pdmodel.PDDocument; import org.apache.pdfbox.pdmodel.common.PDRectangle; import org.apache.pdfbox.pdmodel.graphics.image.PDImageXObject; public PDImageXObject getImageFromPage(PDDocument document, int page) { // 获取指定页面 PDPage pageObject = document.getDocumentCatalog().getPages().get(page); PDRectangle mediaBox = pageObject.getMediaBox(); for (PDResources resources : pageObject.getResources()) { if (resources instanceof PDImageXObject) { PDImageXObject image = (PDImageXObject) resources; return image; } } throw new IllegalArgumentException("No image found on the specified page."); } ``` 4. 将图像数据保存为图片:将解码出的图像数据保存为图片文件,例如PNG或JPEG。 ```java import javax.imageio.ImageIO; import java.awt.image.BufferedImage; import java.io.File; import java.io.IOException; public void saveImageAsFile(byte[] imageData, String filePath) throws IOException { BufferedImage bufferedImage = ImageIO.read(new ByteArrayInputStream(imageData)); File outputFile = new File(filePath); ImageIO.write(bufferedImage, "png", outputFile); } ``` 5. 合成整个过程:将上述部分组合在一起,遍历PDF中的每一页,如果找到图像就将其转换并保存。 ```java public void convertPdfToImage(String pdfPath, String outputDir) { try { PDDocument document = PDDocument.load(new File(pdfPath)); int totalPages = document.getNumberOfPages(); for (int i = 0; i < totalPages; i++) { PDImageXObject image = getImageFromPage(document, i); byte[] imageData = decodeBase64(image.getData()); saveImageAsFile(imageData, outputDir + "/page_" + (i+1) + ".png"); } document.close(); } catch (IOException e) { e.printStackTrace(); } } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值