canvas 转换的图像无法被 python PIL _io.BytesIO 读取
A image converted with canvas fails to be read by python PIL _io.BytesIO
Python PIL 拒绝读取您用 Javascript canvas
调整大小的图像
我在客户端调整图像大小 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:
找到答案here。
我将图像作为 DataURL 注入,而 POST 需要一个二进制文件。我可以使用 "Network" 选项卡看到不同之处:
要将 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);
Python PIL 拒绝读取您用 Javascript canvas
调整大小的图像我在客户端调整图像大小 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:
找到答案here。
我将图像作为 DataURL 注入,而 POST 需要一个二进制文件。我可以使用 "Network" 选项卡看到不同之处:
要将 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);