Skip to content

[google_maps_flutter] Fix markers NPOT sampling issue for IOS#11711

Open
cuteUtya wants to merge 1 commit into
flutter:mainfrom
cuteUtya:pot-sapling-fix-185742
Open

[google_maps_flutter] Fix markers NPOT sampling issue for IOS#11711
cuteUtya wants to merge 1 commit into
flutter:mainfrom
cuteUtya:pot-sapling-fix-185742

Conversation

@cuteUtya
Copy link
Copy Markdown

@cuteUtya cuteUtya commented May 14, 2026

This PR fixes bug explained in this issue

  • Fixes incorrect or swapped custom marker icons on iOS when decoded bitmaps or target sizes
    are not power-of-two

Expected behavior:
Screenshot 2026-05-14 at 12 45 30

Actual behavior (before PR):
image

Pre-Review Checklist

If you need help, consider asking for advice on the #hackers-new channel on Discord.

Note: The Flutter team is currently trialing the use of Gemini Code Assist for GitHub. Comments from the gemini-code-assist bot should not be taken as authoritative feedback from the Flutter team. If you find its comments useful you can update your code accordingly, but if you are unsure or disagree with the feedback, please feel free to wait for a Flutter team member's review for guidance on which automated comments should be addressed.

Footnotes

  1. Regular contributors who have demonstrated familiarity with the repository guidelines only need to comment if the PR is not auto-exempted by repo tooling. 2

Copy link
Copy Markdown

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request updates the iOS Google Maps plugin to address issues with custom marker icons by padding them to the next power-of-two size. The changes include a new utility function for power-of-two calculations and updated image scaling logic in FGMImageUtils.m, along with corresponding test updates. Review feedback identifies a potential orientation bug and notes that padding the image will cause marker anchor displacement. It was also suggested to return the original image directly when it is already a power-of-two size to avoid unnecessary object creation.

return image;
}

return [UIImage imageWithCGImage:potCGImage scale:image.scale orientation:image.imageOrientation];
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

There are two significant issues with this return statement:

  1. Orientation Bug: The potCGImage was created by drawing the original image into a context via drawInRect:, which already handles the image's orientation. The resulting bitmap is already in the 'Up' orientation. Re-applying image.imageOrientation here will cause the orientation to be applied a second time, leading to incorrectly rotated markers if the source image had orientation metadata (e.g., from EXIF).
  2. Anchor Displacement: Padding the image to a power-of-two size changes the logical dimensions of the UIImage. Since marker anchors in the Google Maps SDK are normalized (0.0 to 1.0) relative to the image size, this change will cause markers to be misaligned on the map. For example, a 20x20 icon padded to 32x32 with a bottom-center anchor (0.5, 1.0) will now be anchored at (16, 32) instead of (10, 20) relative to the artwork. To fix this, the plugin would need to adjust the marker's groundAnchor to compensate for the padding.
Suggested change
return [UIImage imageWithCGImage:potCGImage scale:image.scale orientation:image.imageOrientation];
return [UIImage imageWithCGImage:potCGImage scale:image.scale orientation:UIImageOrientationUp];

Comment on lines +215 to 219
if (alreadyPOT) {
return [UIImage imageWithCGImage:existingCGImage
scale:image.scale
orientation:image.imageOrientation];
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

If the image is already at the target power-of-two size, you can return the original image directly instead of creating a new UIImage instance from the same CGImage.

  if (alreadyPOT) {
    return image;
  }

@cuteUtya
Copy link
Copy Markdown
Author

Apologies in advance if I made some guideline mistakes; I rarely contribute to open-source. However, google_maps_flutter is vital to my work, and I've encountered other similar issues with markers functionality in the past (that was resolved by contributors is past years)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant