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

问题描述:

我通过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
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
提供的源码资源涵盖了安卓应用、小程序、Python应用和Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值