简体   繁体   English

canvas 使用 toDataURL("image/jpeg") 获取空白图片

[英]canvas uses toDataURL("image/jpeg") to get a blank image


    <!DOCTYPE html>
    <html lang="en">
    
    <head>
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Document</title>
    </head>
    
    <body>
        <div>Test</div>
        <canvas id="canvas"></canvas>
    
        <script>
            const data =  ""//long char,base64 in github
        </script>
        <script>
            function watermarking(file, date, callback) {
                const img = new Image();
                img.src = file;
                img.onload = function () {
                    const canvas = document.querySelector("canvas");
                    const ctx = canvas.getContext("2d");
    
                    let width = img.width;
                    let height = img.height;
                    canvas.width = width;
                    canvas.height = height;
    
                    ctx.drawImage(img, 0, 0, width, height);
                    const newBase64 = canvas.toDataURL("image/jpeg");
                    callback(newBase64);
    
    
                };
    
                img.onerror = (e) => {
                    console.log(e);
                };
    
    
            }
            watermarking(data, "2022-11-11", (base64) => {
                console.log("base64 url:", base64)
            })
        </script>
    </body>
    
    </html>

When I use this image to get base64 url, canvas toDataURL() gets a blank image, other images get the desired effect, I don't know why.当我使用这张图片获取base64 url​​时,canvas toDataURL() 得到一个空白图片,其他图片得到想要的效果,不知道为什么。

Result from chrome log, there are many A!!!!. chrome log的结果,有很多A!!!!。

From the results, it should be that the asynchronous somewhere does not take effect, resulting in toDataURL or drawImage() getting a blank image.从结果来看,应该是某处异步没有生效,导致toDataURL或者drawImage()得到一张空白图片。

enter link description here 在此处输入链接描述

在此处输入图像描述

There is definitely something odd happening here.这里肯定发生了一些奇怪的事情。

First thing to note, the image that's contained in your data seems to be corrupted, at least Photoshop refuses to open it claiming that " an unexpected end-of-file was encountered. ".首先要注意的是,您数据中包含的图像似乎已损坏,至少 Photoshop 拒绝打开它,声称“遇到了意外的文件结尾。 ”。
And indeed trying with any other image or even the same opened in macOS Preview app, and saved with the same settings does work fine.并且确实尝试使用任何其他图像,甚至在 macOS 预览应用程序中打开的相同图像,并使用相同的设置保存都可以正常工作。

So the best is to reencode your image.所以最好的办法是重新编码你的图像。 If it happens more often, you may want to open a new question, explaining how you are producing this image.如果它更频繁地发生,您可能需要提出一个新问题,解释您是如何制作此图像的。

As for the odd part, it's that the browser is actually able to open and decode that image, but it seems that Chrome won't do this decode before being asked but still will fire the load event, and it won't wait for the image to be decoded before returning from drawImage .至于奇怪的部分,浏览器实际上能够打开并解码该图像,但似乎 Chrome 在被询问之前不会进行此解码,但仍会触发加载事件,并且不会等待从drawImage返回之前要解码的图像。 This is a bug on their part.这是他们的一个错误。 drawImage is synchronous, and it's supposed to wait for the image is decoded before returning. drawImage是同步的,它应该在返回之前等待图像被解码。 My educated guess is that Chrome expects the decoding to already have happened when the load event fires and thus they don't check in the drawImage code farther than is_loaded.我有根据的猜测是,Chrome 期望在加载事件触发时解码已经发生,因此他们不会在比 is_loaded 更远的地方签入drawImage代码。

Anyway, a quick workaround for that is to call the HTMLImageElement.decode() method, which will return a Promise resolving when the decoding is entirely done, even for this seemingly broken image.无论如何,一个快速的解决方法是调用HTMLImageElement.decode()方法,它会在解码完成后返回一个 Promise 解析,即使对于这个看似损坏的图像也是如此。
But once again the best for you is to reencode that image.但是再一次,对您来说最好的方法是重新编码该图像。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM