2012-12-05 71 views
72

假設我有3841 x 7195像素大小的圖像。我想將圖的內容保存到磁盤,導致我以像素指定的確切大小的圖像以像素爲單位指定並保存精確大小的圖形

沒有軸,沒有標題。只是圖像。我個人不關心DPI,因爲我只想指定圖像在(以像素像素爲例)中的屏幕大小。

我已閱讀otherthreads,他們似乎都轉換爲英寸,然後以英寸爲單位指定圖形的尺寸並以某種方式調整dpi。我想避免處理像素到英寸轉換可能導致的準確性潛在損失。

我曾嘗試用:

w = 7195 
h = 3841 
fig = plt.figure(frameon=False) 
fig.set_size_inches(w,h) 
ax = plt.Axes(fig, [0., 0., 1., 1.]) 
ax.set_axis_off() 
fig.add_axes(ax) 
ax.imshow(im_np, aspect='normal') 
fig.savefig(some_path, dpi=1) 

沒有運氣(?Python的抱怨,寬度和高度,每一個都必須低於32768())

一切從我所看到的,matplotlib需要數字大小要在inchesdpi中指定,但我只對的像素感興趣。我怎樣才能做到這一點?

澄清:我正在尋找一種方法來與matplotlib做到這一點,而不是與其他圖像保存庫。

+0

使用matplotlib時,不可能直接以英寸爲單位設置圖形大小。 – tiago

+0

我的意思是像素... – tiago

回答

83

Matplotlib不直接使用像素,而是物理尺寸和DPI。如果要顯示具有某個像素大小的圖形,則需要知道顯示器的DPI。例如this link會爲您檢測到。

如果你有一個3841x7195像素的圖像,你不太可能監視到那麼大,所以你將不能顯示這個尺寸的圖形(matplotlib需要該圖形適合屏幕,如果你要求尺寸太大,會縮小到屏幕尺寸)。假設您只需要一個800x800像素的圖像作爲示例。以下是如何在我的顯示器(my_dpi=96)顯示的爲800x800像素的圖片:

plt.figure(figsize=(800/my_dpi, 800/my_dpi), dpi=my_dpi) 

所以你基本上只是通過你的DPI鴻溝英寸的尺寸。

如果你想保存一個特定大小的數字,那麼它是一個不同的問題。屏幕DPI不再那麼重要(除非你要求一個不適合屏幕的數字)。使用800x800像素圖的相同示例,我們可以使用dpi關鍵字savefig將其保存爲不同的分辨率。要保存它在相同的分辨率屏幕正使用相同的DPI:

plt.savefig('my_fig.png', dpi=my_dpi) 

爲了將其保存爲8000x8000像素的圖像,使用dpi的10倍:

plt.savefig('my_fig.png', dpi=my_dpi * 10) 

注意,所有後端都不支持DPI的設置。這裏使用了PNG後端,但pdf和ps後端將實現不同的大小。另外,更改DPI和大小也會影響字體大小等。較大的DPI將保持相同的字體和元素的相對大小,但如果您希望較小的字體用於較大的數字,則需要增加物理大小而不是DPI。

再回到你的例子,如果你要保存的圖像與3841 X 7195個像素,可以做到以下幾點:

plt.figure(figsize=(3.841, 7.195), dpi=100) 
(your code ...) 
plt.savefig('myfig.png', dpi=1000) 

請注意,我用的100的數字DPI以適應大多數屏幕,但保存爲dpi=1000以達到所需的分辨率。在我的系統中,這產生了3840x7190像素的PNG - 看起來DPI保存的像素總是比選定的值小0.02像素/英寸,這對大圖像尺寸會有(小)影響。關於here的更多討論。

+2

記住顯示器尺寸(以及標準的瀏覽器和UI窗口尺寸)通常是96 dpi的倍數--96的倍數,這很方便。像1440像素的突然數字是有意義的(15英寸)當想到這樣的時候。 –

+0

無法通過'figsize'傳遞給'plt.figure'。解決辦法是按照其他答案的建議,在調用_without_' figsize'之後,然後調用''figure''的'fig.set_size_inches(w,h)' – Trinidad

+0

文檔(https://matplotlib.org/api/ pyplot_api.html#matplotlib.pyplot.figure)和['savefig'](https://matplotlib.org/api/pyplot_api.html#matplotlib.pyplot.savefig)。 – handle

10

這爲我工作,根據你的代碼,生成93MB PNG由於色噪聲和所需尺寸的圖片:

import matplotlib.pyplot as plt 
import numpy 

w = 7195 
h = 3841 

im_np = numpy.random.rand(h, w) 

fig = plt.figure(frameon=False) 
fig.set_size_inches(w,h) 
ax = plt.Axes(fig, [0., 0., 1., 1.]) 
ax.set_axis_off() 
fig.add_axes(ax) 
ax.imshow(im_np, aspect='normal') 
fig.savefig('figure.png', dpi=1) 

我使用Python 2.7庫的最後PIP版本的Linux Mint的13 。

希望有所幫助!

+2

設置非常低的dpi將意味着字體幾乎不可見,除非明確使用非常大的字體大小。 – tiago

+1

設置較高的dpi並將英寸大小(無論如何是任意的)除以dpi可能會更好。除此之外,您的設置確實會爲像素複製生成精確的像素,謝謝! – FrenchKheldar

+0

我試圖使用它之前保存與它的情節元素(圓圈,線,...)的圖片。這擾亂了線寬,使得元素幾乎不可見。 – Gauthier

相關問題