Javascript 将画布保存为PNG或JPEG文件

Javascript 将画布保存为PNG或JPEG文件,javascript,php,html,canvas,Javascript,Php,Html,Canvas,我目前正在编写一个网站,用户可以上传.mp4视频。我想在用户上传视频并将此图像写入我服务器上的.jpg或.png文件时制作一个缩略图 我遇到的问题是,该文件存储在我的服务器上,但它没有被视为图像文件 这是我目前的代码 HTML部分 <canvas id="c"></canvas> <video id="v" controls> <source src="/215003/1.1/videos/7/f9ed57e2b0ee1e87a4cbc17c7b74

我目前正在编写一个网站,用户可以上传.mp4视频。我想在用户上传视频并将此图像写入我服务器上的.jpg或.png文件时制作一个缩略图

我遇到的问题是,该文件存储在我的服务器上,但它没有被视为图像文件

这是我目前的代码

HTML部分

<canvas id="c"></canvas>
<video id="v" controls>
  <source src="/215003/1.1/videos/7/f9ed57e2b0ee1e87a4cbc17c7b743eff.mp4" type="video/mp4">
</video>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
处理数据和存储图像的PHP文件:

<?php
// requires php5
define('UPLOAD_DIR', 'img/');
$img = $_POST['img'];
$img = str_replace('data:image/png;base64,', '', $img);
$img = str_replace(' ', '+', $img);
$data = base64_decode($img);
$file = UPLOAD_DIR . uniqid() . '.png';
$success = file_put_contents($file, $data);
print $success ? $file : 'Unable to save the file.';
?>


有人能帮我吗?:)

我很少使用PHP,但我知道Base64编码中没有空格。并不是说它会因为没有空格而改变任何东西,但为什么第二个会用加号替换空格呢

至于你的问题。您需要更改用于触发post的事件
onloadedmetadata
在有任何数据渲染帧之前激发。您应该使用
oncanplay
,然后您将有数据要发送,尽管这样您至少应该得到一个空白图像。要查看客户端上的内容,请添加'image=new image();image.src=dataURL;'然后将该图像添加到dom中,您可以看到是否得到了想要的,而不是猜测


除此之外,我什么也找不到

我终于发现了我的错误。问题是draw函数有一个SetTimeOut函数。所以我只是在我的服务器上写了一个黑色的图像,因为DataTour函数触发的太快了

解决方法是将draw函数之后的所有内容都放在write函数中。并给该函数一个超时,以确保绘制图像

以下是更正后的代码:

document.addEventListener('DOMContentLoaded', function(){
 var v = document.getElementById('v');
 var canvas = document.getElementById('c');
 var context = canvas.getContext('2d');

 var v = document.getElementById("v");
v.addEventListener('loadedmetadata', function() {
 this.currentTime = this.duration / 3;
 }, false);
v.addEventListener( "loadedmetadata", function () {
 var cw = this.videoWidth;
 var ch = this.videoHeight;
    console.log(cw); //displaying the width of the video
    console.log(ch); //displaying the height of the video
    canvas.width = cw; //seting the width of the canvas
    canvas.height = ch; //setting the height of the canvas
    draw(this,context,cw,ch); // Drawing the image from the video onto the canvas
    setTimeout(function() {
    write(canvas);
    }, 1000)
    }, false );

},false);

function draw(v,c,w,h) {
 c.drawImage(v,0,0,w,h);
 setTimeout(draw,20,v,c,w,h);
}
function write(c) {
 var dataURL = c.toDataURL('image/jpeg');
 var image = document.createElement("img");
    image.src=dataURL;
    document.getElementById("placehere").appendChild(image);
    $.ajax({
      type: 'POST',
      url: 'saveThumb.php',
      data: 'img=' + dataURL
    }).done(function(o) {
        console.log(dataURL);
      console.log('saved'); 
    });
}

并检查你的控制台。当你尝试此操作时,会出现什么错误?你能通过FTP或其他方式查看图像文件吗?还是该文件不能作为图像文件正确存在?嗨,杰克,我在执行程序时没有收到任何错误。我可以在FTP服务器上看到文件及其大小。但是当我用windows打开它时,它说文件无法识别。这是我从“canvas.toDataURL('image/png');”中获得的数据数据:图像/png;base64,Ivborw0kggoaaansuhueugaaoaaaaaafocayaaadhmkpraaasdkleqvr4xu3wqqeaagcmelf2ia3gzb8shmecbagqiaaqipgaxsck(以及更多字符)Hi blindman 67,当我将“onload元数据”改为“oncanplay”或“canplay”时,程序进入了一个循环,没有结束。因此,我将我的can play更改为“onloadedmetadata”,我添加了您建议显示图像的行,现在我看到Base64编码只为PNG提供了一个空白图像,为Jpeg提供了一个黑色图像。。。我认为javascript中的编码肯定有问题,我认为程序进入循环,因为draw函数使用settimeout调用它自己。更改回oncanplay并删除设置的超时。
document.addEventListener('DOMContentLoaded', function(){
 var v = document.getElementById('v');
 var canvas = document.getElementById('c');
 var context = canvas.getContext('2d');

 var v = document.getElementById("v");
v.addEventListener('loadedmetadata', function() {
 this.currentTime = this.duration / 3;
 }, false);
v.addEventListener( "loadedmetadata", function () {
 var cw = this.videoWidth;
 var ch = this.videoHeight;
    console.log(cw); //displaying the width of the video
    console.log(ch); //displaying the height of the video
    canvas.width = cw; //seting the width of the canvas
    canvas.height = ch; //setting the height of the canvas
    draw(this,context,cw,ch); // Drawing the image from the video onto the canvas
    setTimeout(function() {
    write(canvas);
    }, 1000)
    }, false );

},false);

function draw(v,c,w,h) {
 c.drawImage(v,0,0,w,h);
 setTimeout(draw,20,v,c,w,h);
}
function write(c) {
 var dataURL = c.toDataURL('image/jpeg');
 var image = document.createElement("img");
    image.src=dataURL;
    document.getElementById("placehere").appendChild(image);
    $.ajax({
      type: 'POST',
      url: 'saveThumb.php',
      data: 'img=' + dataURL
    }).done(function(o) {
        console.log(dataURL);
      console.log('saved'); 
    });
}