通过javascript循环上传多个画布图像 [英] Upload multiple canvas images through javascript loop

查看:158
本文介绍了通过javascript循环上传多个画布图像的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想要制作一个上传脚本,在 saveimage.php 处理它们之前调整多个图片客户端的大小。原因是因为它们将上传到可能有非常缓慢的互联网的外部位置。

I am trying to make an upload script which resizes multiple images client side before the saveimage.php handles them. The reason for this is because they will be uploaded at an outside location where there might be very slow internet.

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

I have been able to find pieces of code around here which helped me put it together. I am only a beginner so it's probably very messy!

它目前所做的是检查每当文件被输入'file_input'字段。然后,它会查看文件的数量,并循环通过它们,直到每个文件都放在画布上,并在其中的时候上传。

What it currently does is it checks whenever files are being input in the 'file_input' field. Then it looks at the amount of files and loop through them until every file has been placed in the canvas and upload while it's in there.

is:,当我不为每个文件添加警报时,循环过快,并且只处理10个图像中的1或2个。

However, the problem is: when I don't add an alert for each file, the loop goes too fast and only processes 1 or 2 out of 10 images for example. Because the upload script will go faster than the canvas can be updated with a new image.

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

This is my current page, simplified to the core:

<!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 $ b $

  • 正如我所说,我对javascript不是很有经验,所以如果有一个
    更简单的方式来实现这个目标。请让我知道!

  • I have added canvas, because as far as I can understand that's the only way to resize images client side. In the final script it will be set to hidden.
  • If the canvas could be skipped and the data sent to saveimage.php immediately then that would solve the problem too I think.
  • As I said I am not very experienced with javascript, so if there is a much simpler way to achieve this goal. Please let me know!

提前感谢!

推荐答案

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

JavaScript loads image asynchronously. That means once it is assigned a new image's .src it will begin loading the image but will simultaneously continue processing the javascript after the .src while the image takes time to load.

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

You're using the same image variable (var img) inside your for loop. Therefore, each time through the loop you are overwriting the previous img before the previous image has been fully loaded.

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

Here's an image loader that fully loads all image and then calls the start() function where you can do you processing:

// 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[]

}

这篇关于通过javascript循环上传多个画布图像的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆