怎样将html5中利用canvas绘制的图像在服务端保存为图片?

本文介绍如何正确处理HTML5 Canvas生成的Base64编码图像数据,包括解码过程和保存为本地文件的方法。

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

问题描述:

我通过html5的canvas绘制了一个图像,然后用toDataURL("image/jpeg")将生成的数据提交到服务器端。因为提交过来其实是data URI地址,而且该地址分为两部分,中间用逗号分割,其中第一部分为“data:”+导出图像的MIME类型+“;base64”,第二部分为一个经过base64编码的字符串。我想通过Base64解码后将数据保存成图片,但是我的方法保存的图片无法查看,打开时显示“已经损坏”,求解答。
我的主要代码:

public class Base64 {
	/**
	 * 对字符串进行Base64解码
	 * @param s 要解码的字符串
	 * @return 返回解码后的字符串
	 */
	public static String decode(String s){
		String decoded_str=null;
		BASE64Decoder decoder=new BASE64Decoder();
		try {
			byte[] bytes=decoder.decodeBuffer(s);
			decoded_str=new String(bytes);
		} catch (IOException e) {
			e.printStackTrace();
		}
		return decoded_str;
	}
}

/**
 * 得到经过Base64解码的图像二进制数据
 */
public String getImgData(){
	/*
	 * 利用canvas元素的toDataURL("image/jpeg")方法生成的图像地址格式为:
	 *	第一部分:data:image/jpeg;base64
	 * 	中间一个逗号
	 * 	第二部分:一个经过base64编码的字符串,通过Base64解码后即可得到该图像原始二进制数据
	 */
	String[] data=fileUrl.split(",");//这里fileUrl就是前台toDataURL()方法传过来的数据
	return Base64.decode(data[1]);
}

/**
 * 保存Base64解码后的二进制数据到文件
 * @param base64Str 经Base64解码后的图片原始二进制数据
 * @param path 文件路径
 */
public void saveImage(String base64Str,String path){
	File file=new File(path);
	FileOutputStream outputStream=null;
	try {
		outputStream=new FileOutputStream(file);
		outputStream.write(base64Str.getBytes());
	} catch (FileNotFoundException e) {
		e.printStackTrace();
	} catch (IOException e) {
		e.printStackTrace();
	} finally{
		closeSteam(outputStream);
	}
}

/**
 * 关闭文件输出流
 * @param outputStream
 */
public void closeSteam(FileOutputStream outputStream){
	if(outputStream!=null){
		try {
			outputStream.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}

最后调用saveImage(getImgData(), imgPath);保存到图片文件。

解答(by 德问用户YODA):

首先你得搞明白为什么需要Base64这个东西,Base64的主要应用场景就是把二进制(Binary)的内容通过一个映射转换到可以用ASCII字符表达的字符串,然后便于使用HTTP协议在客户端和服务器端传输数据。所以,关键的一部你做的有些问题

byte[] bytes=decoder.decodeBuffer(s);

这里解码出来的byte[]已经是你的图片内容了,这些byte不可能再成功的构造成字符串了,否则为何还需要用Base64啊。所以,你需要保存的是解码出来的byte[],而不是Base64的字符串。

另外,Base64的编解码器,你用的那个BASE64Decoder是sun.misc提供的,为了确保最大化的兼容,比如运行在非Sun JVM的环境时,建议使用apache的common-codec。

解决:

修改Base64工具类的decode方法,并对其他调用方法进行相应修改。

修改后程序如下:

public class Base64 {
	/**
	 * 对字符串进行Base64解码
	 * @param s 要解码的字符串
	 * @return 返回解码后的字符串
	 */
	public static byte[] decode(String s){
		String decoded_str=null;
		BASE64Decoder decoder=new BASE64Decoder();
		byte[] bytes=null;
		try {
			bytes=decoder.decodeBuffer(s);
		} catch (IOException e) {
			e.printStackTrace();
		}
		return bytes;
	}
}
/**
 * 得到经过Base64解码的图像二进制数据
 */
public byte[] getImgData(){
	/*
	 * 利用canvas元素的toDataURL("image/jpeg")方法生成的图像地址格式为:
	 *	第一部分:data:image/jpeg;base64
	 * 	中间一个逗号
	 * 	第二部分:一个经过base64编码的字符串,通过Base64解码后即可得到该图像原始二进制数据
	 */
	String[] data=fileUrl.split(",");//这里fileUrl就是前台toDataURL()方法传过来的数据
	return Base64.decode(data[1]);
}

/**
 * 保存Base64解码后的二进制数据到文件
 * @param base64Str 经Base64解码后的图片原始二进制数据
 * @param path 文件路径
 */
public void saveImage(byte[] imageBytes,String path){
	File file=new File(path);
	FileOutputStream outputStream=null;
	try {
		outputStream=new FileOutputStream(file);
		outputStream.write(imageBytes);
	} catch (FileNotFoundException e) {
		e.printStackTrace();
	} catch (IOException e) {
		e.printStackTrace();
	} finally{
		closeSteam(outputStream);
	}
}

/**
 * 关闭文件输出流
 * @param outputStream
 */
public void closeSteam(FileOutputStream outputStream){
	if(outputStream!=null){
		try {
			outputStream.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值