Подпроцесс Python: проведите кадр изображения в команду imagemagick shell
У меня есть изображение в памяти, и я хочу выполнить метод convert
imagemagick с использованием subprocess
Python. Хотя эта линия хорошо работает с терминалом Ubuntu:
cat image.png | convert - new_image.jpg
Этот кусок кода не работает с использованием Python:
jpgfile = Image.open('image.png'); proc = Popen(['convert', '-', 'new_image.jpg'], stdin=PIPE, shell=True) print proc.communicate(jpgfile.tostring())
Я также пробовал читать изображение как обычный файл без использования PIL, я пробовал переключение между методами subprocess
и разными способами записи в stdin.
Лучшая часть – ничего не происходит, но я не получаю реальной ошибки. Когда вы печатаете stdout, я вижу обратную помощь на терминале, а затем следующее:
По умолчанию формат файла `file 'определяется его магическим числом. Чтобы указать конкретный формат изображения, перед именем файла укажите имя формата изображения и двоеточие (например, ps: изображение) или укажите тип изображения в качестве суффикса имени файла (например, image.ps). Укажите «файл» как «-» для стандартного ввода или вывода. (Нет, Нет)
Может быть, здесь есть намек, который я не получаю. Пожалуйста, укажите мне в правильном направлении, я новичок в Python, но из моего опыта работы с PHP это должно быть очень простой задачей, или я надеюсь.
Редактировать:
Это решение, которое я в конечном итоге использовал для обработки объекта изображения PIL без сохранения временного файла. Надеюсь, это поможет кому-то. (в примере я читаю файл с локального диска, но идея состоит в том, чтобы прочитать изображение из удаленного места)
out = StringIO() jpgfile = Image.open('image.png') jpgfile.save(out, 'png', quality=100); out.seek(0); proc = Popen(['convert', '-', 'image_new.jpg'], stdin=PIPE) proc.communicate(out.read())
- subprocess.call с использованием строки vs с использованием списка
- Подпроцессы python readlines ()?
- Использование модуля Python для открытия проводника в файле
- Инструмент командной строки Bigquery в Windows
- Подпроцесс Python – запуск нескольких команд оболочки через SSH
Это не подпроцесс, вызывающий какую-либо проблему, это то, что вы передаете imagemagick, что неверно, tostring()
передается в imagemagick
. если вы действительно хотели реплицировать команду linux, вы можете переходить из одного процесса в другой:
from subprocess import Popen,PIPE proc = Popen(['cat', 'image.jpg'], stdout=PIPE) p2 = Popen(['convert', '-', 'new_image.jpg'],stdin=proc.stdout) proc.stdout.close() out,err = proc.communicate() print(out)
Когда вы передаете список аргументов, вам не требуется shell = True, если вы хотите использовать shell = True, вы должны передать одну строку:
from subprocess import check_call check_call('cat image.jpg | convert - new_image.jpg',shell=True)
Обычно я бы избегал shell=True
. Этот ответ описывает, что именно shell = True делает.
Вы также можете передать файл-объект в stdin:
with open('image.jpg') as jpgfile: proc = Popen(['convert', "-", 'new_image.jpg'], stdin=jpgfile) out, err = proc.communicate() print(out)
Но так как нет результата при успешном выполнении кода, вы можете использовать check_call, который повысит CalledProcessError, если есть ненулевой статус выхода, который вы можете поймать и предпринять соответствующие действия:
from subprocess import check_call, CalledProcessError with open('image.jpg') as jpgfile: try: check_call(['convert', "-", 'new_image.jpg'], stdin=jpgfile) except CalledProcessError as e: print(e.message)
Если вы хотите написать в stdin, используя связь, вы также можете передать содержимое файла, используя .read:
with open('image.jpg') as jpgfile: proc = Popen(['convert', '-', 'new_image.jpg'], stdin=PIPE) proc.communicate(jpgfile.read())
Если вы хотите, не хотите хранить изображение на диске, используйте tempfile:
import tempfile import requests r = requests.get("http://www.reptileknowledge.comhttp://img.rupython.com/pythonball-python.jpg") out = tempfile.TemporaryFile() out.write(r.content) out.seek(0) from subprocess import check_call check_call(['convert',"-", 'new_image.jpg'], stdin=out)
Использование объекта CStringIo.StringIO :
import requests r = requests.get("http://www.reptileknowledge.comhttp://img.rupython.com/pythonball-python.jpg") out = cStringIO.StringIO(r.content) from subprocess import check_call,Popen,PIPE p = Popen(['convert',"-", 'new_image.jpg'], stdin=PIPE) p.communicate(out.read())
- Разделение Django F () – Как избежать округления
- Накладные расходы / производительность данных Python
- Мониторинг сбоя программы
- Python – как выполнять команды оболочки с помощью трубы?
- Использование subprocess.Popen для процесса с большим выходом
- «Pwd» дает путь к машине Windows при запуске подпроцесса python
- Почему Popen.poll () возвращает код возврата None, даже если подпроцесс завершен?
- subprocess.check_output (): показать вывод при сбое
- Python – Выполнение процесса -> Блокировать до выхода и подавления вывода
- Python3 asyncio: wait_for () общаться () с таймаутом, как получить частичный результат?
- Извлечение имени основного класса java в python