Canvas图保存成图片或pdf

        Canvas画好的图片虽然可以通过toDataURL()转成二进制流的字符串格式,图片稍大一点就无法发送了,当然如果需求简单的话,可以在页面上加一个image元素,将转成的流直接赋给image的src就可以显示图片了。

        但是大部分的时候我们还希望弹出保存框,保存图片到我们自己想要的路径下,或者添加一些统计和分析的信息到pdf中一起保存成一个pdf文件,这就需要在后台处理了,两种方式:后台新建一个Web Browser加载当前的页面,然后将获得到的图片流的信息再发送到前台弹出保存的对话框,后台发送到前台是没有字符长度的限制的,不过如果要保存成pdf,就需要截图然后放到pdf中,图片太长就会截断;另一种方式就是将用到的参数传到后台,后台用GDI+在Bitmap上重新画一遍,Canvas能实现的,后台的GDI+同样都能实现,而且有些实现可能更方便一些,这个方法的好处是,没有图片大小的限制。

        我最近做的一个项目用的是第二种方法实现的,贴下代码吧:

1、前台代码【点击保存图片按钮】:

        var width = drawObject.getCanvas().width;
	var height = drawObject.getCanvas().height;
	var figures = drawObject.getCurrentFigures();
	$.ajax(
	{
		url: "./WareHousePrintHandler.ashx?action=drawpng&width=" + width + "&height=" + height,
		type: "post",
		data: "datas=" + JSON.stringify(figures),
		success: function (fileName)
		{
			$('#frameImage').attr('src', "./WareHousePrintHandler.ashx?action=getpng&fileName=" + fileName);
		},
		error: function (err)
		{
			alert("Print failed.");
		}
	});

        将前台需要画图的信息通过ajax传到后台的一个handler中,handler负责接收参数,并且将画好的图片保存至某个IIS的共享路径下,图片名称返回到前台,前台再用一个大小为0的iframe去通过重新加载页面,通过此图片名称去后台取图片流并弹出保存提示框。

2、iframe的代码

<iframe width="0" height="0" id="frameImage" name="frameImage" frameborder="0" scrolling="no"></iframe>

3、后台代码

if (action.ToString() == "drawpng")
{
	if (context.Request["datas"] == null)
	{
		return;
	}

	double w = double.Parse(context.Request["width"].ToString());
	double h = double.Parse(context.Request["height"].ToString());
	string allFigures = context.Server.UrlDecode(context.Request["datas"].ToString());
	List<DrawModel> figureList = AspSoft.WareHouse.Util.JsonHelper.JsonDeserialize<List<DrawModel>>(allFigures);

	WareHouseDrawing drawing = new WareHouseDrawing();
	string fileName = drawing.GetImageUrl((int)w, (int)h, figureList, filePath);
	context.Response.Write(fileName);
	//ms.WriteTo(Response.OutputStream);
	context.Response.End();
}
else if (action.ToString() == "getpng")
{
	string fileName = context.Request["fileName"].ToString();
	string fullFileName = filePath + "/" + fileName;
	context.Response.AppendHeader("Content-Disposition", string.Format("Attachment; FileName={0}.png;", HttpUtility.UrlEncode(DateTime.Now.ToString("yyyyMMdd_HHmmss"), System.Text.Encoding.UTF8)));
	context.Response.WriteFile(fullFileName);
	context.Response.End();
}

       GetImageUrl是具体画的方法,将画好的图片保存到一个共享路径下,必须是IIS能访问的共享路径,不能是本地的路径,第二次请求是获得png,实际是获得png的路径,iframe加载图片的路径后会自动获得图片的流信息,这是浏览器自动处理的,这里关键的是要加上Attachment,要以附件的形式发送。

        此方法必须发送两次请求到后来才能完成,因为如果第一次就通过iframe的src方式请求图片,由于只能通过querystring的方式请求,不能传大的数据,因为需要画图的数据量也是比较大,必须先通过ajax请求。PDF的道理同上,就是将bitmap的信息放到PDF中就可以了。

 

 

 

你可能感兴趣的:(Ajax,canvas,pdf,png)