-
-
Notifications
You must be signed in to change notification settings - Fork 2.4k
Closed
Description
What did you do?
I ran the attached code to resize, and then save an image from URL; I checked using a jupyter notebook and at various stages the image seems fine, so it seems to be saving code, with optimize=True which causes the issue.
What did you expect to happen?
Image resized, without artifacts
What actually happened?
Artifacts in the image. Unsure why.
What are your OS, Python and Pillow versions?
- OS: MacOS
- Python: 3.11.6
- Pillow: 10.1.0
Code to download an image, process it as 128x128 and save it
import base64
import io
from pathlib import Path
from typing import Tuple
import requests
from PIL import Image
EXIF_ORIENTATION_BYTE_OFFSET = 0x0112
url = "http://localhost:8080/13246.png"
s = requests.Session()
response = s.get(url, timeout=10)
image_file = io.BytesIO(response.content)
def make_white_copy(image: Image, background_color: Tuple[int, int, int]=(255, 255, 255)) -> Image:
"""Ensure we get correct background when cropping image."""
width = image.width
height = image.height
is_landscape = width > height
is_portrait = height > width
x_pos = 0
y_pos = 0
if width != height:
if is_landscape:
desired_width = width
desired_height = int(height * (width / height))
x_pos = 0
y_pos = int((desired_width - height) / 2)
elif is_portrait:
desired_width = int(width * (height / width))
desired_height = height
x_pos = int((desired_height - width) / 2)
y_pos = 0
new_img = Image.new("RGB", (desired_width, desired_height), background_color)
new_img.paste(image, (x_pos, y_pos))
return new_img
def transpose_by_exif(image: Image) -> Image:
"""Use exif data if present to perform action on image."""
orientation = image.getexif().get(EXIF_ORIENTATION_BYTE_OFFSET)
if orientation is not None and orientation > 1:
transposition_action = {
2: Image.FLIP_LEFT_RIGHT,
3: Image.ROTATE_180,
4: Image.FLIP_TOP_BOTTOM,
5: Image.TRANSPOSE,
6: Image.ROTATE_270,
7: Image.TRANSVERSE,
8: Image.ROTATE_90,
}.get(orientation)
image = image.transpose(transposition_action)
return image
def resize(image: Image) -> Image:
"""Resize Image to dimensions."""
size = (128, 128)
image.thumbnail(size)
return image
saved_image = None
img = Image.open(image_file)
managed_image = resize(make_white_copy(img))
with Path.open("/Users/lewiscowles/Desktop/13246.jpg", "w") as out:
managed_image.save(
out,
"JPEG",
optimize=True,
quality=100,
jfif_unit=1,
dpi=(96, 96),
jfif_density=(96, 96),
)

