2017-01-19 1 views
2

Мы пытаемся перенести файл поддержки домашнего задания, который хорошо работает в Linux на Windows. Часть задания требует от студентов обработки необработанных данных изображения, а файлы поддержки используют Python для преобразования между необработанными данными и файлами изображений. Код для преобразования графических файлов в исходных данных является:Почему я получаю «Недостаточно данных изображения» от Pillow в Windows, в то время как тот же код хорошо работает в Linux?

import os, sys 
from PIL import Image 
from struct import * 

fileName = sys.argv[1] 
try: 
    myImg = Image.open(fileName) 
    width,height = myImg.size 
    sys.stdout.write(pack("ii",width,height)) 
    rgbImg = myImg.convert("RGB") 
    pixels = rgbImg.getdata() 
    for (r,g,b) in pixels: 
     sys.stdout.write(pack("BBB", r,g,b)) 
except IOError, e: 
    print >> sys.stderr, "%s: %s\n\nCannot open or understand %s" % (sys.argv[0], str(e), fileName) 

Хотя код для преобразования обратно:

import os, sys 
from PIL import Image 
from struct import * 

fileName = sys.argv[1] 
try: 
    dimensions = sys.stdin.read(2*4) 
    width,height = unpack("ii", dimensions) 

    pixels = sys.stdin.read(3*width*height) 
    myImg = Image.frombytes("RGB", (width, height), pixels, "raw", "RGB", 0, 1) 
    myImg.save(fileName, "PNG") 
except IOError, e: 
    print >> sys.stderr, "%s: %s\n\nCannot open or write to %s" % (sys.argv[0], str(e), fileName) 

Стандартные выходы и входы перенаправляются на файлы в коде проверки объектов. Код отлично работает в Linux, но не работает в Windows. Мы всегда получаем следующую ошибку при попытке записи файлов изображений в Windows:

Traceback (most recent call last): 
    File "image-rewrite.py", line 16, in <module> 
    myImg = Image.frombytes("RGB", (width, height), pixels, "raw", "RGB", 0, 1) 
    File "C:\Python27\lib\site-packages\PIL\Image.py", line 2100, in frombytes 
    im.frombytes(data, decoder_name, args) 
    File "C:\Python27\lib\site-packages\PIL\Image.py", line 742, in frombytes 
    raise ValueError("not enough image data") 
ValueError: not enough image data 

У вас есть идеи, что не так? Большое спасибо.

ответ

2

Использование stdin/stdout для передачи двоичных данных в Windows - плохая идея. Windows использует CRLF ('\r\n') в качестве маркера End Of Line, который переводится на \n на вход и выводится на выход; что процесс перевода может привести к хаосу с двоичными данными.

Вместо этого вы должны использовать именованные файлы и открывать их в двоичном режиме.


Кстати, в Python 3, вы не можете читать/писать бинарные данные непосредственно из/в sys.stdin/sys.stdout, даже на Linux. Вместо этого вам необходимо использовать методы read/writesys.stdin.buffer/sys.stdout.buffer.

+0

Для Python 2 опция '-u' использует небуферизованный стандартный ввод-вывод. В Windows он также переключается в двоичный режим, т. Е. Отключает перевод новой строки на 'stdin' и' stdout'. Вы также можете установить переменную окружения 'PYTHONUNBUFFERED', но установка этого постоянно прерывает интерактивный REPL Python 2, который зависит от перевода новой строки при чтении с консоли Windows. – eryksun

+0

@eryksun Спасибо за информацию! Я иногда использовал опцию '-u' (в Python 2), но забыл, что он также устанавливает двоичный файл' stdout'/'stderr' (находясь в Linux, текстовый или двоичный режим редко что-то я думаю, но я все еще пытаюсь открыть мои файлы в соответствующем режиме), но я совершенно не знал, что это повлияло на 'stdin'. –

+0

В командной строке не упоминается 'stdin', но это [документально] (https://docs.python.org/2/using/cmdline.html#cmdoption-u). – eryksun

Смежные вопросы