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中就可以了。

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章