2015-02-11 26 views
0

我试图在saveimage.php处理它们之前制作一个上传脚本,它调整了多个图像客户端的大小。原因是因为他们会在可能非常缓慢的互联网的外部位置上传。通过javascript循环上传多个画布图像

我已经能够找到这里的代码片段,这帮助我把它放在一起。我只是一个初学者,所以它可能非常混乱!

它目前的功能是检查文件是否在'file_input'字段中输入。然后它会查看文件的数量并遍历它们,直到每个文件都被放置在画布上并在其中进行上传。

但是,问题是:当我没有为每个文件添加警报时,循环速度过快,例如只处理10或10个图像中的1或2个。因为上传脚本将比使用新图像更新画布更快。

这是我当前的页面,简化为核心:

<!DOCTYPE html> 
<html> 
<head> 
    <script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script> 
</head> 
<body> 

<form> 
    <input id="file_input" type='file' multiple /> 
</form> 

<div id="preview"> 
    <canvas id="canvas"></canvas> 
</div> 

<script> 

    var input = document.getElementById('file_input'); 
    input.addEventListener('change', handleFiles); 

    function handleFiles(e) { 

     var files = input.files; 
     alert(files.length +" files are being uploaded!"); // display amount of files for testing purpose 

     for (var i = 0; i < files.length; ++i) { 

      alert("Upload file number: "+i); // display file # for testing purpose, when this is removed the script will go too fast 

      var MAX_HEIGHT = 1000; 
      var ctx = document.getElementById('canvas').getContext('2d'); 
      var img = new Image; 

      img.onload = function(){ 
       if(img.height > MAX_HEIGHT) { 
        img.width *= MAX_HEIGHT/img.height; 
        img.height = MAX_HEIGHT; 
       } 
       var ctx = canvas.getContext("2d"); 
       ctx.clearRect(0, 0, canvas.width, canvas.height); 
       preview.style.width = img.width + "px"; 
       preview.style.height = img.height + "px"; 
       canvas.width = img.width; 
       canvas.height = img.height; 
       ctx.drawImage(img, 0, 0, img.width, img.height); 

       // the canvas should contain an image now and this will send it through saveimage.php 
       var myDrawing = document.getElementById("canvas"); 
       var drawingString = myDrawing.toDataURL("image/jpeg", 0.5); 
       var postData = "canvasData="+drawingString; 
       var ajax = new XMLHttpRequest(); 
       ajax.open("POST",'saveimage.php',true); 
       ajax.setRequestHeader('Content-Type', 'canvas/upload'); 
       ajax.onreadystatechange=function() 
        { 
         if (ajax.readyState == 4); 
        } 
        ajax.send(postData); 
      }; 

      img.src = URL.createObjectURL(e.target.files[i]); 
     } 
    } 

</script> 

</body> 
</html> 

这是我saveimage.php效果很好,但只是为完整的综述:

<?php 

if (isset($GLOBALS["HTTP_RAW_POST_DATA"])) 
{ 
    $rawImage=$GLOBALS['HTTP_RAW_POST_DATA']; 
    $removeHeaders=substr($rawImage, strpos($rawImage, ",")+1); 
    $decode=base64_decode($removeHeaders); 

    // check if the file already exists and keep adding +1 intil it's unique 
    $i = 1; 
    while(file_exists('uploads/image'.$i.'.jpg')) {   
     $i++; 
    } 

    $fopen = fopen('uploads/image'.$i.'.jpg', 'wb'); 
    fwrite($fopen, $decode); 
    fclose($fopen); 

} 

?> 

一点额外信息:

  • 我已经添加了画布,因为据我所知,这是 只能调整图像客户端的方式。在最后的脚本中,将 设置为隐藏。
  • 如果画布可以跳过,并立即将数据发送到saveimage.php 那么我也会解决这个问题。
  • 正如我所说我不是很有经验的JavaScript,所以如果有一个更简单的方法来实现这个目标。请告诉我!

在此先感谢!

+0

在做任何事情之前:在*设置src之前设置onload handler *。 – GameAlchemist 2015-02-11 15:33:10

+0

@GameAlchemist我已经将onload处理程序放在src之前,它似乎仍然以同样的方式运行,它的原因是什么? – Pascal 2015-02-11 16:08:09

回答

1

JavaScript以异步方式加载图像。这意味着一旦它被分配一个新的图像的.src它将开始加载图像,但将同时继续处理JavaScript后.src而图像需要时间加载。

您在for循环中使用相同的图像变量(var img)。因此,每次遍历循环时,都会在完全加载前一个图像之前覆盖之前的img。

这里是一个图像加载器完全加载所有图像,然后调用start()函数,你可以做你处理:

// image loader 

// put the paths to your images in imageURLs[] 
var imageURLs=[]; 
imageURLs.push("myImage1.png"); 
imageURLs.push("myImage2.png"); 
// etc, etc. 

// the loaded images will be placed in imgs[] 
var imgs=[]; 

var imagesOK=0; 
loadAllImages(start); 

function loadAllImages(callback){ 
    for (var i=0; i<imageURLs.length; i++) { 
     var img = new Image(); 
     imgs.push(img); 
     img.onload = function(){ 
      imagesOK++; 
      if (imagesOK>=imageURLs.length) { 
       callback(); 
      } 
     }; 
     img.onerror=function(){alert("image load failed");} 
     img.crossOrigin="anonymous"; 
     img.src = imageURLs[i]; 
    }  
} 

function start(){ 

    // the imgs[] array now holds fully loaded images 
    // the imgs[] are in the same order as imageURLs[] 

} 
0

在onload回调使用this关键字(而不是img)到当前图像,img可以/将在覆盖回调火灾之前循环。
img.height --> this.height etc
也有一个原因,你使用自定义内容类型而不是application/x-www-form-urlencoded
Url编码的表单数据更容易处理。

0

我一直在努力与有一段时间了相同的问题,但我最后 拼凑在一起的另一种解决方案,使用其他人的代码,谁已解决这个问题, ,它的工作原理。这可能不完美,我欢迎任何改进建议。 这个概念是你有两个Javascript 函数,它们是称为Resize0和Resize1的标识,并且它们互相呼叫 ,直到调整了所有照片的大小,然后调整 上一张图像的函数提交表单。这两个函数彼此之间传递 之间的参数,以便其中一个将知道何时提交表单。 其中两个参数是Number_Of_Images和当前Image_Number。 您也可以从 http://www.wantitconsulting.co.nz/ExampleResizeUpload.zip下载工作示例网页。 您需要在测试网站 的基本目录中创建一个文件夹,以便进入图像。文件夹名称是TestResizeUpload。服务器 方使用PHP。

0

我曾经有过类似的问题,但我必须首先在隐藏的“img”标签中显示所有图像,以此作为参考文章“HTML5 to display uploaded image untill next one is uploaded?”,然后触发一个带有附加功能的功能按键使用了最近创建的图像并绘制所有的人在这也同时使图像在那里上传,代码会是这样

的HTML创建的分离帆布:

<form> 
    <input type="file" id="files" name="files[]" multiple /> 
    <button type="button" id="run">Run</button> 
</form> 

<div id="preview"> 
    <output id="list"></output><br> 
    <output id="list2"></output><br> 
    <div id="status"></div> 
</div> 

剧本:

document.getElementById('files').addEventListener('change', handleFileSelect,false); 
    document.getElementById('run').addEventListener('click', read); 

    function handleFileSelect(evt) { 
     var files = evt.target.files; // FileList object 

     // Loop through the FileList and render image files as thumbnails. 
     for (var i = 0, f; f = files[i]; i++) { 

     // Only process image files. 
     if (!f.type.match('image.*')) { 
      continue; 
     } 

     var reader = new FileReader(); 

     // Closure to capture the file information. 
     reader.onload = (function(theFile) { 
      return function(e) { 
      // Render thumbnail. 
      var span = document.createElement('span'); 
      span.innerHTML = ['<img class="thumb" name="forms" src="', e.target.result, '" title="', escape(theFile.name), '"/ hidden>'].join(''); 
      document.getElementById('list').insertBefore(span, null); 
      var span = document.createElement('span'); 
      span.innerHTML = ['<canvas></canvas>'].join(''); 
      document.getElementById('list2').insertBefore(span, null);      
      }; 
     })(f); 
     // Read in the image file as a data URL. 
     reader.readAsDataURL(f); 
     } 
    } 

function read() { 
    imgs = document.getElementsByName('forms'); 
    canvas = document.getElementsByTagName("canvas"); 
    for (var i = 0; i < imgs.length; ++i) { 
     ctx[i] = canvas[i].getContext("2d"); 
     ctx[i].clearRect(0, 0, canvas[i].width, canvas[i].height); 
     preview.style.width = imgs[i].width + "px"; 
     preview.style.height = imgs[i].height + "px"; 
     canvas[i].width = imgs[i].width; 
     canvas[i].height = imgs[i].height;       
     ctx[i].drawImage(imgs[i], 0, 0, imgs[i].width, imgs[i].height); 
     // do all you need with each new canvas canvas 
    } 
} 
相关问题