簡體   English   中英

Python:優化內存中的圖像(使用jpegoptim進行StringIO和POpen)

[英]Python: Optimizing Images in Memory (StringIO & POpen with jpegoptim)

我正在嘗試使用STDIN版本的各種庫(本例中為jpegoptim)壓縮圖像而不觸摸磁盤。

此代碼不返回優化(jpegoptim壓縮)圖像。

有人可以幫助或解釋為什么Popen()與StringIO.StringIO()對象的使用不會返回圖像的優化版本? 如果我將文件保存到磁盤,它可以正常工作。

import sys
import urllib2 as urllib
import StringIO

from subprocess import Popen, PIPE, STDOUT
fp = urllib.urlopen('http://www.path.to/unoptimized.jpg')
out_im2 = StringIO.StringIO(fp.read()) # StringIO Image
print "Image Size: %s" % format(sys.getsizeof(out_im2.getvalue()))
subp = Popen(["/usr/bin/jpegoptim", "-"], shell=True, stdout=PIPE, stdin=PIPE, stderr=STDOUT)
image_str = subp.communicate(input=out_im2.getvalue())[0]
out_im2.write(image_str)

##This should be a different size if it worked! It's not
print "Compressed JPG: %s" % format(sys.getsizeof(out_im2.getvalue()))

這是因為您正在寫入相同的輸入緩沖區。 創建一個新的StringIO()。

StringIO緩沖區最初擴展到第一個未壓縮的jpeg的大小。 然后使用新的較短字符串緩沖區從0位置開始寫入緩沖區,但它不會自動截斷緩沖區或任何內容。 StringIO緩沖區的大小仍然相同,實際上所有尾隨數據都將保留在原始映像的垃圾中。

In [1]: import StringIO

In [2]: out = StringIO.StringIO("abcdefg")

In [3]: out.getvalue()
Out[3]: 'abcdefg'

In [4]: out.write("123")

In [5]: out.getvalue()
Out[5]: '123defg'

有幾個問題:

  1. StringIO() 指出錯誤覆蓋StringIO()緩沖區的問題
  2. 使用len而不是sys.getsizeof() 后者返回內存中內部表示的大小,該大小不等於bytestring中的字節數

  3. 不要一起使用list參數和shell=True

您可以將套接字作為stdin傳遞給某些系統上的子進程:

import socket
from urllib2 import urlopen
from subprocess import check_output

saved = socket._fileobject.default_bufsize
socket._fileobject.default_bufsize = 0  # hack to disable buffering
try:
    fp = urlopen('http://www.path.to/unoptimized.jpg')
finally:
    socket._fileobject.default_bufsize = saved # restore back

# urlopen() has read http headers; subprocess can read the body now
image_bytes = check_output(["/usr/bin/jpegoptim", "-"], stdin=fp) 
fp.close()

# use `image_bytes` bytestring here..

stderr未設置為避免隱藏錯誤。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM