diff --git a/html2docx/image.py b/html2docx/image.py
index a8465aa..bedbc32 100644
--- a/html2docx/image.py
+++ b/html2docx/image.py
@@ -16,6 +16,7 @@
# In LibreOffice, the maximum height for an image is capped to USABLE_HEIGHT.
USABLE_HEIGHT = Inches(8.1)
USABLE_WIDTH = Inches(5.8)
+DEFAULT_DPI = 72
MAX_IMAGE_SIZE = 10 * 1024 * 1024 # 10 MiB
@@ -104,11 +105,23 @@ def image_size(
"""
image = Image.from_blob(image_buffer.getbuffer())
- height = image.px_height if height_px is None else height_px
- width = image.px_width if width_px is None else width_px
+ # Normalize image size to inches.
+ # - Without a specified pixel size, images are their actual pixel size, so that
+ # images of the same pixel size appear the same size in the document, regardless
+ # of their resolution.
+ # - With a specified pixel size, images should take the specified size, regardless
+ # of their resolution.
+ if height_px is None:
+ height = image.px_height / image.vert_dpi
+ else:
+ height = height_px / DEFAULT_DPI
+ if width_px is None:
+ width = image.px_width / image.horz_dpi
+ else:
+ width = width_px / DEFAULT_DPI
- height = Inches(height / image.vert_dpi)
- width = Inches(width / image.horz_dpi)
+ height = Inches(height)
+ width = Inches(width)
size = {}
if width > USABLE_WIDTH:
diff --git a/tests/data/img_height.json b/tests/data/img_height.json
index 182d0c7..631469e 100644
--- a/tests/data/img_height.json
+++ b/tests/data/img_height.json
@@ -7,8 +7,8 @@
"shapes": [
{
"type": 3,
- "width": 2857500,
- "height": 2857500
+ "width": 3810000,
+ "height": 3810000
}
]
}
diff --git a/tests/data/img_ratio.json b/tests/data/img_ratio.json
index 9f09d34..c901760 100644
--- a/tests/data/img_ratio.json
+++ b/tests/data/img_ratio.json
@@ -7,8 +7,8 @@
"shapes": [
{
"type": 3,
- "width": 190500,
- "height": 95250
+ "width": 254000,
+ "height": 127000
}
]
}
diff --git a/tests/data/img_width.json b/tests/data/img_width.json
index 182d0c7..631469e 100644
--- a/tests/data/img_width.json
+++ b/tests/data/img_width.json
@@ -7,8 +7,8 @@
"shapes": [
{
"type": 3,
- "width": 2857500,
- "height": 2857500
+ "width": 3810000,
+ "height": 3810000
}
]
}
diff --git a/tests/test_image_size.py b/tests/test_image_size.py
index 6f663fd..71a936d 100644
--- a/tests/test_image_size.py
+++ b/tests/test_image_size.py
@@ -2,19 +2,19 @@
from docx.shared import Inches
-from html2docx.image import USABLE_HEIGHT, USABLE_WIDTH, image_size
+from html2docx.image import DEFAULT_DPI, USABLE_HEIGHT, USABLE_WIDTH, image_size
-from .utils import DPI, PROJECT_DIR, generate_image
+from .utils import PROJECT_DIR, generate_image
broken_image = PROJECT_DIR / "html2docx" / "image-broken.png"
broken_image_bytes = broken_image.read_bytes()
-def inches_to_px(inches: int, dpi: int = DPI) -> int:
+def inches_to_px(inches: int, dpi: int = DEFAULT_DPI) -> int:
return ceil(inches / Inches(1) * dpi)
-def px_to_inches(px: int, dpi: int = DPI) -> int:
+def px_to_inches(px: int, dpi: int = DEFAULT_DPI) -> int:
return ceil(px * Inches(1) / dpi)
@@ -77,15 +77,29 @@ def test_resize_exceeds_height():
assert size == {"height": USABLE_HEIGHT}
-def test_dpi_width():
+def test_no_pixel_size_uses_dpi_width():
width_px = inches_to_px(USABLE_WIDTH, 300)
image = generate_image(width=width_px, height=1, dpi=(300, 300))
size = image_size(image)
assert size == {}
-def test_dpi_height():
+def test_no_pixel_size_uses_dpi_height():
height_px = inches_to_px(USABLE_HEIGHT, 300)
image = generate_image(width=1, height=height_px, dpi=(300, 300))
size = image_size(image)
assert size == {}
+
+
+def test_pixel_size_specified_ignores_dpi_width():
+ width_px = inches_to_px(Inches(1))
+ image = generate_image(width=width_px, height=1, dpi=(300, 300))
+ size = image_size(image, width_px=width_px)
+ assert size == {"width": Inches(1)}
+
+
+def test_pixel_size_specified_ignores_dpi_height():
+ height_px = inches_to_px(Inches(1))
+ image = generate_image(width=1, height=height_px, dpi=(300, 300))
+ size = image_size(image, height_px=height_px)
+ assert size == {"height": Inches(1)}
diff --git a/tests/utils.py b/tests/utils.py
index 13b9df8..3c22b0d 100644
--- a/tests/utils.py
+++ b/tests/utils.py
@@ -3,12 +3,13 @@
from PIL import Image
+from html2docx.image import DEFAULT_DPI
+
TEST_DIR = pathlib.Path(__file__).parent.resolve(strict=True)
PROJECT_DIR = TEST_DIR.parent
-DPI = 72
-def generate_image(width: int, height: int, dpi=(DPI, DPI)) -> BytesIO:
+def generate_image(width: int, height: int, dpi=(DEFAULT_DPI, DEFAULT_DPI)) -> BytesIO:
data = BytesIO()
with Image.new("L", (width, height)) as image:
image.save(data, format="png", dpi=dpi)