简体   繁体   English

python PIL _io.BytesIO无法读取用画布转换的图像

[英]A image converted with canvas fails to be read by python PIL _io.BytesIO

Python PIL rejects to read an image you have resized with Javascript canvas Python PIL 拒绝读取您使用 Javascript 画布调整大小的图像

I resize an image on the client-side with 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);

The result seems ok, less size, seemingly ok:结果看起来还可以,尺寸更小,看起来还可以: 在此处输入图片说明 There are only minor differences on the files with identify :带有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

Then I send the file via POST:然后我通过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);

And then I read on the server with python open_image(BytesIO(img_bytes)) :然后我用 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))

The above works without problems with any normal image, but it fails with any image that is the result of the resize with js, and the error is没有问题的上述工程与任何正常的图像,但它无法用与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>```

I've tried canvas.toDataURL("image/jpeg", quality) on the JS side, and reading directly with PIL (not fastai, which calls PIL).我已经在 J​​S 端尝试过canvas.toDataURL("image/jpeg", quality) ,并直接用 PIL 读取(不是 fastai,它调用 PIL)。 It's the same error :frowning_face:这是同样的错误:皱眉脸:

Found the answer here .这里找到了答案。

I was injecting the image as aa DataURL, when the POST expected a binary.当 POST 需要二进制文件时,我将图像作为 DataURL 注入。 I could see the difference using the "Network" tab:我可以使用“网络”选项卡看到不同之处: 在此处输入图片说明

To convert a DataURL into the binary we need to make a Blob, and then put it into a File:要将 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);

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

相关问题 使用 Django 将 html5 画布加载到 PIL 图像中 - Load an html5 canvas into a PIL Image with Django SVG图片无法使用canvg正确转换为Canvas - SVG Image not converted properly to Canvas using canvg Windows OCR引擎无法识别画布中的文本(已转换为位图) - Windows OCR engine fails to recognize the text in canvas (converted to bitmap) 使用画布显示长文本将文本转换为图像 - converted text into image using canvas display long text 如何保存从画布转换为本地文件夹的图像? - how to save an image which is converted from a canvas in to my local folder? 将画布(包括图像)复制到另一个画布失败 - Copying canvas (which includes an image) to another canvas fails 使用canvas和javascript读取图像的像素颜色 - use canvas and javascript to read the pixel colors of an image 通过 socket.io 没有在 canvas 上添加图像? - image is not being added on the canvas through socket.io? 将画布转换为html5中的图像后,当前上传的图像未设置在确切位置 - Current uploaded image not set on exact position after converted canvas into image in html5 如何以用户友好的方式在计算机上保存从画布转换的图像? - How to save an image converted from a canvas, on the computer, in a user-friendly manner?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM