[GH-ISSUE #303] Incorrect image aspect ratio when image width exceeds column width #243

Closed
opened 2026-05-05 12:01:10 -06:00 by gitea-mirror · 17 comments
Owner

Originally created by @evanmiller on GitHub (Aug 19, 2020).
Original GitHub issue: https://github.com/jmcnamara/libxlsxwriter/issues/303

Originally assigned to: @jmcnamara on GitHub.

I'm not sure about the exact circumstances that produce this, but here is the code:

lxw_image_options options = {
    .x_offset = 1, .y_offset = 2,
    .x_scale = 0.5, .y_scale = 0.5,
    .object_position = LXW_OBJECT_MOVE_DONT_SIZE
};
worksheet_insert_image_buffer_opt(cws, excel_row, excel_col, data.bytes, data.length, &options);

The inserted PNG image is 140 x 140 @ 300dpi. However, the resulting XLSX scales the image down by different amounts along each axis:

xlsx

I notice that libxlsxwriter will correctly preserve aspect ratio if I decrease the image size below the column width, or increase the column width to exceed the image width.

I am not using constant_memory = true so I don't think this is a duplicate of #284.

Originally created by @evanmiller on GitHub (Aug 19, 2020). Original GitHub issue: https://github.com/jmcnamara/libxlsxwriter/issues/303 Originally assigned to: @jmcnamara on GitHub. I'm not sure about the exact circumstances that produce this, but here is the code: ```C lxw_image_options options = { .x_offset = 1, .y_offset = 2, .x_scale = 0.5, .y_scale = 0.5, .object_position = LXW_OBJECT_MOVE_DONT_SIZE }; worksheet_insert_image_buffer_opt(cws, excel_row, excel_col, data.bytes, data.length, &options); ``` The inserted PNG image is 140 x 140 @ 300dpi. However, the resulting XLSX scales the image down by different amounts along each axis: <img width="649" alt="xlsx" src="https://user-images.githubusercontent.com/134711/90664167-9da2b500-e218-11ea-9d8b-cc0867236b18.png"> I notice that libxlsxwriter will correctly preserve aspect ratio if I decrease the image size below the column width, or increase the column width to exceed the image width. I am *not* using `constant_memory` = true so I don't think this is a duplicate of #284.
Author
Owner

@jmcnamara commented on GitHub (Aug 19, 2020):

Can you attach the image so I can reproduce this.

<!-- gh-comment-id:676591103 --> @jmcnamara commented on GitHub (Aug 19, 2020): Can you attach the image so I can reproduce this.
Author
Owner

@evanmiller commented on GitHub (Aug 19, 2020):

image1

<!-- gh-comment-id:676593000 --> @evanmiller commented on GitHub (Aug 19, 2020): ![image1](https://user-images.githubusercontent.com/134711/90676084-67b9fc80-e229-11ea-9de0-61df6e774048.png)
Author
Owner

@jmcnamara commented on GitHub (Aug 19, 2020):

Also, I notice that the row height with the image is changed. Is that change implicit or explicit? See this section of the docs on Object scaling due to automatic row height adjustment for an explanation.

<!-- gh-comment-id:676593008 --> @jmcnamara commented on GitHub (Aug 19, 2020): Also, I notice that the row height with the image is changed. Is that change implicit or explicit? See this section of the docs on [Object scaling due to automatic row height adjustment](http://libxlsxwriter.github.io/working_with_object_positioning.html) for an explanation.
Author
Owner

@evanmiller commented on GitHub (Aug 19, 2020):

Row height is set programmatically:

worksheet_set_row(cws, excel_row, LXW_DEF_ROW_HEIGHT * 5, NULL);

There is text in the row but it is the standard font and does not wrap.

<!-- gh-comment-id:676594263 --> @evanmiller commented on GitHub (Aug 19, 2020): Row height is set programmatically: ```C worksheet_set_row(cws, excel_row, LXW_DEF_ROW_HEIGHT * 5, NULL); ``` There is text in the row but it is the standard font and does not wrap.
Author
Owner

@jmcnamara commented on GitHub (Aug 19, 2020):

Attaching file created in Excel for reference: gh303_excel.xlsx

<!-- gh-comment-id:676614141 --> @jmcnamara commented on GitHub (Aug 19, 2020): Attaching file created in Excel for reference: [gh303_excel.xlsx](https://github.com/jmcnamara/libxlsxwriter/files/5098805/gh303_excel.xlsx)
Author
Owner

@jmcnamara commented on GitHub (Aug 19, 2020):

I've seen this issue before. It seems to affect Excel on macOS. For example the file gh303_excel.xlsx above was created in Excel 2007 on a Windows VM. In Excel 2011 and Excel 2016/365 for macOS it shows the scaling issue you report:

Screenshot 2020-08-19 at 20 43 06

However with Excel 2015/365 on another Windows machine it looks fine:

aa_image

<!-- gh-comment-id:676624544 --> @jmcnamara commented on GitHub (Aug 19, 2020): I've seen this issue before. It seems to affect Excel on macOS. For example the file gh303_excel.xlsx above was created in Excel 2007 on a Windows VM. In Excel 2011 and Excel 2016/365 for macOS it shows the scaling issue you report: ![Screenshot 2020-08-19 at 20 43 06](https://user-images.githubusercontent.com/94267/90682261-9bfae080-e25c-11ea-9b1c-bad293fc6790.png) However with Excel 2015/365 on another Windows machine it looks fine: ![aa_image](https://user-images.githubusercontent.com/94267/90682964-b71a2000-e25d-11ea-8d91-ad659d06cad4.png)
Author
Owner

@jmcnamara commented on GitHub (Aug 19, 2020):

I don't know what causes this. Libxlsxwriter duplicates the Excel 2007 behaviour and there are currently 84 test cases to ensure that it matches Excel for a range of different images in different positions and scales.

Maybe you can verify the behaviour yourself by creating an Excel file with an image on a Windows machine and transferring it to Excel on the mac.

I also found this explanation from MS on the difference between image on Windows and Mac versions of Excel: https://answers.microsoft.com/en-us/msoffice/forum/all/size-of-images-changes-mac-windows/cc9009dc-27d4-4620-8649-514881bb9e3a

But in summary, I've been over this in the past and I don't think that I can fix this in libxlsxwriter.

<!-- gh-comment-id:676632897 --> @jmcnamara commented on GitHub (Aug 19, 2020): I don't know what causes this. Libxlsxwriter duplicates the Excel 2007 behaviour and there are currently 84 test cases to ensure that it matches Excel for a range of different images in different positions and scales. Maybe you can verify the behaviour yourself by creating an Excel file with an image on a Windows machine and transferring it to Excel on the mac. I also found this explanation from MS on the difference between image on Windows and Mac versions of Excel: https://answers.microsoft.com/en-us/msoffice/forum/all/size-of-images-changes-mac-windows/cc9009dc-27d4-4620-8649-514881bb9e3a But in summary, I've been over this in the past and I don't think that I can fix this in libxlsxwriter.
Author
Owner

@evanmiller commented on GitHub (Aug 19, 2020):

There's some strange trigger with the column width - in certain ranges, shrinking the column produces the correct aspect ratio. I wonder if there's some kind of "snap to cell width" logic when the right image border is close to a cell border.

<!-- gh-comment-id:676663187 --> @evanmiller commented on GitHub (Aug 19, 2020): There's some strange trigger with the column width - in certain ranges, shrinking the column produces the correct aspect ratio. I wonder if there's some kind of "snap to cell width" logic when the right image border is close to a cell border.
Author
Owner

@jmcnamara commented on GitHub (Aug 19, 2020):

@evanmiller Ok. If you create a test case with the sample above I will look into it.

<!-- gh-comment-id:676738706 --> @jmcnamara commented on GitHub (Aug 19, 2020): @evanmiller Ok. If you create a test case with the sample above I will look into it.
Author
Owner

@evanmiller commented on GitHub (Aug 20, 2020):

If your test file opens on Windows OK, then I'm willing to chalk it up to a Microsoft bug. It's a frustrating one, though!

<!-- gh-comment-id:676837053 --> @evanmiller commented on GitHub (Aug 20, 2020): If your test file opens on Windows OK, then I'm willing to chalk it up to a Microsoft bug. It's a frustrating one, though!
Author
Owner

@jmcnamara commented on GitHub (Aug 20, 2020):

It's a frustrating one, though!

It is. Especially since any differences in image scaling are immediately visible. It is doing the same thing for other worksheet objects such as charts and buttons but those changes aren't obvious. It is also frustrating since I put a lot of reverse-engineering work into matching Excel's behaviour on Windows.

Since there is nothing that I can do here I'm going to close this.

<!-- gh-comment-id:677932392 --> @jmcnamara commented on GitHub (Aug 20, 2020): > It's a frustrating one, though! It is. Especially since any differences in image scaling are immediately visible. It is doing the same thing for other worksheet objects such as charts and buttons but those changes aren't obvious. It is also frustrating since I put a lot of reverse-engineering work into matching Excel's behaviour on Windows. Since there is nothing that I can do here I'm going to close this.
Author
Owner

@bdkjones commented on GitHub (Apr 6, 2024):

Just chiming in to say this is still an issue in 2024. I have exactly the same problem: if I insert an image such that its right edge is "too close" to a column, the image's aspect ratio is mutilated and it "snaps" to the column boundary.

The only solution I've found is to make the column much wider than necessary.

The same behavior manifests when the *.xlsx file is opened in Apple Numbers. Clicking "original size" in the image inspector within Numbers restores the correct aspect ratio.

<!-- gh-comment-id:2041231767 --> @bdkjones commented on GitHub (Apr 6, 2024): Just chiming in to say this is still an issue in 2024. I have exactly the same problem: if I insert an image such that its right edge is "too close" to a column, the image's aspect ratio is mutilated and it "snaps" to the column boundary. The only solution I've found is to make the column much wider than necessary. The same behavior manifests when the *.xlsx file is opened in Apple Numbers. Clicking "original size" in the image inspector within Numbers restores the correct aspect ratio.
Author
Owner

@bdkjones commented on GitHub (Apr 7, 2024):

After hours of fighting, I've settled on a (very clunky) workaround.

The spreadsheet I'm building has a column of images, each of which SHOULD be a 16:9 (1.77777) aspect ratio. But if I size the images such that their right edge is closer than roughly 20 pixels to the right border of the cell, the aspect ratio is distorted—but distorted in a predictable fashion.

The images' aspect ratio ends up at 2.002. So in my lxw_image_options, I just supply a yScale factor to correct this nonsense and leave the xScale factor at 1.0. The image is still "snapped" to the cell width, but I can now ensure that it retains the correct aspect ratio when that happens.

I haven't tested the resulting spreadsheets on Excel for Windows. Microsoft never really got into high-resolution screens like Apple did, so I'm not shocked there's a bunch of weirdness or that they rely on 72 and 96 DPI.

<!-- gh-comment-id:2041309106 --> @bdkjones commented on GitHub (Apr 7, 2024): After hours of fighting, I've settled on a (very clunky) workaround. The spreadsheet I'm building has a column of images, each of which SHOULD be a 16:9 (1.77777) aspect ratio. But if I size the images such that their right edge is closer than roughly 20 pixels to the right border of the cell, the aspect ratio is distorted—*but distorted in a predictable fashion*. The images' aspect ratio ends up at 2.002. So in my `lxw_image_options`, I just supply a `yScale` factor to correct this nonsense and leave the `xScale` factor at `1.0`. The image is still "snapped" to the cell width, but I can now ensure that it retains the correct aspect ratio when that happens. I haven't tested the resulting spreadsheets on Excel for Windows. Microsoft never really got into high-resolution screens like Apple did, so I'm not shocked there's a bunch of weirdness or that they rely on 72 and 96 DPI.
Author
Owner

@slw287r commented on GitHub (Apr 7, 2024):

I've similar workaround when the cell height is more than expected if I specify monospace font such as "Courier New" for multiple-line string set to align vertically top by the format LXW_ALIGN_VERTICAL_TOP.

The trick is to make the row height slightly smaller:

worksheet_set_row(worksheet, row_number, LXW_DEF_ROW_HEIGHT / 1.001, NULL);
<!-- gh-comment-id:2041357767 --> @slw287r commented on GitHub (Apr 7, 2024): I've similar workaround when the cell height is more than expected if I specify monospace font such as "Courier New" for multiple-line string set to align vertically top by the format `LXW_ALIGN_VERTICAL_TOP`. The trick is to make the row height slightly smaller: ``` worksheet_set_row(worksheet, row_number, LXW_DEF_ROW_HEIGHT / 1.001, NULL); ```
Author
Owner

@jmcnamara commented on GitHub (Apr 7, 2024):

Just chiming in to say this is still an issue in 2024. I have exactly the same problem: if I insert an image such that its right edge is "too close" to a column, the image's aspect ratio is mutilated and it "snaps" to the column boundary.

Folks, I understand the frustration here but I need to reiterate that this isn't a libxlsxwriter issue, it is a Mac/Windows Excel issue. This is easily reproducible outside of libxlsxwriter and the link above https://github.com/jmcnamara/libxlsxwriter/issues/303#issuecomment-676632897 shows that general Excel users also encounter this issue.

For cases where the image is in a single cell it should be resolved by Excel's newer embedded image option that I will implement as part of #417.

<!-- gh-comment-id:2041503934 --> @jmcnamara commented on GitHub (Apr 7, 2024): > Just chiming in to say this is still an issue in 2024. I have exactly the same problem: if I insert an image such that its right edge is "too close" to a column, the image's aspect ratio is mutilated and it "snaps" to the column boundary. Folks, I understand the frustration here but I need to reiterate that this isn't a libxlsxwriter issue, it is a Mac/Windows Excel issue. This is easily reproducible outside of libxlsxwriter and the link above https://github.com/jmcnamara/libxlsxwriter/issues/303#issuecomment-676632897 shows that general Excel users also encounter this issue. For cases where the image is in a single cell it should be resolved by Excel's newer embedded image option that I will implement as part of #417.
Author
Owner

@bdkjones commented on GitHub (Apr 7, 2024):

I should have been more clear: it's still an issue with Excel. I was simply posting my workaround in case it helps others who encounter the problem.

<!-- gh-comment-id:2041532869 --> @bdkjones commented on GitHub (Apr 7, 2024): I should have been more clear: it's still an issue with Excel. I was simply posting my workaround in case it helps others who encounter the problem.
Author
Owner

@bdkjones commented on GitHub (Apr 7, 2024):

@jmcnamara This thread is a weird place for the discussion, but the Rust version of libxlxswriter has just a fraction of the interest that the C and Python versions have (although the Rust repo is likely newer, so there's an age bias).

I don't have any experience with Rust, but I understand it can be compiled to a static C library. That would make it much more useable for app developers and would also obviate the need to maintain the C version of libxlsxwriter, which frees up your time.

Perhaps that's a better way forward than maintaining the library in triplicate?

<!-- gh-comment-id:2041575980 --> @bdkjones commented on GitHub (Apr 7, 2024): @jmcnamara This thread is a weird place for the discussion, but the Rust version of libxlxswriter has just a fraction of the interest that the C and Python versions have (although the Rust repo is likely newer, so there's an age bias). I don't have any experience with Rust, but I understand it can be compiled to a static C library. That would make it much more useable for app developers and would also obviate the need to maintain the C version of libxlsxwriter, which frees up your time. Perhaps that's a better way forward than maintaining the library in triplicate?
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: github-starred/libxlsxwriter#243
No description provided.