Python Django,正在保存图像,操作错误:无法识别图像文件

Python Django,正在保存图像,操作错误:无法识别图像文件,python,django,file,Python,Django,File,代码: if request.is_ajax(): testpic = TestPic.objects.get(pk=1) form = TestPicForm(request.POST, request.FILES) if form.is_valid(): from PIL import Image from io import BytesIO data = request.FILES['file']

代码:

if request.is_ajax():
    testpic = TestPic.objects.get(pk=1)

    form = TestPicForm(request.POST, request.FILES)
    if form.is_valid():
        from PIL import Image
        from io import BytesIO

        data = request.FILES['file']
        data_50 = request.FILES['file']

        input_file = BytesIO(data.read())
        image_crop = Image.open(input_file)
        print('print 2')

        # Problem starts.
        input_file_50 = BytesIO(data_50.read())
        image_crop_50 = Image.open(input_file_50)
        image_crop = image_crop.crop((1,1,100,100))
        image_crop_50 = image_crop_50.crop((40, 40, 140, 140))
        image_resize = image_crop.resize((300, 300), Image.ANTIALIAS)
        image_resize_50 = image_crop_50.resize((50, 50), Image.ANTIALIAS)

        image_file = BytesIO()
        image_resize.save(image_file, 'JPEG')

        image_file_50 = BytesIO()
        image_resize_50.save(image_file_50, 'JPEG')

        data.file = image_file
        testpic.file = data

        data_50.file = image_file_50
        testpic.file_50 = data_50

        testpic.save()
        return JsonResponse({'success': 'file_uploaded'})

    return JsonResponse({'success': 'failed'})
回溯是这样的:

print 2
Traceback (most recent call last):
... I remove some lines ...
  File "D:\pythonDev\project\upward\chatkaboo\authapp\views.py", line 844, in crop
    image_crop_50 = Image.open(input_file_50)
  File "D:\pythonDev\interpreters\forMultichat\lib\site-packages\PIL\Image.py", line 2590, in open
    % (filename if filename else fp))
OSError: cannot identify image file <_io.BytesIO object at 0x0000024B40510BF8>
打印2
回溯(最近一次呼叫最后一次):
... 我删除了一些行。。。
文件“D:\pythonDev\project\upper\chatkaboo\authapp\views.py”,第844行,在crop中
image\u crop\u 50=image.open(输入文件\u 50)
文件“D:\pythonDev\interprevers\forMultichat\lib\site packages\PIL\Image.py”,第2590行,打开
%(如果文件名为fp,则为文件名)
OSError:无法识别图像文件
说明:

if request.is_ajax():
    testpic = TestPic.objects.get(pk=1)

    form = TestPicForm(request.POST, request.FILES)
    if form.is_valid():
        from PIL import Image
        from io import BytesIO

        data = request.FILES['file']
        data_50 = request.FILES['file']

        input_file = BytesIO(data.read())
        image_crop = Image.open(input_file)
        print('print 2')

        # Problem starts.
        input_file_50 = BytesIO(data_50.read())
        image_crop_50 = Image.open(input_file_50)
        image_crop = image_crop.crop((1,1,100,100))
        image_crop_50 = image_crop_50.crop((40, 40, 140, 140))
        image_resize = image_crop.resize((300, 300), Image.ANTIALIAS)
        image_resize_50 = image_crop_50.resize((50, 50), Image.ANTIALIAS)

        image_file = BytesIO()
        image_resize.save(image_file, 'JPEG')

        image_file_50 = BytesIO()
        image_resize_50.save(image_file_50, 'JPEG')

        data.file = image_file
        testpic.file = data

        data_50.file = image_file_50
        testpic.file_50 = data_50

        testpic.save()
        return JsonResponse({'success': 'file_uploaded'})

    return JsonResponse({'success': 'failed'})
正如您在上面看到的,我的代码的目的是保存请求的图像文件

我试图找出发生了什么以及哪条线路有问题。所以打印了
print 2
,因此
input\u file\u 50=BytesIO(data\u 50.read())
行出现问题

问题:

if request.is_ajax():
    testpic = TestPic.objects.get(pk=1)

    form = TestPicForm(request.POST, request.FILES)
    if form.is_valid():
        from PIL import Image
        from io import BytesIO

        data = request.FILES['file']
        data_50 = request.FILES['file']

        input_file = BytesIO(data.read())
        image_crop = Image.open(input_file)
        print('print 2')

        # Problem starts.
        input_file_50 = BytesIO(data_50.read())
        image_crop_50 = Image.open(input_file_50)
        image_crop = image_crop.crop((1,1,100,100))
        image_crop_50 = image_crop_50.crop((40, 40, 140, 140))
        image_resize = image_crop.resize((300, 300), Image.ANTIALIAS)
        image_resize_50 = image_crop_50.resize((50, 50), Image.ANTIALIAS)

        image_file = BytesIO()
        image_resize.save(image_file, 'JPEG')

        image_file_50 = BytesIO()
        image_resize_50.save(image_file_50, 'JPEG')

        data.file = image_file
        testpic.file = data

        data_50.file = image_file_50
        testpic.file_50 = data_50

        testpic.save()
        return JsonResponse({'success': 'file_uploaded'})

    return JsonResponse({'success': 'failed'})
为什么会发生这种错误
BytesIO
一次只能处理一个文件


如何处理一个文件并将其保存为两个或多个文件?

正如@wiesion在对该问题的评论中所说,您可以尝试使用
数据重置缓冲区。seek(0)

为什么??在你的代码里有

data = request.FILES['file']
data_50 = request.FILES['file']
这意味着
data
data\u 50
将指向同一个文件。调用
data.read()
时,内容被读取,当前位置保持在文件的末尾

稍后调用
data\u 50.read()
,当前位置已经在末尾(因为它与
data
是同一个文件),并且没有更多的内容要读取,因此调用
read()
不会返回任何内容。因此没有要保存的图像

通过调用
data.seek(0)
(或
data\u 50.seek(0)
request.FILES['file'].seek(0)
),您告诉该文件再次将当前位置放在文件的开头,以便下次调用
read()
可以再次输出整个文件内容

input_file = BytesIO(data.read())
image_crop = Image.open(input_file)
print('print 2')

# ADD THIS LINE TO YOUR CODE
# it modifies the 'data' object, which is the same as 'data_50'
data.seek(0)

# Problem starts.
input_file_50 = BytesIO(data_50.read())
image_crop_50 = Image.open(input_file_50)

您可以尝试的另一种方法(不调用
.seek(0)
)是将
.read()
的结果分配给变量:

file_content = request.FILES['file'].read()
input_file = BytesIO(file_content)
input_file_50 = BytesIO(file_content)

image_crop = Image.open(input_file)
image_crop_50 = Image.open(input_file_50)

也许你可以试试这个版本,让我们知道它是否解决了你的问题。

第一个猜测:在
data.read()之后。
你应该做
data.seek(0)
谢谢你的回答。但我有一个问题,如果我使用您的“using read()”,我在哪里可以找到或处理行:“data.file=image\u file testpic.file=data data\u 50.file=image\u file\u 50 testpic.file\u 50=data\u 50”。。。说得好。我不太确定。但首先要做的事情是:您是否仅通过添加
数据来尝试代码。seek(0)
?只有这样,我们才能继续寻找优化/改进代码的方法。好吧,我试过了,但它抛出了
一个字节,像object is required,而不是'int'
这可能是错误吗?还是我做错了什么?
input\u file=BytesIO(data.seek(0))
这一行。这里是回溯:
回溯(最近一次调用上次):…已删除。。。文件“D:\pythonDev\project\upper\chatkaboo\authapp\views.py”,第840行,在crop input\u File=BytesIO(data.seek(0))TypeError:需要一个类似字节的对象,而不是“int”[2018/06/23 22:19:05]HTTP POST/accounts/crop/500[0.03127.0.0.1:53564]
Ah,no,
data.seek(0)
应该是它自己的行。试着将这一行添加到代码中;我对我的答案进行了编辑,以显示你应该把那一行放在哪里。