javascript 在发送到 BASE64 之前调整图像大小(不使用 img 元素)

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/30902360/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-28 12:53:39  来源:igfitidea点击:

Resize image before sending to BASE64 (without using img element)

javascriptphpbase64

提问by DTH

EDIT: I dont want to show the image on the client, the purpose is to shrink the image and scale...

编辑:我不想在客户端显示图像,目的是缩小图像和缩放...

Im having some trouble resizing an image which is selected using a file input in a form before it must be uploaded to the server.

我在调整使用表单中的文件输入选择的图像大小时遇到​​了一些麻烦,然后才能将其上传到服务器。

I have the following code monitoring my file input:

我有以下代码监控我的文件输入:

// monitor file inputs and trigger event
$(document).on('change', '.btn-file :file', function() {

    var F = this.files;
    if(!isImage( F[0] ))
    {
        alert("Not an image file"); 
    }

    var fileurl = resizeImage(F[0]);
    console.log(fileurl);               

    var input = $(this),label = input.val().replace(/\/g, '/').replace(/.*\//, '');
    input.trigger('fileselect', [label]);
});

This function will call resizeImage which looks like this:

此函数将调用 resizeImage,如下所示:

function resizeImage(file)
{
    var MAX_WIDTH = 800;
    var MAX_HEIGHT = 600;

    var img = document.createElement("img");
    img.src = window.URL.createObjectURL(file);
    console.log(img.width);         

    var canvas = document.createElement('canvas');

    var width = img.width;
    var height = img.height;

    if (width > height) {
      if (width > MAX_WIDTH) {
        height *= MAX_WIDTH / width;
        width = MAX_WIDTH;
      }
    } else {
      if (height > MAX_HEIGHT) {
        width *= MAX_HEIGHT / height;
        height = MAX_HEIGHT;
      }
    }
    canvas.width = width;
    canvas.height = height;

    var ctx = canvas.getContext("2d");

    ctx.drawImage(img, 0, 0, width, height);
    console.log(ctx);       
    var dataurl = canvas.toDataURL("image/png");
    return dataurl;
}

Problem is, that my console log tells me that the return value from my resize function is "data:,". I then started to console.log my way out of it, to narrow down where the problem is hiding. In my resizeImage function i logged the WIDTH of my img element which gave me a width of 0 which should not be correct ? .. I can't figure out what i have done wrong..

问题是,我的控制台日志告诉我调整大小函数的返回值是“data:,”。然后我开始使用 console.log 解决问题,以缩小问题所在的范围。在我的 resizeImage 函数中,我记录了我的 img 元素的宽度,这给了我 0 的宽度,这不应该是正确的?.. 我不知道我做错了什么..

回答by markE

If your target browser supports the fileinput attribute, then you can use URL.createObjectURLto create an image source that you can manipulate with the canvas element.

如果您的目标浏览器支持fileinput 属性,那么您可以使用它URL.createObjectURL来创建可以使用canvas 元素操作的图像源。

Given a maximum desired size of maxW x maxHyou can calculate the scaling factor that will resize the image while maintaining the original aspect ratio like this:

给定最大所需尺寸,maxW x maxH您可以计算缩放因子,该比例因子将在保持原始纵横比的同时调整图像大小,如下所示:

var scale=Math.min((maxW/img.width),(maxH/img.height));

Here's example code and a Demo.

这是示例代码和演示。

Note that the demo does draw the image to the canvas, but you could just as easily substitute an in-memory canvas with document.createElement('canvas').

请注意,该演示确实将图像绘制到画布上,但您可以轻松地将内存画布替换为document.createElement('canvas').

var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
var cw=canvas.width;
var ch=canvas.height;

// limit the image to 150x100 maximum size
var maxW=150;
var maxH=100;

var input = document.getElementById('input');
input.addEventListener('change', handleFiles);

function handleFiles(e) {
  var img = new Image;
  img.onload = function() {
    var iw=img.width;
    var ih=img.height;
    var scale=Math.min((maxW/iw),(maxH/ih));
    var iwScaled=iw*scale;
    var ihScaled=ih*scale;
    canvas.width=iwScaled;
    canvas.height=ihScaled;
    ctx.drawImage(img,0,0,iwScaled,ihScaled);
    alert(canvas.toDataURL());
  }
  img.src = URL.createObjectURL(e.target.files[0]);
}
body{ background-color: ivory; }
#canvas{border:1px solid red;}
<input type="file" id="input"/>
<br>
<canvas id="canvas" width=300 height=300></canvas>