通过动态创建html文件元素来上载克隆的画布照片,默认值为画布图像

Gra*_*kel 5 html javascript php jquery canvas

我正在尝试将图像过滤器应用于图像,并在每次单击过滤器时重新创建文件元素.因此,这将是伪代码.它仍然说文件字段为空,我不知道为什么.

我正在尝试将文件传递给处理上传的PHP脚本,但我不知道如何在脚本中执行此操作,因为我的javascript技能不够好..

HTML

<div id="uploadPic" class="modal fade" >
  <form method="post" id="fileinfo" name="fileinfo" onsubmit="return submitForm();">
    <div class="modal-dialog">
        <div class="modal-content">
            <div class="modal-header" style="background:#f3f3f3;">
                <button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
                <h4 class="modal-title" style="color:black;">Choose picture to upload as profile pic.</h4>          
            </div>
            <div class="modal-body">
              <div id="filterContainer" style='width:400px;'>
                <ul id="filters" style='width:400px;'>
                  <li> <a href="#" id="normal">Normal</a> </li>
                  <li> <a href="#" id="vintage">Vintage</a> </li>
                  <li> <a href="#" id="lomo">Lomo</a> </li>
                  <li> <a href="#" id="clarity">Clarity</a> </li>
                  <li> <a href="#" id="sinCity">Sin City</a> </li>
                  <li> <a href="#" id="sunrise">Sunrise</a> </li> 
                  <li> <a href="#" id="crossProcess">Cross Process</a> </li>
                  <li> <a href="#" id="orangePeel">Orange Peel</a> </li>
                  <li> <a href="#" id="love">Love</a> </li>
                  <li> <a href="#" id="grungy">Grungy</a> </li>
                  <li> <a href="#" id="jarques">Jarques</a> </li>
                  <li> <a href="#" id="pinhole">Pinhole</a> </li>
                  <li> <a href="#" id="oldBoot">Old Boot</a> </li>
                  <li> <a href="#" id="glowingSun">Glowing Sun</a> </li>
                  <li> <a href="#" id="hazyDays">Hazy Days</a> </li>
                  <li> <a href="#" id="herMajesty">Her Majesty</a> </li>
                  <li> <a href="#" id="nostalgia">Nostalgia</a> </li>
                  <li> <a href="#" id="hemingway">Hemingway</a> </li>
                  <li> <a href="#" id="concentrate">Concentrate</a> </li>
                </ul>
              </div>
              <div id='output_file'></div>
              <div id="output"></div>
              <div id="photo">
                <a href="#" class="downloadImage" target="_blank" download="photo.png">Download Image</a>-
              </div>
            </div>
            <div class="modal-footer">
                <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
                <input type="submit" value="Upload" class="btn btn-info" data-dismiss="modal" onClick="return submitForm();"/> 
            </div>
        </div>
    </div>
  </form>
</div> 
Run Code Online (Sandbox Code Playgroud)

JavaScript的:

$(function() {
    /*
        In this code, we are going to do the following:
        1. Accept an image on drag and drop
        2. Create a new canvas element (original), with a max size
           of 500x500px (customizable) and keep it in memory
        3. Listen for clicks on the filters. When one is selected:
                3.1 Create a clone of the original canvas
                3.2 Remove any canvas elements currently on the page
                3.3 Append the clone to the #photo div
                3.4 If the selected filter is different from the "Normal"
                    one, call the Caman library. Otherwise do nothing.
                3.5 Mark the selected filter with the "active" class
        4. Trigger the "Normal" filter
    */
    var maxWidth = 500,
        maxHeight = 500,
        photo = $('#photo'),
        originalCanvas = null,
        filters = $('#filters li a'),
        filterContainer = $('#filterContainer');
    // Use the fileReader plugin to listen for
    // file drag and drop on the photo div:
    photo.fileReaderJS({
        on:{
            load: function(e, file){
                // An image has been dropped.
                var img = $('<img>').appendTo(photo),
                    imgWidth, newWidth,
                    imgHeight, newHeight,
                    ratio;
                // Remove canvas elements left on the page
                // from previous image drag/drops.
                photo.find('canvas').remove();
                filters.removeClass('active');

                // When the image is loaded successfully,
                // we can find out its width/height:
                img.load(function() {
                    imgWidth  = this.width;
                    imgHeight = this.height;
                    // Calculate the new image dimensions, so they fit
                    // inside the maxWidth x maxHeight bounding box
                    if (imgWidth >= maxWidth || imgHeight >= maxHeight) {
                        // The image is too large,
                        // resize it to fit a 500x500 square!
                        if (imgWidth > imgHeight) {
                            // Wide
                            ratio = imgWidth / maxWidth;
                            newWidth = maxWidth;
                            newHeight = imgHeight / ratio;
                        } else {
                            // Tall or square
                            ratio = imgHeight / maxHeight;
                            newHeight = maxHeight;
                            newWidth = imgWidth / ratio;
                        }
                    } else {
                        newHeight = imgHeight;
                        newWidth = imgWidth;
                    }
                    // Create the original canvas.
                    originalCanvas = $('<canvas>');
                    var originalContext = originalCanvas[0].getContext('2d');
                    // Set the attributes for centering the canvas
                    originalCanvas.attr({
                        width: newWidth,
                        height: newHeight
                    }).css({
                        marginTop: -newHeight/2,
                        marginLeft: -newWidth/2
                    });
                    // Draw the dropped image to the canvas
                    // with the new dimensions
                    originalContext.drawImage(this, 0, 0, newWidth, newHeight);
                    // We don't need this any more
                    img.remove();
                    filterContainer.fadeIn();
                    // Trigger the default "normal" filter
                    filters.first().click();
                });
                // Set the src of the img, which will
                // trigger the load event when done:
                img.attr('src', e.target.result);
            },
            beforestart: function(file){
                // Accept only images.
                // Returning false will reject the file.
                return /^image/.test(file.type);
            }
        }
    });
    // Listen for clicks on the filters
    filters.click(function(e){
        e.preventDefault();
        var f = $(this);
        if(f.is('.active')){

            // Apply filters only once
            return false;
        }
        filters.removeClass('active');
        f.addClass('active');
        // Clone the canvas
        var clone = originalCanvas.clone();
        // Clone the image stored in the canvas as well
        clone[0].getContext('2d').drawImage(originalCanvas[0],0,0);
        // Add the clone to the page and trigger
        // the Caman library on it
        photo.find('canvas').remove().end().append(clone);
        var effect = $.trim(f[0].id);
        Caman(clone[0], function () {
            // If such an effect exists, use it:
            if( effect in this){
                this[effect]();
                this.render();
        var url = clone[0].toDataURL("image/png;base64;");
        $("#output_file").html('<input type="file" name="file" value="'+url+'" required / >');
                // Show the download button
                showDownload(clone[0]);
            }
            else{
                hideDownload();
            }
        });
    });
    // Use the mousewheel plugin to scroll
    // scroll the div more intuitively
    filterContainer.find('ul').on('mousewheel',function(e, delta){
        this.scrollLeft -= (delta * 50);
        e.preventDefault();
    });
    var downloadImage = $('a.downloadImage');
    function showDownload(canvas){
        downloadImage.off('click').click(function(){
            // When the download link is clicked, get the
            // DataURL of the image and set it as href:
            var url = canvas.toDataURL("image/png;base64;");
            downloadImage.attr('href', url);
        }).fadeIn();
    }
    function hideDownload(){
        downloadImage.fadeOut();
    }
});
Run Code Online (Sandbox Code Playgroud)

PHP:

<?php
$username = $_POST["username"];
$timestamp = $_POST["timestamp"];
$allowedExts = array("gif", "jpeg", "jpg", "png");
$temp = explode(".", $_FILES["file"]["name"]);
$extension = end($temp);
if ((($_FILES["file"]["type"] == "image/gif")
|| ($_FILES["file"]["type"] == "image/jpeg")
|| ($_FILES["file"]["type"] == "image/jpg")
|| ($_FILES["file"]["type"] == "image/pjpeg")
|| ($_FILES["file"]["type"] == "image/x-png")
|| ($_FILES["file"]["type"] == "image/png"))
&& ($_FILES["file"]["size"] < 200000)
&& in_array($extension, $allowedExts)) {
    if ($_FILES["file"]["error"] > 0) {
        #echo "Return Code: " . $_FILES["file"]["error"] . "<br>";
    } else {
        $filename = $username.$timestamp.$_FILES["file"]["name"];
        #echo "Upload: " . $_FILES["file"]["name"] . "<br>";
        #echo "Type: " . $_FILES["file"]["type"] . "<br>";
        #echo "Size: " . ($_FILES["file"]["size"] / 1024) . " kB<br>";
        #echo "Temp file: " . $_FILES["file"]["tmp_name"] . "<br>";
        if (file_exists("images/profile_images/" . $filename)) {
            echo $filename . " already exists. ";
        } else {
            move_uploaded_file($_FILES["file"]["tmp_name"],
            "images/profile_images/" . $filename);
            echo "images/profile_images/" . $filename;
        }
    }
} else {
    echo "Invalid file";
}
?>
Run Code Online (Sandbox Code Playgroud)

根据Rayon的评论,我正在做以下事情:

每次单击过滤器时,这会将base64附加到主页面上的表单数据.因此,当有人点击上传时,它会将该数据发送到pho脚本.

var fd = new FormData(document.getElementById("fileinfo"));
fd.append("file_upload", clone[0].toDataURL("image/png;base64;"));
Run Code Online (Sandbox Code Playgroud)

这是我当前用于处理AJAX请求的JavaScript:

function submitForm() {
  if (get_user != logged_username) {} else {
    var d = new Date();
    var time = d.getTime();
    //console.log(document.getElementById("file"));
    var fd = new FormData(document.getElementById("fileinfo"));
    //console.log(fd);
    fd.append("username", logged_username);
    fd.append("timestamp", time);
    $.ajax({
      url: "upload_photo.php",
      type: "POST",
      data: fd,
      enctype: 'multipart/form-data',
      processData: false, // tell jQuery not to process the data
      contentType: false // tell jQuery not to set contentType
    }).done(function(data) {
      if (data.indexOf("Invalid") >= 0) {
        alert('invalid file type, must be jpeg, jpg, or png.');
      } else {
        var post = {
          "pic_location": data,
          "time": time,
          "username": logged_username
        };
        console.log(data);
        var json_data = post;
        Cynergi.insert('http://thhd.com:3000/profile_pictures', json_data);
        //this is where we save the photos location to the db for retrieveal.
      }
    });
    return false;
  }
}
Run Code Online (Sandbox Code Playgroud)

然后是php:

<?php

    // requires php5
    define('UPLOAD_DIR', 'images/profile_images/');
    $img = $_POST['file_info'];
    $img = str_replace('data:image/png;base64,', '', $img);
    $img = str_replace(' ', '+', $img);
    $data = base64_decode($img);
    $file = UPLOAD_DIR . uniqid() . '.png';
    $success = file_put_contents($file, $data);
    echo $file;
    print $success ? $file : 'Unable to save the file.';

?>
Run Code Online (Sandbox Code Playgroud)

记录输出显示:

数据:图像/ PNG; BASE64,iVBORw0KGgoAAAANSUhEUgAAAfQAAAH0CAYAAADL1t + KAAAgAElEQ ... P3PeerM0GN4J7vE4xyTdlT34hvfOMbuiYnL6xlqkUu4v8BZ033tp7lXCwAAAAASUVORK5CYII =

php返回无法保存文件,并保存一个0字节的文件.

这有效,但它放置一个0字节的文件,我不知道为什么.

Ray*_*yon 1

无需输入文件。您可以在画布上绘制图像,并在用户的每个操作后重新绘制它,如果您愿意存储该图像,那么您需要使用 php 脚本将图像的 Base64 数据操作为图像。