Base64 ข้อมูล PNG ไปยังผ้าใบ HTML5


90

ฉันต้องการโหลดภาพ PNG ที่เข้ารหัสใน Base64 เป็นองค์ประกอบ canvas ฉันมีรหัสนี้:

<html>
<head>
</head>
<body>
<canvas id="c"></canvas>
<script type="text/javascript">

var canvas = document.getElementById("c");
var ctx = canvas.getContext("2d");

data =  "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAIAAAACDbGyAAAAAXNSR0IArs4c6QAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB9oMCRUiMrIBQVkAAAAZdEVYdENvbW1lbnQAQ3JlYXRlZCB3aXRoIEdJTVBXgQ4XAAAADElEQVQI12NgoC4AAABQAAEiE+h1AAAAAElFTkSuQmCC";

ctx.drawImage(data, 0, 0);

</script>
</body>
</html>

ใน Chrome 8 ฉันได้รับข้อผิดพลาด: Uncaught TypeError: Type error

และใน Firebug ของ Firefox สิ่งนี้: "ประเภทของวัตถุไม่เข้ากันกับประเภทที่คาดไว้ของพารามิเตอร์ที่เกี่ยวข้องกับวัตถุ" code: "17"

ใน base64 นั้นคือสี่เหลี่ยม PNG สีดำขนาด 5x5px ที่ฉันทำใน GIMP และเปลี่ยนเป็น base64 ในโปรแกรม base64 ของ GNU / Linux

คำตอบ:


172

โดยรูปลักษณ์ของมันคุณต้องผ่าน drawImage วัตถุรูปภาพจริงๆ

var canvas = document.getElementById("c");
var ctx = canvas.getContext("2d");

var image = new Image();
image.onload = function() {
  ctx.drawImage(image, 0, 0);
};
image.src = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAIAAAACDbGyAAAAAXNSR0IArs4c6QAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB9oMCRUiMrIBQVkAAAAZdEVYdENvbW1lbnQAQ3JlYXRlZCB3aXRoIEdJTVBXgQ4XAAAADElEQVQI12NgoC4AAABQAAEiE+h1AAAAAElFTkSuQmCC";
<canvas id="c"></canvas>

ฉันได้ลองใช้ใน chrome แล้วและใช้งานได้ดี


8
คำตอบที่ดี แต่คุณแน่ใจหรือไม่ว่าจะได้ผลทุกครั้ง ฉันพบว่ามันมีปัญหาในการวาดภาพทันทีหลังจากตั้งค่าsrcเนื่องจากคุณควรใช้การonloadโทรกลับเพื่อให้แน่ใจว่ารูปภาพโหลดเสร็จแล้ว 50% ของการทดสอบของฉันล้มเหลวเนื่องจากโหลดรูปภาพไม่เสร็จ
Scott Rippey

ว้าว! ระเบิดจากอดีต :) คุณค่อนข้างถูกต้อง หากคุณกำลังเรียก drawImage หลังจากที่คุณตั้งค่า src ของรูปภาพแล้วคุณอาจประสบปัญหาและขึ้นอยู่กับสถานการณ์ของคุณคุณมักจะต้องการใช้ onload เพื่อให้แน่ใจว่ารูปภาพนั้นโหลดจริงก่อนที่คุณจะพยายามแสดงผล ลงบนผืนผ้าใบ โค้ดด้านบนเป็นเพียงตัวอย่างเพิ่มเติมที่แสดงให้เห็นว่า drawImage ต้องการออบเจ็กต์รูปภาพจริง ๆ และจะส่งผ่านไปได้อย่างไร
Jerryf

8
โปรดทราบว่าหากคุณกำลังวนซ้ำหลายแคนวาสคุณอาจต้องเปลี่ยนเป็นเพื่อctx.drawImage(this,0,0);ให้แน่ใจว่าตัวแปรรูปภาพอ้างถึงรูปภาพที่ถูกต้อง ตอบดีมาก!
Dormouse

13
ควรตั้งค่าเหตุการณ์ onload ก่อน src บางครั้งสามารถโหลด src ได้ทันทีและไม่เริ่มเหตุการณ์ onload
Totty.js

3
แต่ถ้าdata:image/ความยาวมากเราจะได้414 (Request-URI Too Long
Sarath

17

คำตอบของ Jerryf นั้นใช้ได้ยกเว้นข้อบกพร่องเดียว

ควรตั้งค่าเหตุการณ์ onload ก่อน src บางครั้งสามารถโหลด src ได้ทันทีและไม่เริ่มเหตุการณ์ onload

(เช่นเดียวกับที่ Totty.js ชี้ให้เห็น)

var canvas = document.getElementById("c");
var ctx = canvas.getContext("2d");

var image = new Image();
image.onload = function() {
    ctx.drawImage(image, 0, 0);
};
image.src = "data:image/  png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAIAAAACDbGyAAAAAXNSR0IArs4c6QAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB9oMCRUiMrIBQVkAAAAZdEVYdENvbW1lbnQAQ3JlYXRlZCB3aXRoIEdJTVBXgQ4XAAAADElEQVQI12NgoC4AAABQAAEiE+h1AAAAAElFTkSuQmCC";

2
Btw: ฉันแก้ไขคำตอบของ Jerryf แต่มีคนปฏิเสธ ไม่สามารถเป็นเจอร์รีฟได้เนื่องจากโปรไฟล์ของเขาระบุว่าเขาเข้าสู่ระบบครั้งล่าสุดในปี 2014
จอห์น

3
"บางครั้งสามารถโหลด src ได้ทันทีและห้ามเริ่มการทำงานของเหตุการณ์ onload" ฉันคิดว่าเหตุการณ์นี้เกิดขึ้นได้ยากมากจนแทบจะไม่เคยมีมาก่อน แต่ไม่มีเหตุผลใดที่จะไม่ทำให้เป็นนิสัยมาonloadก่อนsrc... ฉันทำจนเป็นนิสัย
markE

2
@markE ไม่ใช่ของหายาก จะเกิดขึ้นตลอดเวลาเมื่อเบราว์เซอร์แคชรูปภาพตัวอย่างเช่นเมื่อเบราว์เซอร์โหลดซ้ำ สิ่งนี้เกิดขึ้นในโปรแกรม IE ในโปรแกรม c ++
Stefan Rein
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.