JPEG saved with keep_rgb=True and dpi reopens with incorrect colors
维护者通常 1 天内回复
评估
调研方向
Start with the JPEG encoder path in src/libImaging/JpegEncode.c and the decoder’s color-space selection; the issue links both relevant code locations and cites libjpeg-turbo’s default selection. Compare JPEGs saved with and without DPI and keep_rgb=True, then run the reproducer in the issue. Done means both files reopen with approximately red pixels while retaining the requested DPI behavior; pull request #10345 is already open.
由索引模型根据 Issue 内容生成。
描述
What did you do?
Saved the same RGB image to JPEG with keep_rgb=True, once with DPI and once without it, then reopened both files:
from io import BytesIO
from PIL import Image
image = Image.new("RGB", (16, 16), (255, 0, 0))
for dpi in (None, (72, 72)):
out = BytesIO()
options = {"keep_rgb": True, "quality": 100, "subsampling": 0}
if dpi is not None:
options["dpi"] = dpi
image.save(out, "JPEG", **options)
out.seek(0)
with Image.open(out) as reopened:
print(dpi, reopened.getpixel((0, 0)))
What did you expect to happen?
Both images should reopen approximately red. Setting DPI should not visibly change the colors.
What actually happened?
On both installations below, the output was:
None (255, 0, 0)
(72, 72) (76, 255, 28)
The DPI version contains both a JFIF APP0 marker and an Adobe APP14 marker with transform 0; the version without DPI contains only the Adobe marker. As a diagnostic, removing the JFIF marker from the generated bytes made Pillow reopen the pixel as (255, 0, 0), but also removed the DPI. I don't know whether the right fix is in the writer, the reader, or both.
FFmpeg 9.0.2 decodes both generated JPEGs as (255, 0, 0) on the same machine. This suggests a difference in decoding the DPI version; I have not isolated the responsible layer.
The generated file has component IDs R, G and B. As a diagnostic, forcing the low-level JPEG decoder input mode to RGB also restores the expected red in both Pillow versions.
Looking at libjpeg-turbo 3.2.0, its default color-space selection gives the JFIF marker precedence over Adobe APP14, selecting YCbCr when both are present. Pillow enables JFIF when both DPI values are positive.
#7679 notes that setting DPI forces JFIF even for non-JFIF color spaces. The JPEG encoder source is identical between the 13.0.0 tag and current main, although I haven't built main to reproduce this there.
What are your OS, Python and Pillow versions?
- Windows 11, Python 3.15.2, Pillow 13.0.0, libjpeg-turbo 3.2.0.
- Also reproduced with Python 3.12.14, Pillow 12.3.0, libjpeg-turbo 3.1.4.1.
Reproducer and investigation assisted by Codex.
- 主要语言
- Python
- 星标
- 13.9k
- 派生
- 2.6k
- 平均合并
- 1 天 7 小时
- 30 天内合并 PR
- 174
环境准备
- 没有 Dockerfile 或 Docker Compose 文件
- 有 Pull Request 模板
- 阅读贡献指南
从这里开始
- 先读完整个 Issue,再读项目的贡献指南。
- 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
- Fork 仓库,在一个分支上完成修改。
- 提交 Pull Request,并在描述里引用这个 Issue 编号。
python-pillow/Pillow 的其他 Issue
-
TIFF without XResolution/YResolution reports dpi (1, 1)可能已有人在做 @brettdavies 于 2 天前认领。 未关闭🤖-assisted TIFF
难度 2/5 1-3 小时 新手友好度 75/100
python-pillow/Pillow#10332 · 2 条评论 ·
维护者通常 1 天内回复
-
Warn that pre-applying arabic_reshaper + python-bidi corrupts text on a Raqm build可能已有人在做 @Syamjith-NK 于 61 天前认领。 未关闭Documentation Font Rendering PNG Third Party Framework
难度 2/5 1-3 小时 新手友好度 78/100
python-pillow/Pillow#9907 · 2 条评论 ·
维护者通常 1 天内回复
-
Image.putpixel incorrectly labels supported arguments in type annotations可能已有人在做 @radarhere 于 189 天前认领。 未关闭PNG
难度 2/5 1-3 小时 新手友好度 70/100
python-pillow/Pillow#9584 · 1 条评论 ·
维护者通常 1 天内回复
-
JPEG dpi read from EXIF uses XResolution for both axes可能已有人在做 @unvisible789 于 2 天前认领。 未关闭
难度 2/5 1-3 小时 新手友好度 20/100
python-pillow/Pillow#10331 · 1 条评论 ·
维护者通常 1 天内回复
-
16-bit PNG tRNS key: convert("RGBA") misses the keyed pixel and makes another transparent可能已有人在做 关联的 PR 仍在进行中或已合并。 未关闭Conversion
难度 3/5 1-2 天 新手友好度 58/100
python-pillow/Pillow#10330 · 3 条评论 ·
维护者通常 1 天内回复
查看 python-pillow/Pillow 的全部 Issue
相似的 Issue
-
Context/namespace resources fail in-cluster: "Invalid kube-config file. No configuration found."未关闭
难度 2/5 1-3 小时 新手友好度 76/100
-
bug documentation
难度 1/5 1 小时以内 新手友好度 88/100
awslabs/visual-asset-management-system#880 ·
维护者通常 1 天内回复
-
netbox status: needs owner type: documentation
难度 2/5 1-3 小时 新手友好度 74/100
netbox-community/netbox#23533 ·
维护者通常 1 天内回复
-
app: scripts status: backlog type: documentation
难度 2/5 1-3 小时 新手友好度 86/100
netbox-community/netbox-scripts#68 ·
维护者通常 1 天内回复
-
难度 1/5 1 小时以内 新手友好度 91/100
marin-community/marin#10765 ·
维护者通常 1 天内回复