So sánh các phương pháp khác nhau để đặt kích thước hình ảnh chính xác trong pixel
Câu trả lời này sẽ tập trung vào:
1: Cách lưu vào tệp, không chỉ hiển thị trên màn hình#!/usr/bin/env python3 import sys import numpy as np import matplotlib.pyplot as plt import matplotlib as mpl height = int[sys.argv[1]] fig, ax = plt.subplots[] t = np.arange[-10., 10., 1.] plt.plot[t, t, '.'] plt.plot[t, t**2, '.'] ax.text[0., 60., 'Hello', fontdict=dict[size=25]] plt.savefig[ 'get_size.png', format='png', dpi=height/fig.get_size_inches[][1] ]
- Đặt kích thước tính bằng pixel
Dưới đây là một so sánh nhanh về một số phương pháp tôi đã thử với hình ảnh cho thấy những gì cho.
Tóm tắt tình trạng hiện tại: Mọi thứ lộn xộn, không chắc đó là một hạn chế cơ bản hay nếu trường hợp sử dụng không nhận được đủ sự chú ý từ các nhà phát triển, tôi không thể dễ dàng tìm thấy một cuộc thảo luận ngược dòng về điều này.
Ví dụ cơ bản mà không cố gắng đặt kích thước hình ảnh
Chỉ để có một điểm so sánh:
base.py
#!/usr/bin/env python3
import sys
import numpy as np
import matplotlib.pyplot as plt
import matplotlib as mpl
fig, ax = plt.subplots[]
print['fig.dpi = {}'.format[fig.dpi]]
print['fig.get_size_inches[] = ' + str[fig.get_size_inches[]]
t = np.arange[-10., 10., 1.]
plt.plot[t, t, '.']
plt.plot[t, t**2, '.']
ax.text[0., 60., 'Hello', fontdict=dict[size=25]]
plt.savefig['base.png', format='png']
run:
./base.py
identify base.png
outputs:
fig.dpi = 100.0
fig.get_size_inches[] = [6.4 4.8]
base.png PNG 640x480 640x480+0+0 8-bit sRGB 13064B 0.000u 0:00.000
Cách tiếp cận tốt nhất của tôi cho đến nay:
2 Kiểm soát chỉ có chiều cao#!/usr/bin/env python3
import sys
import numpy as np
import matplotlib.pyplot as plt
import matplotlib as mpl
height = int[sys.argv[1]]
fig, ax = plt.subplots[]
t = np.arange[-10., 10., 1.]
plt.plot[t, t, '.']
plt.plot[t, t**2, '.']
ax.text[0., 60., 'Hello', fontdict=dict[size=25]]
plt.savefig[
'get_size.png',
format='png',
dpi=height/fig.get_size_inches[][1]
]
Tôi nghĩ rằng đây là những gì tôi sẽ đi với hầu hết thời gian, vì nó đơn giản và quy mô:
get_size.py
#!/usr/bin/env python3
import sys
import numpy as np
import matplotlib.pyplot as plt
import matplotlib as mpl
height = int[sys.argv[1]]
fig, ax = plt.subplots[]
t = np.arange[-10., 10., 1.]
plt.plot[t, t, '.']
plt.plot[t, t**2, '.']
ax.text[0., 60., 'Hello', fontdict=dict[size=25]]
plt.savefig[
'get_size.png',
format='png',
dpi=height/fig.get_size_inches[][1]
]
run:
./get_size.py 431
outputs:
get_size.png PNG 574x431 574x431+0+0 8-bit sRGB 10058B 0.000u 0:00.000
và
./get_size.py 1293
outputs:
main.png PNG 1724x1293 1724x1293+0+0 8-bit sRGB 46709B 0.000u 0:00.000
Tôi có xu hướng chỉ đặt chiều cao bởi vì tôi thường quan tâm nhất về việc không gian thẳng đứng mà hình ảnh sẽ chiếm giữa văn bản của tôi.
3 Thay đổi kích thước hình ảnh#!/usr/bin/env python3
import sys
import numpy as np
import matplotlib.pyplot as plt
import matplotlib as mpl
height = int[sys.argv[1]]
fig, ax = plt.subplots[]
t = np.arange[-10., 10., 1.]
plt.plot[t, t, '.']
plt.plot[t, t**2, '.']
ax.text[0., 60., 'Hello', fontdict=dict[size=25]]
plt.savefig[
'get_size.png',
format='png',
dpi=height/fig.get_size_inches[][1]
]
Tôi luôn cảm thấy rằng có quá nhiều không gian trắng xung quanh hình ảnh và có xu hướng thêm
#!/usr/bin/env python3
import sys
import numpy as np
import matplotlib.pyplot as plt
import matplotlib as mpl
height = int[sys.argv[1]]
fig, ax = plt.subplots[]
t = np.arange[-10., 10., 1.]
plt.plot[t, t, '.']
plt.plot[t, t**2, '.']
ax.text[0., 60., 'Hello', fontdict=dict[size=25]]
plt.savefig[
'get_size.png',
format='png',
dpi=height/fig.get_size_inches[][1]
]
4 khỏi: Xóa không gian trắng xung quanh một hình ảnh đã lưuTuy nhiên, điều đó hoạt động bằng cách cắt hình ảnh và bạn sẽ không nhận được kích thước mong muốn với nó.
Thay vào đó, cách tiếp cận khác này được đề xuất trong cùng một câu hỏi dường như hoạt động tốt:
plt.tight_layout[pad=1]
plt.savefig[...
trong đó cung cấp chiều cao mong muốn chính xác cho chiều cao bằng 431:
Chiều cao cố định,
5, chiều rộng có kích thước tự động và tỷ suất lợi nhuận nhỏ#!/usr/bin/env python3
import sys
import numpy as np
import matplotlib.pyplot as plt
import matplotlib as mpl
height = int[sys.argv[1]]
fig, ax = plt.subplots[]
t = np.arange[-10., 10., 1.]
plt.plot[t, t, '.']
plt.plot[t, t**2, '.']
ax.text[0., 60., 'Hello', fontdict=dict[size=25]]
plt.savefig[
'get_size.png',
format='png',
dpi=height/fig.get_size_inches[][1]
]
ERMMM,
#!/usr/bin/env python3
import sys
import numpy as np
import matplotlib.pyplot as plt
import matplotlib as mpl
height = int[sys.argv[1]]
fig, ax = plt.subplots[]
t = np.arange[-10., 10., 1.]
plt.plot[t, t, '.']
plt.plot[t, t**2, '.']
ax.text[0., 60., 'Hello', fontdict=dict[size=25]]
plt.savefig[
'get_size.png',
format='png',
dpi=height/fig.get_size_inches[][1]
]
5 làm hỏng mọi thứ một lần nữa và ngăn chặn #!/usr/bin/env python3
import sys
import numpy as np
import matplotlib.pyplot as plt
import matplotlib as mpl
height = int[sys.argv[1]]
fig, ax = plt.subplots[]
t = np.arange[-10., 10., 1.]
plt.plot[t, t, '.']
plt.plot[t, t**2, '.']
ax.text[0., 60., 'Hello', fontdict=dict[size=25]]
plt.savefig[
'get_size.png',
format='png',
dpi=height/fig.get_size_inches[][1]
]
7 thực sự loại bỏ lề ... Đây là một trường hợp sử dụng quan trọng mà tôi chưa có giải pháp tuyệt vời.Đã hỏi tại: Làm thế nào để có được chiều cao cố định trong pixel, đã cố định tỷ lệ khung hình X/Y và tự động loại bỏ lề lề trắng ngang trong matplotlib?
2 + điều khiển chiều rộng#!/usr/bin/env python3
import sys
import numpy as np
import matplotlib.pyplot as plt
import matplotlib as mpl
height = int[sys.argv[1]]
fig, ax = plt.subplots[]
t = np.arange[-10., 10., 1.]
plt.plot[t, t, '.']
plt.plot[t, t**2, '.']
ax.text[0., 60., 'Hello', fontdict=dict[size=25]]
plt.savefig[
'get_size.png',
format='png',
dpi=height/fig.get_size_inches[][1]
]
Nếu bạn thực sự cần một chiều rộng cụ thể ngoài chiều cao, điều này có vẻ hoạt động tốt:
width.py
#!/usr/bin/env python3
import sys
import numpy as np
import matplotlib.pyplot as plt
import matplotlib as mpl
h = int[sys.argv[1]]
w = int[sys.argv[2]]
fig, ax = plt.subplots[]
wi, hi = fig.get_size_inches[]
fig.set_size_inches[hi*[w/h], hi]
t = np.arange[-10., 10., 1.]
plt.plot[t, t, '.']
plt.plot[t, t**2, '.']
ax.text[0., 60., 'Hello', fontdict=dict[size=25]]
plt.savefig[
'width.png',
format='png',
dpi=h/hi
]
run:
./base.py
identify base.png
0output:
./base.py
identify base.png
1và cho một chiều rộng nhỏ:
./base.py
identify base.png
0output:
./base.py
identify base.png
3Vì vậy, có vẻ như các phông chữ đang mở rộng chính xác, chúng tôi chỉ gặp một số rắc rối cho chiều rộng rất nhỏ với các nhãn bị cắt, ví dụ:
#!/usr/bin/env python3
import sys
import numpy as np
import matplotlib.pyplot as plt
import matplotlib as mpl
height = int[sys.argv[1]]
fig, ax = plt.subplots[]
t = np.arange[-10., 10., 1.]
plt.plot[t, t, '.']
plt.plot[t, t**2, '.']
ax.text[0., 60., 'Hello', fontdict=dict[size=25]]
plt.savefig[
'get_size.png',
format='png',
dpi=height/fig.get_size_inches[][1]
]
9 ở trên cùng bên trái.Tôi đã xoay sở để làm việc xung quanh những người với việc loại bỏ không gian trắng xung quanh một hình ảnh đã lưu
./base.py
identify base.png
4Mà mang lại:
./base.py
identify base.png
5Từ đó, chúng ta cũng thấy rằng
./get_size.py 431
0 sẽ loại bỏ rất nhiều khoảng trống ở đầu hình ảnh, vì vậy tôi thường luôn sử dụng nó.Cố định chiều cao cơ sở ma thuật,
1 trên quy mô ./get_size.py 431
2 và ./get_size.py 431
3./get_size.py 431
Tôi tin rằng điều này tương đương với cách tiếp cận được đề cập tại: //stackoverflow.com/a/13714720/895245
magic.py
./base.py
identify base.png
6run:
./base.py
identify base.png
7outputs:
./base.py
identify base.png
8Và để xem nó có tỷ lệ độc đáo không:
./base.py
identify base.png
9outputs:
fig.dpi = 100.0
fig.get_size_inches[] = [6.4 4.8]
base.png PNG 640x480 640x480+0+0 8-bit sRGB 13064B 0.000u 0:00.000
0Vì vậy, chúng tôi thấy rằng phương pháp này cũng hoạt động tốt. Vấn đề duy nhất tôi gặp phải là bạn phải đặt tham số
./get_size.py 431
4 đó hoặc tương đương.Đã sửa lỗi DPI +
5./get_size.py 431
Cách tiếp cận này đã đưa ra một kích thước pixel hơi sai, và nó làm cho nó khó có thể mở rộng mọi thứ một cách liền mạch.
set_size_inches.py
fig.dpi = 100.0
fig.get_size_inches[] = [6.4 4.8]
base.png PNG 640x480 640x480+0+0 8-bit sRGB 13064B 0.000u 0:00.000
1run:
fig.dpi = 100.0
fig.get_size_inches[] = [6.4 4.8]
base.png PNG 640x480 640x480+0+0 8-bit sRGB 13064B 0.000u 0:00.000
2outputs:
fig.dpi = 100.0
fig.get_size_inches[] = [6.4 4.8]
base.png PNG 640x480 640x480+0+0 8-bit sRGB 13064B 0.000u 0:00.000
3Vì vậy, chiều cao hơi tắt và hình ảnh:
Các kích thước pixel cũng chính xác nếu tôi làm cho nó lớn hơn 3 lần:
fig.dpi = 100.0
fig.get_size_inches[] = [6.4 4.8]
base.png PNG 640x480 640x480+0+0 8-bit sRGB 13064B 0.000u 0:00.000
4outputs:
fig.dpi = 100.0
fig.get_size_inches[] = [6.4 4.8]
base.png PNG 640x480 640x480+0+0 8-bit sRGB 13064B 0.000u 0:00.000
5Tuy nhiên, chúng tôi hiểu rằng đối với cách tiếp cận này với tỷ lệ độc đáo, bạn cần thực hiện mọi cài đặt phụ thuộc DPI tỷ lệ thuận với kích thước tính bằng inch.
Trong ví dụ trước, chúng tôi chỉ tạo ra văn bản "Xin chào" tỷ lệ và nó đã giữ được chiều cao của nó trong khoảng từ 60 đến 80 như chúng tôi mong đợi. Nhưng tất cả mọi thứ mà chúng tôi không làm điều đó, trông nhỏ bé, bao gồm:
- chiều rộng đường của trục
- Nhãn đánh dấu
- Điểm đánh dấu điểm
SVG
Tôi không thể tìm thấy cách đặt nó cho hình ảnh SVG, các cách tiếp cận của tôi chỉ hoạt động cho PNG, ví dụ:
get_size_svg.py
fig.dpi = 100.0
fig.get_size_inches[] = [6.4 4.8]
base.png PNG 640x480 640x480+0+0 8-bit sRGB 13064B 0.000u 0:00.000
6run:
fig.dpi = 100.0
fig.get_size_inches[] = [6.4 4.8]
base.png PNG 640x480 640x480+0+0 8-bit sRGB 13064B 0.000u 0:00.000
7và đầu ra được tạo chứa:
fig.dpi = 100.0
fig.get_size_inches[] = [6.4 4.8]
base.png PNG 640x480 640x480+0+0 8-bit sRGB 13064B 0.000u 0:00.000
8và xác định nói:
fig.dpi = 100.0
fig.get_size_inches[] = [6.4 4.8]
base.png PNG 640x480 640x480+0+0 8-bit sRGB 13064B 0.000u 0:00.000
9Và nếu tôi mở nó trong Chromium 86, công cụ gỡ lỗi trình duyệt đã xác nhận rằng chiều cao là 460,79.
Nhưng tất nhiên, vì SVG là một định dạng vector, mọi thứ nên theo quy mô lý thuyết, vì vậy bạn chỉ có thể chuyển đổi sang bất kỳ định dạng có kích thước cố định nào mà không mất độ phân giải, ví dụ:
#!/usr/bin/env python3
import sys
import numpy as np
import matplotlib.pyplot as plt
import matplotlib as mpl
height = int[sys.argv[1]]
fig, ax = plt.subplots[]
t = np.arange[-10., 10., 1.]
plt.plot[t, t, '.']
plt.plot[t, t**2, '.']
ax.text[0., 60., 'Hello', fontdict=dict[size=25]]
plt.savefig[
'get_size.png',
format='png',
dpi=height/fig.get_size_inches[][1]
]
0Cung cấp chiều cao chính xác:
Tôi sử dụng Inkscape thay vì
./get_size.py 431
6 của ImageMagick ở đây vì bạn cũng cần phải gây rối với ./get_size.py 431
7 để có được SVG SVG thay đổi kích thước với ImageMagick:- //superuser.com/questions/598849/imagemagick-convert-how-to-produce-sharp-resized-png-files-from-svg-files/1602059#1602059
- Làm thế nào để chuyển đổi SVG thành PNG với Imagemagick?
Và cài đặt
./get_size.py 431
8 trên HTML cũng chỉ nên hoạt động cho trình duyệt.Được thử nghiệm trên matplotlib == 3.2.2.