当前位置: 首页 > 知识库问答 >
问题:

上传前调整图像大小-将画布转换为文件对象

邓正谊
2023-03-14

以下是我现在使用HTML5文件API上传多个图像的代码片段:

/**
 * @param {FileList} files
 */
upload: function(files){
    nfiles = files.length;

    for (var i = 0; i < nfiles; i++) {
        /** @var file File **/
        var file = files[i];

        var xhr = new XMLHttpRequest();

        xhr.open("POST", settings.post_upload, true);
        xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest");
        xhr.upload.filenumb = i;
        xhr.filenumb = i;
        xhr.upload.filename = file.name;

        var nef = new FormData();
        nef.append("folder", settings.folder);
        nef.append("file_element", settings.file_elem);
        nef.append("udata", settings.user_data);
        nef.append(settings.file_elem, file);
        xhr.send(nef);

    }
}

我想在使用canvas对象上传之前调整图像大小,但没有这方面的经验,我不确定如何使用技术更新代码,例如这里描述的技术:HTML5在上传之前预调整图像大小

canvas.toDataURL("Image/png");将返回一个编码字符串。但是我需要发布File对象

您将如何(合理地)为大多数现代浏览器编写跨浏览器功能,以便在上传之前调整文件大小,以透明方式处理jpg、png和GIF:

/** 
 * @param {File} file 
 * @param int max_width
 * @param int max_height
 * @param float compression_ratio
 * @returns File
 */
function resize(file, max_width, max_height, compression_ratio){}

共有3个答案

子车鸿运
2023-03-14

可以在上调用toBlob

穆招
2023-03-14

客户端图像调整大小

选项1。使用Pica图书馆(https://github.com/nodeca/pica)

选项2。使用以下自定义脚本(http://jsfiddle.net/cL3hapL4/2/)

var file = document.getElementById('imageUpload');
var mime = "image/jpeg";
var max_width = 100;
var max_height = 100;
var canvas = document.createElement("canvas");
var ctx = canvas.getContext("2d");
var img = new Image();

img.onload = function () {

    // Clear canvas, and resize image
    ctx.clearRect(0, 0, max_width, max_height);
    ctx.drawImage(img,
        0, 0, img.width, img.height, // size of image
        0, 0, max_width, max_height // size of canvas
    );

    // Get image from canvas as a dataURI, and convert to a blob object
    var dataURI = canvas.toDataUrl(mime);
    // Note: This function can be replaced with canvas.toBlob(),
    // once supported by browsers.
    // ---
    var image_blob = (function () {

        var binary = atob(dataURI.split(',')[1]);
        var array = [];
        for(var i = 0; i < binary.length; i++) {
            array.push(binary.charCodeAt(i));
        }
        return new Blob([new Uint8Array(array)], {type: mime});

    })();
    // ---

    // Attach blob-object (contains our image) to form object
    var form = new Form();
    form.append("image", image_blob);

    // Send AJAX request with multi-part data
    var xhr = new XMLHttpRequest();
    xhr.open('POST', '/route', true);
    xhr.send(form);

    // jQuery version
    //$.ajax({
    //    type: "POST",
    //    url: "/route",
    //    data: form,
    //    processData: false,
    //    contentType: false
    //})
    //.done(function (response) {
    //    console.log(response);
    //});

};
img.src = URL.createObjectURL(file);
萧焱
2023-03-14

试试这样:

function resize(file, max_width, max_height, compression_ratio, imageEncoding){
    var fileLoader = new FileReader(),
    canvas = document.createElement('canvas'),
    context = null,
    imageObj = new Image(),
    blob = null;            

    //create a hidden canvas object we can use to create the new resized image data
    canvas.id     = "hiddenCanvas";
    canvas.width  = max_width;
    canvas.height = max_height;
    canvas.style.visibility   = "hidden";   
    document.body.appendChild(canvas);  

    //get the context to use 
    context = canvas.getContext('2d');  

    // check for an image then
    //trigger the file loader to get the data from the image         
    if (file.type.match('image.*')) {
        fileLoader.readAsDataURL(file);
    } else {
        alert('File is not an image');
    }

    // setup the file loader onload function
    // once the file loader has the data it passes it to the 
    // image object which, once the image has loaded, 
    // triggers the images onload function
    fileLoader.onload = function() {
        var data = this.result; 
        imageObj.src = data;
    };

    fileLoader.onabort = function() {
        alert("The upload was aborted.");
    };

    fileLoader.onerror = function() {
        alert("An error occured while reading the file.");
    };  


    // set up the images onload function which clears the hidden canvas context, 
    // draws the new image then gets the blob data from it
    imageObj.onload = function() {  

        // Check for empty images
        if(this.width == 0 || this.height == 0){
            alert('Image is empty');
        } else {                

            context.clearRect(0,0,max_width,max_height);
            context.drawImage(imageObj, 0, 0, this.width, this.height, 0, 0, max_width, max_height);


            //dataURItoBlob function available here:
            // http://stackoverflow.com/questions/12168909/blob-from-dataurl
            // add ')' at the end of this function SO dont allow to update it without a 6 character edit
            blob = dataURItoBlob(canvas.toDataURL(imageEncoding));

            //pass this blob to your upload function
            upload(blob);
        }       
    };

    imageObj.onabort = function() {
        alert("Image load was aborted.");
    };

    imageObj.onerror = function() {
        alert("An error occured while loading image.");
    };

}

请注意:

使用文件加载器和加载映像意味着会有一些延迟,因此该函数是异步的,所以试图简单地返回Blob数据是行不通的。您需要等待加载发生,然后才能使用加载的数据,并启动对每个文件上传函数的调用。

此外,fileloader可能会有一些浏览器兼容性问题,但我认为这是不可能的任何其他方式客户端。

 类似资料:
  • 问题内容: 我在这个主题上进行了很多搜索,但找不到真正需要的东西。我会解释我的问题: 在我的网站上,用户可以上传图像。我需要调整此图片的大小并将其转换为JPEG, 然后再 上传。 我在Views.py中看到了使用方法的一些解决方案,但我想通过重写Models.py中的save()方法来实现。问题是,我发现所有用于在save方法中调整图像大小的解决方案都是在第一次保存(称为超级功能)后才执行的,这意

  • 请看下面的P5代码 这个小应用程序的目的是在画布上拖放图像,根据“上传”图像的宽度和高度改变其大小。 使用:成功加载图像(至少显示图像)后,我将其宽度和高度分配给变量和。接着是画布大小的变化。。。这会导致一个错误,画布的大小与上传的图像相同(在上选中),但不显示任何内容。 使用:当禁用上的画布大小更改并单击画布时,调整大小会完美地显示图像。 应用程序需要在不点击的情况下工作,在删除图像后应该自动更

  • 问题内容: 我正在尝试使用javascript和canvas元素在客户端创建缩略图,但是当我缩小图像时,它看起来很糟糕。看起来好像是在Photoshop中缩小了尺寸,将重采样设置为“最近的邻居”而不是Bicubic。我知道有可能使它看起来正确,因为该站点也可以使用画布来完成它。我已经尝试使用与[[Source]]链接中所示相同的代码,但是看起来仍然很糟糕。是否缺少我需要的设置,需要设置的设置? 编

  • 我正在尝试用画布调整一些图像的大小,但我不知道如何平滑它们。在photoshop,浏览器等。有几个算法他们使用(例如双三次,双线性),但我不知道这些是不是内置到画布。 这是我的小提琴:http://jsfidle.net/ewupt/ 第一个是正常的调整大小的图像标签,第二个是画布。注意画布是如何不是平滑的。我怎样才能实现‘平滑’呢?

  • 我正在尝试将画布作为图像发送到我的服务器,并希望以base64发送。Fabricjs提供了使用或将画布转换为图像,但我的日志上的输出似乎是一个Klass对象(第一次看到),将该对象发送到服务器并记录服务器上接收到的内容后,我会得到一个空对象或路径,即: Klass对象控制台图像: 我的代码: 我尝试了这个,仍然是同一个klass对象,需要将画布转换为base64图像(首选png),然后发送到服务器

  • 问题内容: 我正在尝试将调整大小的图像上传到S3: 但我得到一个错误: 问题答案: 您需要先将输出图像转换为一组字节,然后才能上载到s3。您可以将图像写入文件然后上传文件,也可以使用cStringIO对象来避免写入磁盘,就像我在这里所做的那样: