Hacktoberfest 2026:メンテナが10月に向けて印を付けた、オープンで初心者向けの issue。 Hacktoberfest の issue を見る

JPEG saved with keep_rgb=True and dpi reopens with incorrect colors

オープン
#10,344 コメント 0 件 リアクション 0 件 担当者 0 名 GitHub で見る

メンテナーはふだん 1 日以内に返信

@Muguett-DBY がすでに取り組んでいます。

2026年10月28日 から。

  • #10345 @Muguett-DBY による — オープン

評価

難易度
4/5
見積もり時間
1〜2日
初心者へのやさしさ
25/100
issue の種類
バグ
明瞭さ
おおむね明確
活発さ
停滞
技術スタック
c, python
領域
backend

調査の方向性

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 の本文から書いたものです。

説明

🤖-assisted JPEG
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日 3時間
マージ済み PR(30日)
174

環境構築

はじめの一歩

  1. issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
  2. 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
  3. リポジトリをフォークし、ブランチを切って変更します。
  4. issue 番号を参照したプルリクエストを送ります。

python-pillow/Pillow のほかの issue

python-pillow/Pillow の issue をすべて見る

似ている issue

Python の issue をもっと見る

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。