【问题标题】:A image converted with canvas fails to be read by python PIL _io.BytesIOpython PIL _io.BytesIO无法读取用canvas转换的图像
【发布时间】:2019-12-11 11:57:42
【问题描述】:

Python PIL 拒绝读取您使用 Javascript 画布调整大小的图像

我在客户端使用 Javascript 调整图像大小:

var reader = new FileReader();
    reader.onload = function (e) {
        el('image-picked').src = e.target.result;
        el('image-picked').className = '';
        var image = new Image();

        //compress Image
        image.onload=function(){
            el("image-picked").src=image.src;
            var canvas=document.createElement("canvas");
            var context=canvas.getContext("2d");
            new_size = get_sizes(image.width,image.height,max_side_px)
            [canvas.width,canvas.height] = new_size;
            context.drawImage(image,
                0,
                0,
                image.width,
                image.height,
                0,
                0,
                canvas.width,
                canvas.height
            );
            console.log("Converted");

            //el('image-picked').className = 'no-display'
            //el('image-picked').src=""
            el('upload-Preview').className = ''
            el('upload-Preview').src = canvas.toDataURL("image/png", quality);

结果似乎还可以,尺寸更小,貌似还可以: identify 的文件只有细微差别:

(base) ➜  Desktop file before.png after.png
before.png: PNG image data, 4048 x 3036, 8-bit/color RGB, non-interlaced
after.png:  PNG image data, 500 x 375, 8-bit/color RGBA, non-interlaced

然后我通过 POST 发送文件:

    var xhr = new XMLHttpRequest();
    var loc = window.location
    xhr.open('POST', `${loc.protocol}//${loc.hostname}:${loc.port}/analyze`, true);
    xhr.onerror = function() {alert (xhr.responseText);}
    xhr.onload = function(e) {
        if (this.readyState === 4) {
            var response = JSON.parse(e.target.responseText);
            el('result-label').innerHTML = `Result = ${response['result']}`;
        }
    }

    var fileData = new FormData();
    var file = new File([el('upload-Preview').src],
      "image.png", { type: "image/png",
                     lastModified : new Date()});
    fileData.append('file', uploadFiles[0]);
    xhr.send(fileData);

然后我在服务器上用 python open_image(BytesIO(img_bytes)) 阅读:

@app.route('/analyze', methods=['POST'])
async def analyze(request):
    data = await request.form()
    img_bytes = await (data['file'].read())
    img = open_image(BytesIO(img_bytes))

上述工作对任何正常图像都没有问题,但是对于任何使用js调整大小的结果的图像失败,错误是

File "/Users/brunosan/anaconda3/envs/fastai/lib/python3.7/site-packages/PIL/Image.py", line 2705, in open
    % (filename if filename else fp))
OSError: cannot identify image file <_io.BytesIO object at 0x124ce6360>```

我在 JS 端尝试过canvas.toDataURL("image/jpeg", quality),并直接使用 PIL 读取(不是 fastai,它调用 PIL)。还是一样的错误 :frowning_face:

【问题讨论】:

    标签: javascript python todataurl bytesio


    【解决方案1】:

    找到答案here

    当 POST 需要二进制文件时,我将图像作为 DataURL 注入。我可以使用“网络”选项卡看到差异:

    要将 DataURL 转换为二进制文件,我们需要制作一个 Blob,然后将其放入文件中:

    function dataURItoBlob(dataURI) {
        // convert base64/URLEncoded data component to raw binary data held in a string
        var byteString;
        if (dataURI.split(',')[0].indexOf('base64') >= 0)
            byteString = atob(dataURI.split(',')[1]);
        else
            byteString = unescape(dataURI.split(',')[1]);
    
        // separate out the mime component
        var mimeString = dataURI.split(',')[0].split(':')[1].split(';')[0];
    
        // write the bytes of the string to a typed array
        var ia = new Uint8Array(byteString.length);
        for (var i = 0; i < byteString.length; i++) {
            ia[i] = byteString.charCodeAt(i);
        }
    
        return new Blob([ia], {type:mimeString});
    }
    
    blob=dataURItoBlob(el('upload-Preview').src)
    var file = new File([blob],
          "image.png", { type: "image/png",
                         lastModified : new Date()});
    var fileData = new FormData();
    fileData.append('file', file);
    

    【讨论】:

      猜你喜欢
      • 2016-04-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-04-29
      • 1970-01-01
      • 2014-05-21
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多