Append canvas images to input array with JavaScript

僤鯓⒐⒋嵵緔 提交于 2019-12-12 06:04:41

问题


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.

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>

My code (SERVER) save.php

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

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 :-)


回答1:


EDIT: 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.

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.

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.

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]);
    }
?>

Output

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



来源:https://stackoverflow.com/questions/28773631/append-canvas-images-to-input-array-with-javascript

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!