2013-06-18 36 views
3

我知道有很多關於這個問題的StackOverflow問題,但我已經搜索了儘可能多的代碼,並且還沒有讓我的代碼正常工作,所以我終於發佈了我自己的問題。保存HTML5 <canvas>帶有Java Servlet的圖像

我的目標是將我的網頁上的HTML5 <canvas>上的圖像保存到我的服務器上的文件中。我希望能夠使用Java servlet來實現這一點。

我使用JavasScript抓住畫布圖像數據是這樣的:

var canvas = document.getElementById("screenshotCanvas"); 
var context = canvas.getContext("2d");      
var imageDataURL = canvas.toDataURL('image/png'); 
// I'm not if I need to do this, I've tried several different ways to no avail 
//imageDataURL = imageDataURL.replace("image/png", "image/octet-stream"); 
//imageDataURL = imageDataURL.replace(/^data:image\/(png|jpeg);base64,/,""); 

$.ajax({ 
    url: screenshotCreateUrl, 
    type: "POST", 
    data: { imgBase64: imageDataURL }, 
    error: function(jqXHR, textStatus, errorThrown) { 
     // Handle errors 
    }, 
    success: function(data, textStatus, jqXHR) { 
     // Do some stuff 
    } 
}); 

我的Java servlet嘗試保存圖像,像這樣:

try { 
    HttpServletRequestWrapper wrappedRequest = new HttpServletRequestWrapper(request); 
    HttpServletRequestWrapper requestWithWrapper = (HttpServletRequestWrapper) wrappedRequest.getRequest(); 
    byte[] contentData = requestWithWrapper.getContentData(); 
    byte[] decodedData = Base64.decodeBase64(contentData);   
    FileOutputStream fos = new FileOutputStream("testOutput.png"); 
    fos.write(decodedData); 
    fos.close(); 
} catch(Exception e) { 
    // Handle exceptions 
} 

該servlet成功地寫出了一個圖像文件,但它無法正常打開並且不包含其中的所有圖像數據。我的javascript成功抓住<canvas>圖像數據,它看起來像這樣:

data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAASwAAACWCAYAAABkW7XSAAAgAElEQVR4nJTa51NcaZ7ge+QBIZBAwgoEkvDeJt577733njRk4r3PhDRAJkkmiTdCXqWqUlVXtZl209OzvWN27t17/5rvvoCu7t6ZmN158YnfcyJOnIjz4vnGEyeOWdRmAP+RaI3fT2I0PiTtBJF9KKD8TTKVb5IpPosl+zCMdFMgKQY/otTPCFl3IljhSPiWB5E7XkToPAnVexNq8CVyP5Cwg0CCDwII2vfHx+TDC6MXz3df8mznGc7bTthu2PJwxRrrufvcnzbn4bQFjnNWuK3a4r3hQrDmBSGbLwlRvyR0w5OQ9ZeErHsRsuFLyIYvQeu+BCh88Zf74K/wxU8ZgL8qEH9VEAHq0L8RqAkjeCuCsO1IwrVRhGujCNNdCdVFEayNJEQXdUUfTYg+mmC9AH99BL47YfjuhOK7G4KvIRhfQzDee4F47QXibQrCe98f730/vPf98N3zw9/kT+B+IG . . . [and so on] 

任何想法,我在這裏失蹤?我覺得我正在犯一些我無法發現的小錯誤。

+0

到目前爲止,我甚至都不知道JavaScript是否能夠將畫布編碼爲圖像...... 爲什麼不嘗試將請求參數作爲請求參數傳遞給request.getParameter( 「imgBase64」)? – cljk

+0

另外我會簡化JS到 $ .post(screenshotCreateUrl,{imgBase64:imageDataURL}); – cljk

回答

1

您希望獲取發佈參數,而不是請求的內容數據。此外,您還需要刪除編碼信息。

試試這個:

try { 
    HttpServletRequestWrapper wrappedRequest = new HttpServletRequestWrapper(request); 
    HttpServletRequestWrapper requestWithWrapper = (HttpServletRequestWrapper) wrappedRequest.getRequest(); 
    String imageString = wrappedRequest.getParameter("imgBase64"); 
    imageString = imageString.substring("data:image/png;base64,".length); 
    byte[] contentData = imageString.getBytes(); 
    byte[] decodedData = Base64.decodeBase64(contentData);   
    FileOutputStream fos = new FileOutputStream("testOutput.png"); 
    fos.write(decodedData); 
    fos.close(); 
} catch(Exception e) { 
    // Handle exceptions 
    e.printStackTrace(); 
} 
+0

感謝您的幫助,我嘗試了這一點,但仍然無法正常工作。 'testOutput.png'文件正在寫出,並在圖像查看器中打開,但圖像看起來是空白的。如果我在文本編輯器中打開該文件,則可以看到其中包含大量數據,但不能完全正確格式化或進行其他操作。 – Steph

3

有相同的任務,並能使其工作(沒有jQuery和與maclema的答覆的幫助下),使用的multipart/form-data的內容類型:

var xhr = new XMLHttpRequest(); 
xhr.open("post", "AddressOfYourServlet", false); 
var boundary = Math.random().toString().substr(2); 
xhr.setRequestHeader("content-type", 
    "multipart/form-data; charset=utf-8; boundary=" + boundary); 
var multipart = "--" + boundary + "\r\n" + 
    "Content-Disposition: form-data; name=myImg\r\n" + 
    "Content-type: image/png\r\n\r\n" + 
    canvas.toDataURL("image/png") + "\r\n" + 
    "--" + boundary + "--\r\n"; 
xhr.send(multipart); 

爲了異步去,或者如果你有更多的部分,以發送(如多張圖片),或者如果你想與應對工作,看到How to send multipart/form-data form content by ajax (no jquery)?

你的servlet的的doPost方法看起來是這樣的:

protected void doPost(HttpServletRequest request, HttpServletResponse response) 
     throws ServletException, IOException { 
    Part part = request.getPart("myImg"); 
    BufferedReader br = new BufferedReader(new InputStreamReader(part.getInputStream(), 
     Charset.forName("utf-8"))); 
    String sImg = br.readLine(); 
    sImg = sImg.substring("data:image/png;base64,".length()); 
    byte[] bImg64 = sImg.getBytes(); 
    byte[] bImg = Base64.decodeBase64(bImg64); // apache-commons-codec 
    FileOutputStream fos = new FileOutputStream("img.png"); 
    fos.write(bImg); 
} 

希望這有助於。

+0

@Steph如果這解決了您的問題,您可以將其標記爲最佳答案:-) – legolas108

+0

非常感謝您的幫助。它很好地解決了我的問題。永遠無法自己解決這個問題。 – Kiwi