【问题标题】:Show resized Base64 output of an image显示图像的调整大小的 Base64 输出
【发布时间】:2016-10-31 13:55:22
【问题描述】:

我正在努力完成并理解我编写的以下“怪物代码”。基本上,这个函数应该在文件输入对话框 (HTML) 被触发时触发。但是代码运行良好只有几行。它加载图像,然后在第一个 alert() 中向我显示原始图像的 base64,但随后在代码中,当实际图像应该加载到画布中时,它返回(在另一个 alert() ) 高度0,可能意味着图像没有正确加载或根本没有加载。

HTML 输入表单(简化)如下所示:

<input type='File' accept='image/*' onChange='changeBtn(this);' />

还有下面的函数:

function changeBtn(elem) {
    selfile = document.getElementById(elem.id);

    if ('files' in selfile) {
        var file = selfile.files[0];
        if ('name' in file) {
            str1 = file.name;
        }
        if ('size' in file) {
            str1 += ' (' + ((file.size / 1024) / 1024).toFixed(2) + 'MB)';
        }
        document.getElementById("label_" + elem.id).innerHTML = str1;

        var FR= new FileReader();
        var img = document.createElement("img");
        FR.onload = function(e) {
            img.src = e.target.result;
            alert(e.target.result); // Returns B64 of the original image
        };

        FR.readAsDataURL(file);

        var canvas = document.createElement('canvas');
        var ctx = canvas.getContext("2d");
        ctx.drawImage(img, 0, 0);

        var MAX_WIDTH = 800;
        var MAX_HEIGHT = 600;
        var width = img.width;
        var height = img.height;
        alert(height); // Returns 0

        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);

        var dataurl = canvas.toDataURL("image/png");
        alert(dataurl); // Returns only "data; " and nothing more

    }
} 

提前感谢您的帮助。看起来很简单,但我不明白。我至少重写了 3 次代码,但总是得到相同的结果。

【问题讨论】:

  • 检查img 的范围。您定义它,然后在它仍然为空的onload 之外使用它。
  • @J.Titus 但是当我将所有内容都放入 onload 时,onload 似乎永远不会完成..(它没有显示任何警报)
  • 这不是范围界定问题。您调用FR.readAsDataURL(file); 将通过向onload 发出回调来完成。然而FR.readAsDataURL(file); 立即返回并继续执行您的代码,无论img 变量是否已设置。如果您将 FR.readAsDataURL(file); 后面的所有代码移到 onload 中,它应该可以工作。这可能不是最好的方法,但它是一个开始。
  • @markbernard “这不是范围界定问题……如果您将 FR.readAsDataURL(file); 后面的所有代码移动到 onload 中,它应该可以工作。” - 当它应该在内部时,在回调之外运行的代码不是范围问题吗? :) 当 OP 将img 用于img.widthimg.height 时,它仍然作为新的&lt;img&gt; 运行,因此宽度和高度为0。在回调内部,这会有所不同。
  • @Fusselldieb 定义“一切”。正如马克伯纳德所说,readAsDataURL() 应该留在回调之外。之后的所有东西都应该进去。

标签: javascript html image canvas filereader


【解决方案1】:

想通了! 我在将图像加载到其中之前调用了FR.readAsDataURL(file);,导致它加载了一个未定义的文件。

如果我们查看以下失败的代码:

var FR= new FileReader();
var img = document.createElement("img");
FR.onload = function(e) {
    img.src = e.target.result;
    alert(e.target.result); // Returns B64 of the original image
};
FR.readAsDataURL(file);

我们现在知道为什么了。首先调用var FR= new FileReader();,然后调用FR.readAsDataURL(file);,最后,当onload 触发时:img.src = e.target.result;。那是错误的顺序。正确的顺序是:

function changeBtn(elem) {
    selfile = document.getElementById(elem.id);

    if ('files' in selfile) {
        var file = selfile.files[0];
        if ('name' in file) {
            str1 = file.name;
        }
        if ('size' in file) {
            str1 += ' (' + ((file.size / 1024) / 1024).toFixed(2) + 'MB)';
        }
        document.getElementById("label_" + elem.id).innerHTML = str1;

        var FR= new FileReader();

        FR.readAsDataURL(file);

        var img = document.createElement("img");
        FR.onload = function(e) {
            img.src = e.target.result;
            alert(e.target.result);

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

            ctx.drawImage(img, 0, 0);

            var MAX_WIDTH = 800;
            var MAX_HEIGHT = 600;
            var width = img.width;
            var height = img.height;
            alert(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);

            var dataurl = canvas.toDataURL("image/png");
            alert(dataurl);
        };
    }
} 

【讨论】:

  • 我很快就会做到这一点,我只是在纠正我的答案中的一些小拼写错误。 :)
猜你喜欢
  • 1970-01-01
  • 2012-02-24
  • 1970-01-01
  • 1970-01-01
  • 2023-04-01
  • 1970-01-01
  • 1970-01-01
  • 2017-06-21
  • 2011-09-29
相关资源
最近更新 更多