python - Python 枕头使我的 JPG 文件大 3 倍
问题描述
我正在使用 Pillow 来操作一些 JPG。当我保存经过处理的 JPG 文件时,它的大小是原始文件的三倍。我只画了三个矩形并在图像上添加了一个小文本标签。为什么 Pillow 处理的结果文件比原始文件大得多?我怎样才能使尺寸更接近原始尺寸?
这是一些版本信息和文件列表,以便您可以看到我尝试过的一些故障排除工作。文件image.jpg是原始文件。
版本和文件列表:
pi@raspberrypi:~ $ pip3 freeze | grep -i pil
Pillow==5.4.1
pi@raspberrypi:~ $ python3 --version
Python 3.7.3
pi@raspberrypi:~ ll image*
-rw-r--r-- 1 pi pi 106522 Jul 9 17:14 image2.jpg
-rw-r--r-- 1 pi pi 101431 Jul 9 17:14 imageconv.jpg
-rw-r--r-- 1 pi pi 35873 Jul 9 03:15 image.jpg
-rw-r--r-- 1 pi pi 104781 Jul 9 17:14 imageopt.jpg
-rw-r--r-- 1 pi pi 138430 Jul 9 17:14 imageq85.jpg
-rw-r--r-- 1 pi pi 35856 Jul 9 17:14 imageresaved.jpg
文件操作代码:
def imageDecorate(event_dir, boxes):
source_image = event_dir + "/image.jpg"
dest_image = event_dir + "/image2.jpg"
dest_image3 = event_dir + "/imageq85.jpg"
dest_image4 = event_dir + "/imageopt.jpg"
dest_image5 = event_dir + "/imageconv.jpg"
dest_image6 = event_dir + "/imageresaved.jpg"
if not isfile(source_image):
return False
base = Image.open(source_image).convert('RGBA')
out3 = base.convert('CMYK')
out4 = Image.open(source_image)
# Draw rectangles and text label
draw = ImageDraw.Draw(base)
fnt = ImageFont.truetype("fonts/DejaVuSansMono.ttf", 12)
for box in boxes:
# Omitting irrelevant details. It's normal ImageDraw stuff ...
draw.rectangle( [...])
draw.rectangle( [...])
draw.rectangle( [...])
draw.text( [...] )
out2 = base.convert('CMYK')
# Write to dest_image.
out2.save(dest_image) # image2 - manipulated image
out2.save(dest_image3, quality=85) # imageq85 - Expect it to be larger than image2
out2.save(dest_image4, optimize=True) # imageopt - Expect it to be smaller than image2
out3.save(dest_image5) # imageconv - no editing, just convert -> RGBA -> CYMK
out4.save(dest_image6) # imageresaved - original image, resaved, no change
return True
我在文件头中找到了一些线索,但是我对 JPG 文件的了解还不够,无法理解这些线索并采取行动。
原始文件的标题:
pi@raspberrypi:~ $ xxd image.jpg | head -20
00000000: ffd8 ffe0 0010 4a46 4946 0001 0100 0001 ......JFIF......
00000010: 0001 0000 ffdb 0043 0008 0606 0706 0508 .......C........
00000020: 0707 0709 0908 0a0c 140d 0c0b 0b0c 1912 ................
00000030: 130f 141d 1a1f 1e1d 1a1c 1c20 242e 2720 ........... $.'
00000040: 222c 231c 1c28 3729 2c30 3134 3434 1f27 ",#..(7),01444.'
00000050: 393d 3832 3c2e 3334 32ff db00 4301 0909 9=82<.342...C...
00000060: 090c 0b0c 180d 0d18 3221 1c21 3232 3232 ........2!.!2222
00000070: 3232 3232 3232 3232 3232 3232 3232 3232 2222222222222222
00000080: 3232 3232 3232 3232 3232 3232 3232 3232 2222222222222222
00000090: 3232 3232 3232 3232 3232 3232 3232 ffc0 22222222222222..
000000a0: 0011 0801 5102 5803 0122 0002 1101 0311 ....Q.X.."......
000000b0: 01ff c400 1f00 0001 0501 0101 0101 0100 ................
000000c0: 0000 0000 0000 0001 0203 0405 0607 0809 ................
000000d0: 0a0b ffc4 00b5 1000 0201 0303 0204 0305 ................
000000e0: 0504 0400 0001 7d01 0203 0004 1105 1221 ......}........!
000000f0: 3141 0613 5161 0722 7114 3281 91a1 0823 1A..Qa."q.2....#
00000100: 42b1 c115 52d1 f024 3362 7282 090a 1617 B...R..$3br.....
00000110: 1819 1a25 2627 2829 2a34 3536 3738 393a ...%&'()*456789:
00000120: 4344 4546 4748 494a 5354 5556 5758 595a CDEFGHIJSTUVWXYZ
00000130: 6364 6566 6768 696a 7374 7576 7778 797a cdefghijstuvwxyz
文件imageconv.jpg的头文件,它被简单地转换为 RGBA,然后再转换回 CMYK:
pi@raspberrypi:~ $ xxd imageconv.jpg | head -20
00000000: ffd8 ffee 000e 4164 6f62 6500 6400 0000 ......Adobe.d...
00000010: 0000 ffdb 0043 0008 0606 0706 0508 0707 .....C..........
00000020: 0709 0908 0a0c 140d 0c0b 0b0c 1912 130f ................
00000030: 141d 1a1f 1e1d 1a1c 1c20 242e 2720 222c ......... $.' ",
00000040: 231c 1c28 3729 2c30 3134 3434 1f27 393d #..(7),01444.'9=
00000050: 3832 3c2e 3334 32ff c000 1408 0151 0258 82<.342......Q.X
00000060: 0443 1100 4d11 0059 1100 4b11 00ff c400 .C..M..Y..K.....
00000070: 1f00 0001 0501 0101 0101 0100 0000 0000 ................
00000080: 0000 0001 0203 0405 0607 0809 0a0b ffc4 ................
00000090: 00b5 1000 0201 0303 0204 0305 0504 0400 ................
000000a0: 0001 7d01 0203 0004 1105 1221 3141 0613 ..}........!1A..
000000b0: 5161 0722 7114 3281 91a1 0823 42b1 c115 Qa."q.2....#B...
000000c0: 52d1 f024 3362 7282 090a 1617 1819 1a25 R..$3br........%
000000d0: 2627 2829 2a34 3536 3738 393a 4344 4546 &'()*456789:CDEF
000000e0: 4748 494a 5354 5556 5758 595a 6364 6566 GHIJSTUVWXYZcdef
000000f0: 6768 696a 7374 7576 7778 797a 8384 8586 ghijstuvwxyz....
00000100: 8788 898a 9293 9495 9697 9899 9aa2 a3a4 ................
00000110: a5a6 a7a8 a9aa b2b3 b4b5 b6b7 b8b9 bac2 ................
00000120: c3c4 c5c6 c7c8 c9ca d2d3 d4d5 d6d7 d8d9 ................
00000130: dae1 e2e3 e4e5 e6e7 e8e9 eaf1 f2f3 f4f5 ................
解决方案
问题在于两个 convert() 步骤。他们完全没有必要。
我从评论中得到了足够的线索,尝试直接在图像上绘图,而不是将其转换为 RGBA,然后再转换回 CMYK。我不知道我能做到这一点。文件大小现在更合理。
pi@raspberrypi:~ $ ll image*
-rw-r--r-- 1 pi pi 38283 Jul 10 00:29 image2.jpg
-rw-r--r-- 1 pi pi 101431 Jul 10 00:29 imageconv.jpg
-rw-r--r-- 1 pi pi 35873 Jul 9 03:15 image.jpg
-rw-r--r-- 1 pi pi 37363 Jul 10 00:29 imageopt.jpg
-rw-r--r-- 1 pi pi 50024 Jul 10 00:29 imageq85.jpg
-rw-r--r-- 1 pi pi 35856 Jul 10 00:29 imageresaved.jpg
修改后的代码(保留用于比较的故障排除图像):
def imageDecorate(event_dir, boxes):
source_image = event_dir + "/image.jpg"
dest_image = event_dir + "/image2.jpg"
dest_image3 = event_dir + "/imageq85.jpg"
dest_image4 = event_dir + "/imageopt.jpg"
dest_image5 = event_dir + "/imageconv.jpg"
dest_image6 = event_dir + "/imageresaved.jpg"
if not isfile(source_image):
return False
base = Image.open(source_image)
out3 = base.convert('CMYK')
out4 = Image.open(source_image)
# Draw rectangles and text label
draw = ImageDraw.Draw(base)
fnt = ImageFont.truetype("fonts/DejaVuSansMono.ttf", 12)
for box in boxes:
# Omitting irrelevant details. It's normal ImageDraw stuff ...
draw.rectangle( [...])
draw.rectangle( [...])
draw.rectangle( [...])
draw.text( [...] )
# Write to dest_image.
base.save(dest_image) # image2 - manipulated image
base.save(dest_image3, quality=85) # imageq85 - Expect it to be larger than image2
base.save(dest_image4, optimize=True) # imageopt - Expect it to be smaller than image2
out3.save(dest_image5) # imageconv - no editing, just convert -> RGBA -> CYMK
out4.save(dest_image6) # imageresaved - original image, resaved, no change
return True
推荐阅读
- javascript - JS,当一个数组与另一个数组有相同值时,通过映射进行过滤
- c# - 使用泛型'List
' 需要 1 个类型的参数” 当参数已经给出时 - jquery - 可排序不是一个函数 Jquery UI
- image - 我的任务是降低图像的空间分辨率,但画布大小必须在 MATLAB 中为新图像保持不变
- c# - C# LINQ 无法更新数据表值
- sql-server - 无法加载文件或程序集 Crystaldecisions.shared 或其依赖项之一
- puppeteer - 仅针对最新浏览器版本进行 E2E 测试有什么好处
- python - 熊猫:如何将值相加,仅当它们具有相同的数字时
- php - 如何在表单提交后显示的页面顶部添加“已发送消息”消息(现在不显示)?
- c - 如何使用 C 正则表达式提取子匹配