我无法使用画布从blob URL裁剪图像

时间:2014-07-02 17:26:25

标签: javascript file canvas file-upload

我正在构建一个用户可以上传照片的应用程序,然后调整该照片的大小并将其指定为不同图像标记的src。我无法让它发挥作用,而我因为blob网址而猜测它。任何帮助都会很棒。

这里是直播example

HTML:

<!DOCTYPE html>
<html>
    <head>
        <meta name='viewport' content='width=device-width,initial-scale=1,minimum-scale=1'>

        <title>Test</title>

        <!-- styles -->
        <link rel="stylesheet" href="http://code.jquery.com/ui/1.11.0/themes/smoothness/jquery-ui.css">

        <!-- scripts -->
        <script src="http://code.jquery.com/jquery-1.11.1.min.js"></script>
        <script src='js/script.js'></script>
    </head>

    <body>
        <label for='existing'>Choose existing photo:</label>
            <input id="existing" type="file" accept="image/*">

        <div id="photo_container">
            <img id="photo" src="" width="640">
            <img id="new">
        </div>

        <canvas width="200"></canvas>
    </body>
</html>

JS:

$(document).ready(
    function()
    {   
        var showPicture = document.querySelector("#photo");
        var takePicture = document.querySelector("#existing");

        takePicture.onchange = function( event )
        {
            var files = event.target.files, file;

            if (files && files.length > 0) 
            {
                file = files[0];
            }

            try 
            {
                var URL = window.URL || window.webkitURL;
                var imgURL = URL.createObjectURL(file);

                showPicture.src = imgURL;

                var canvas = document.querySelector('canvas');
                var newImage = document.querySelector('img#new');
                var ctx = canvas.getContext('2d');
                var photoHeight = showPicture.height;
                var photoWidth = showPicture.width;

                canvas.width = photoWidth;
                canvas.height = photoHeight;

                ctx.drawImage(showPicture, photoWidth/2, photoHeight/2);

                newImage.src = canvas.toDataURL('image/jpeg');
            }

            catch(e) 
            {
                try 
                {
                    var fileReader = new FileReader();

                    fileReader.onload = function (event) 
                    {

                        showPicture.src = event.target.result;

                    };

                    fileReader.readAsDataURL(file);
                }

                catch(e) 
                {

                    var error = document.querySelector("#error");

                    if (error) 
                    {
                        error.innerHTML = "Neither createObjectURL or FileReader are supported";
                    }
                }
            }
        };
    }
);

1 个答案:

答案 0 :(得分:2)

以下是加载用户使用FileReader.

选择的符合CORS的图像的一种方法

BTW,请记住,如果用户加载具有透明度的图像(例如.png),则生成的.jpg将为黑色,而传入的图像是透明的。

示例代码和演示:http://jsfiddle.net/m1erickson/9e9LD/

我的示例使用了拖放功能,但如果您愿意,可以替换文件浏览。

<!doctype html>
<html>
<head>
<link rel="stylesheet" type="text/css" media="all" href="css/reset.css" /> <!-- reset css -->
<script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>
<style>
    body{ background-color: ivory; }
    canvas{border:1px solid red;}
    #dropzone{border:1px solid blue; width:300px;height:300px;}
</style>
<script>
$(function(){

    // dropzone event handlers
    var dropzone;
    dropzone = document.getElementById("dropzone");
    dropzone.addEventListener("dragenter", dragenter, false);
    dropzone.addEventListener("dragover", dragover, false);
    dropzone.addEventListener("drop", drop, false);

    //
    function dragenter(e) {
      e.stopPropagation();
      e.preventDefault();
    }
    //

    function dragover(e) {
      e.stopPropagation();
      e.preventDefault();
    }

    //
    function drop(e) {
      e.stopPropagation();
      e.preventDefault();

      var dt = e.dataTransfer;
      var files = dt.files;

      handleFiles(files);
    }

    //
    function handleFiles(files) {

        for (var i = 0; i < files.length; i++) {

          // get the next file that the user selected
          var file = files[i];
          var imageType = /image.*/;

          // don't try to process non-images
          if (!file.type.match(imageType)) {
            continue;
          }

          // a seed img element for the FileReader
          var img = document.createElement("img");
          img.classList.add("obj");
          img.file = file;

          // get an image file from the user
          // this uses drag/drop, but you could substitute file-browsing
          var reader=new FileReader();
          reader.onload=(function(aImg){
              return function(e) {
                  aImg.onload=function(){

                      // draw the aImg onto the canvas
                      var canvas=document.createElement("canvas");
                      var ctx=canvas.getContext("2d");
                      canvas.width=aImg.width;
                      canvas.height=aImg.height;

                      // I don't know your design requirements about clipping
                      // but you can use the extended form of drawImage to crop
                      // the image as your design requires.

                      ctx.drawImage(aImg,0,0);

                      // make the jpeg image
                      var newImg=new Image();
                      newImg.onload=function(){
                          newImg.id="newest";
                          document.body.appendChild(newImg);
                      }
                      newImg.src=canvas.toDataURL('image/jpeg');
                  }
                  // e.target.result is a dataURL for the image
                  aImg.src = e.target.result;
              }; 
          })(img);
          reader.readAsDataURL(file);

        } // end for

    } // end handleFiles

}); // end $(function(){});
</script>
</head>
<body>
    <h4>Drag an image from desktop to blue dropzone.</h4>
    <div id="dropzone"></div>
    <div id="preview"></div>
</body>
</html>