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

使用JavaScript将画布图像附加到输入数组,javascript,html,canvas,asynchronous,html-input,Javascript,Html,Canvas,Asynchronous,Html Input,我正试图让我的代码工作,但我没有成功。 基本上,我想要的是对用户选择的多个图像应用一个调整大小算法,将它们放在HTML5画布中,然后将每个字符串(DataURL)插入输入数组中,通过POST方法发送 我的代码(客户端)index.html: <html> <head> </head> <body> <input type="file" id="pictures" multiple><br&g

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

我的代码(客户端)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>


提交
var-pics=[]; 函数resize() { var numpictures=pictures.files.length; var压缩=0.5; var-dataurl;
对于(i=0;i编辑:更新答案中的注释和更新代码

有许多事情使你的代码无法工作,唉,我累了,在去的时候忘了记下它们,忘记了细节(

您可能希望查看以下代码

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

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

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

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>

函数newEl(标记名){return document.createElement(标记名);}
变量文件、nSized、NPIC、mPicArray;
函数myresizeral()
{
nFiles=pictures.files.length;
nSized=0;
nPics=0;
mPicArray=[];
//计算出所选文件中有多少是图像

对于(var i=0;iNice,谢谢你,我有一个离题的问题要问你:我在你的例子中看到的电子游戏机是什么?不客气。这是任天堂进入游戏世界的原始作品之一。事实上,据我所知,这是第一部。它被称为Ball,于1980年发布,是“游戏与观看”系列的一部分那是从1980年到1991年。马里奥第一次出现在一个叫《金刚驴子》的橙色2屏游戏中。哇,我们小时候就杀了这个游戏。:微笑:你可以在这里开始阅读关于他们的所有内容:有趣!谢谢。抱歉,但我在重新调整图像大小方面遇到了问题。我添加了以下代码:if(dataUrl.indexOf(“data:image”)==-1{nPics--}var dataUrl=e.target.result;但不知道将代码放在何处我的代码可以减少图像:\n因为它们是dataUrl,我对javascript:cNo问题比较陌生。我已经更新了代码以包含此步骤。就像我们必须使用回调来知道文件数据何时加载一样,我们必须使用另一个回调来知道此文件数据何时加载已加载到img元素中。最后,请不要以先前的方式编辑帖子。您(a)更改了帖子的意图,(b)引入了新错误,并错过了结束正文/html标记,最后(c)试图回复我。这样做会使答案无效,实际上会出错。并非每个人都会在编辑和修复时注意到这样的错误。缩进更改可以:)
<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>
<?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]);
    }
?>