2013-02-17 127 views
1

我在下面創建一個測試代碼,你可以操縱它的jsfiddle:保存畫布圖像失敗

http://jsfiddle.net/Stallman41/57hvX/31/
HTML:

<canvas id="test_canvas" style="background-color : #FFFF00" ; width="500px" 
; height="340px"></canvas> 
<br> 
<button id="test_put_btn">Put an image</button> 
<br> 
<button id="save_dataURL">Save to dataURL</button> 
<br> 
<button id="draw_back">Final step: draw 3 images back.</button> 
<br> 
<img id="first_img"; width="100px" ; height="100px" ;></img> 
<img id="second_img"; width="100px" ; height="100px" ></img> 
<img id="third_img"; width="100px" ; height="100px" ;></img> 

的Javascript:

var drawing_plate; 
var context; 
var dataURL_arr = new Array(); 
$(document).ready(function() { 
drawing_plate = document.getElementById("test_canvas"); 
context = drawing_plate.getContext('2d'); 


$("#test_canvas").bind("mousedown", Touch_Start); 
$("#test_canvas").bind("mousemove", Touch_Move); 
$("#test_canvas").bind("mouseup", Touch_End); 


}); //document ready. 



function Touch_Start(event) { 
event.preventDefault(); 
touch = event; 
touch_x = touch.pageX; 
touch_y = touch.pageY; 

line_start_x = touch.pageX - 0; 
line_start_y = touch.pageY - 0; 

context.beginPath(); 
context.moveTo(line_start_x, line_start_y); 
} 

function Touch_Move(event) { 
event.preventDefault(); 
touch = event; //mouse 
line_end_x = touch.pageX - 0; 
line_end_y = touch.pageY - 0; 
context.lineTo(line_end_x, line_end_y); 
context.stroke(); 
} 


$("#test_put_btn").click(function() { 
var test_img = new Image(); 
test_img.src = "http://careerscdn.sstatic.net/careers/gethired/img/careers2-  ad-header-so-crop.png"; 
context.drawImage(test_img, 0, 0); 
}); 

$("#save_dataURL").click(function() { 

dataURL_arr.push(drawing_plate.toDataURL("image/png")); 
}); 

$("#draw_back").click(function() { 
    var f_image= $("#first_img")[0]; 
    var s_image= $("#second_img")[0]; 
    var t_image= $("#third_img")[0]; 

f_image.onload= function() 
{ 
    f_image.src= dataURL_arr[0]; 
} 
    f_image.src= dataURL_arr[0]; 

s_image.onload= function() 
{ 
    s_image.src= dataURL_arr[0]; 
} 
    s_image.src= dataURL_arr[0];  

t_image.onload= function() 
{ 
    t_image.src= dataURL_arr[0]; 
} 
    t_image.src= dataURL_arr[0]; 

}); 


我在Android系統上開發一個繪圖板,將繪圖保存爲一個dataURL字符串。他們可以在畫布上繪製一些東西,並在畫布上放置圖像。我需要讓用戶在小圖標上看到他們的圖紙。我使用canvas.toDataURL("image/png")保存base64字符串。我選擇<img>作爲小圖標容器。但是,我得到的只是圖標可以顯示在圖標上,通常,當我寫img.src= canvas.toDataURL("image/png");圖像時什麼也沒有顯示!
我調查了很長一段時間的問題。
1.我認爲這個問題可能是dataURL字符串太長了?
2.對操作系統的支持:Android?


Jsfiddle中的代碼在這裏顯示了我的Android PhoneGap開發中的類似過程。
首先,您只需在畫布上繪製一些東西,然後按Press an image,然後按Save to dataURL。但是你應該做三次這個過程。在這種情況下,字符串數組包含由圖紙和圖像生成的base64字符串。
在最後,您按Final step: draw 3 images back.,圖像圖標上不會顯示任何內容。
結論:
根據我的經驗,因爲我寫img.src= canvas.toDataURL("image/png");(無論IMG是一個DOM元素或var img = new Image();)。它不能總是工作:有時它的工作原理......但有時不...


(我在Android 4.0.1,1.7.0的PhoneGap工作),尤其是如果我存儲大量將base64字符串轉換爲數組,將它們分配給許多圖像DOM元素,它肯定會失敗。
,如果用戶只畫在畫布上的東西,它總能正常工作。(除的jsfiddle示例代碼,但它的作品在我的Android系統上......) 但如果他繪製圖像context.drawImage(~)圖像不會顯示圖片。
太多混亂...
我需要讓用戶可以查看他們的圖紙在小圖標,任何替代?


一些參考:

1
2
3

回答

1

我只是碰到了這個問題絆倒了。

點擊把圖像,然後單擊保存到dataURL,然後檢查你的JavaScript控制檯類似:

SecurityError: DOM Exception 18 

這是一個瀏覽器的安全功能。由於您已插入來自其他網域的圖片,因此將其視爲一個跨網申請。

如果您使用eliminate the security error,則可以將畫布導出到數據URL。

+0

嗯,我在移動設備上工作(發展與PhoneGap),DOM Exception 18不應該發生。或者你認爲這個錯誤也可能發生? – Stallman 2013-04-06 07:52:33

+0

該例外不應限於任何特定設備或瀏覽器;這是一個普遍的安全機制。除非網站響應標題專門配置爲允許其他域名,否則通常不允許跨域請求。更多信息[在這裏](http://en.wikipedia.org/wiki/Cross-origin_resource_sharing):) – c24w 2013-04-06 10:09:51

0

代碼中的另一件事。

您嘗試在畫布上繪製到您的test_put_btn onclick事件處理程序中的圖像,您的圖像將永遠不會顯示(或者它有時會意外地工作),因爲您不等待圖像被加載繪製到畫布。

您必須處理圖像的「onload」事件並將其繪製到處理程序中以允許繪製圖像。

您test_img.src聲明之前,你必須把:

test_img.onload = function() 
{ 
    context.drawImage(test_img, 0, 0); 
}; 

此外,您嘗試訪問的圖像不能訪問 - >For me it does not work