使用JavaScript将画布图像附加到输入数组

使用JavaScript将画布图像附加到输入数组

问题描述:

我正在努力工作我的代码,但我没有成功。
基本上我想要的是将调整大小算法应用于用户选择的多个图像,使它们在HTML5 Canvas中,然后将每个字符串(DataURL)插入到输入数组中以通过POST方法发送。

I am trying to get work my code, but I have not been successful. Basically what I want is to apply a resize algorithm to multiple images selected by the user, making them in HTML5 Canvas and then inserting each string (DataURL) in the input array to be sent by via POST method.

我的代码(CLIENT)index.html:

My code (CLIENT) index.html:

<html>
    <head>
    </head>
    <body>
        <input type="file" id="pictures" multiple><br>
        <form id="frm" action="save.php" method="POST">
            <input type="hidden" name="sizedpics[]" id="sizedpics">
            <button type="button" onclick="resize()">submit!</button>
        </form>
        <canvas style="display:none;" id="canvas" width="800"></canvas><br>
        <script>
            var pics=[];
            function resize()
            {
                var numpictures=pictures.files.length;
                var compresion=0.5;
                var dataurl;
                for (i=0;i<numpictures;i++)
                {
                    var canvas = document.getElementById("canvas");
                    var ctx = canvas.getContext("2d");

                    img = new Image();
                    img.onload = function () 
                    {
                        canvas.height = canvas.width * (img.height / img.width);

                        /// step 1
                        var oc = document.createElement('canvas'), octx = oc.getContext('2d');
                        oc.width = img.width * compresion;
                        oc.height = img.height * compresion;
                        octx.drawImage(img, 0, 0, oc.width, oc.height);

                        /// step 2
                        octx.drawImage(oc, 0, 0, oc.width * compresion, oc.height * compresion);

                        ctx.drawImage(oc, 0, 0, oc.width * compresion, oc.height * compresion, 0, 0, canvas.width, canvas.height);

                        // Step 3
                        dataurl = canvas.toDataURL("image/jpeg");
                        pics.push(dataurl);
                    }
                    img.src = window.URL.createObjectURL(pictures.files[i]);
                }
                document.getElementById("sizedpics").value=pics;
                document.forms["frm"].submit();
            }
        </script>
    </body>
</html>

我的代码(SERVER)save.php

My code (SERVER) save.php

<?php
    print_r(count($_POST['sizedpics']));exit();
?>

我认为有一个与javascript同步的问题,但我不知道如何解决它,我需要使用单个输入sizespics将所有图像(base64编码的DataURL字符串)发送到我的服务器。

I think there is a problem of sync with the javascript, but I don't know how to solve it, I need to send all images (base64 encoded DataURL strings) to my server using a single input "sizedpics".

有些人知道哪里出错了?
感谢阅读,请原谅我写英文的可怕方式: - )

Some of you know where the error? Thanks for reading, and please excuse my horrible way to write English :-)

编辑: 更新了答案和更新代码中的评论。

Updated comments in answer and updated code.

有很多事情阻止了您的代码工作,唉我已经累了,忘记记笔记了我去的时候已经忘记了具体细节。 :(

There were a number of things that stopped your code from working, alas I'm tired and forgot to make note of them as I went and have forgotten the specifics. :(

您可能希望查看以下代码。

You may wish to review the following code.

它使用fileReader加载图像方法 .readAsDataURL 。然后在完成时触发用户提供的回调。然后这个回调方法尝试将dataURL加载为图像。当(如果!)这成功时,将图像绘制到缩放的画布上,然后检索该画布的dataURL。将此dataURL添加到数组中,将缩放图像的数量与所选图像的数量进行比较。当两个数字匹配时,JSON对数组进行编码并且在提交表单之前将其填充到隐藏的输入中。

It loads the images using a fileReader and the method .readAsDataURL. This then fires a user-supplied callback on completion. This callback method then attempts to load the dataURL as an image. When (if!) this succeeds, the image is drawn onto a scaled canvas and then the dataURL of that canvas is retrieved. This dataURL is added to an array and the number of scaled images is compared to the number of selected images. When the two numbers match, it JSON encodes the array and stuffs it into the hidden input, before submitting the form.

在php端,我们获取提交的数据并对其进行JSON解码。然后我们显示计数在将每个元素作为图像的src输出之前,此数组中的图像数量确认成功上传。

On the php side, we get the submitted data and JSON decode it. We then display a count of the number of images in this array, before ouputing each element as the src of an image,to confirm successful upload.

我添加了代码以确保选择的文件是在进一步处理之前的图像。您可以选择混合图像文件列表,只处理图像。 当所选文件是图像但尝试将其加载到img元素中失败时,我不处理这种情况。

I've added code that will ensure the chosed file is an image before processing it any further. You can select a mixed list of files and only the images will be processed. I don't handle the case when the chosen file is an image yet trying to load it into an img element fails.

resizeAndUpload.html

<html>
<head>
<script>
function newEl(tagName){return document.createElement(tagName);}

var nFiles, nSized, nPics, mPicArray;

function myResizeAll()
{
    nFiles = pictures.files.length;
    nSized = 0;
    nPics = 0;
    mPicArray = [];

    // work out how many of the chosen files are images
    for (var i=0; i<nFiles; i++)
    {
        if (pictures.files[i].type.indexOf("image") != -1)
            nPics++;
    }

    // now try to load the ones that are images
    for (var i=0; i<nFiles; i++)
    {
        if (pictures.files[i].type.indexOf("image") != -1)
            loadFileObject( pictures.files[i], onFileDataLoaded );
    }
}

// callback gets data via the .target.result field of the param passed to it.
function loadFileObject(fileObj, loadedCallback)
{
    var reader = new FileReader();
    reader.onload = loadedCallback;
    reader.readAsDataURL( fileObj );
}

function onFileDataLoaded(e)
{
    var tmpImg = newEl('img');
    tmpImg.addEventListener('load', onImgElemLoaded, false);
    tmpImg.src = e.target.result;
}

function onImgElemLoaded(evt)
{
    // create a canvas
    var can = newEl('canvas');
    var ctx = can.getContext('2d');

    // scale it
    var scale = 0.5;
    can.width = this.width * scale;
    can.height = this.height * scale;

    // draw scaled image
    ctx.drawImage(this, 0, 0, can.width, can.height);

    // get dataURL
    var resizedImgDataURL = can.toDataURL();
    mPicArray.push( resizedImgDataURL );

    nSized++;

    // when all image files have been loaded, then loaded as image elements and finally resized on a canvas,
    // submit the data.
    if (nSized == nPics)
    {
        document.getElementById("sizedpics").value= JSON.stringify(mPicArray);
        document.forms["frm"].submit();
    }
}
</script>
</head>
<body>
    <input type="file" id="pictures" multiple><br>
    <form id="frm" action="save.php" method="POST">
        <input type="hidden" name='sizedpics' id="sizedpics"/>
        <button type="button" onclick="myResizeAll()">submit!</button>
    </form>
    <canvas id="canvas" style='display:none' width="800"></canvas><br>
</body>
</html>

save.php

<?php
    $imgArray = json_decode( $_POST['sizedpics'] );

    print_r( count($imgArray) );

    $numPics = count($imgArray);
    for ($i=0; $i<$numPics; $i++)
    {
        printf("<img src='%s'/>\n", $imgArray[$i]);
    }
?>

输出

您的英语是很好。它比许多母语人士的要好。 ;)

Your English is just fine.It's better than that of many native-speakers. ;)