react-native-vector-icons
react-native-vector-icons copied to clipboard
[Bug] Android's getImageSource returning cropped images
- [x] Review the documentation: https://github.com/oblador/react-native-vector-icons
- [x] Search for existing issues (including closed issues): https://github.com/oblador/react-native-vector-icons/issues
Environment
RN: 0.59.10 react-native-vector-icons: 6.6.0 Target platform: Android
Description
For our app that uses react-native-navigation, we are required to pass images to be used as icons for our bottomTabs. A very common approach is to use this library's getImageSource function to generate the images. It seems that certain icons are not being generated correctly. Initially I thought it was related to FontAwesome 5 icons which we recently upgraded to but we are not the only ones running into it. (https://github.com/wix/react-native-navigation/issues/4931) and additionally it works perfectly on iOS.
I dove into the code myself, messing around with the getImageForFont Android function (https://github.com/oblador/react-native-vector-icons/blob/master/android/src/main/java/com/oblador/vectoricons/VectorIconsModule.java#L43)
But my knowledge is very limited when it comes to Fonts and how Android's paint and canvas work. It seems that SVG's that have a width bigger than height are being cropped incorrectly.
Reproducible Demo
I have confirmed this by doing the following:
loadedIconSource['fa-inbox'] = await FontAwesome.getImageSource('inbox', 24, undefined, FA5Style.solid);
And then using RN's Image component to render it, (using resizeMode contain to make sure we don't crop it):
<Image source={loadedIconSource['fa-inbox']} resizeMode="contain" style={{ height: 84, width: 84 }} />
Result is:
How it should look like: https://fontawesome.com/icons/inbox?style=regular
Having the same issue with Ionicons.
I've resolved for now by patching a line inside android/src/main/java/com/oblador/vectoricons/VectorIconsModule.java
:
i̶n̶t̶ ̶o̶f̶f̶s̶e̶t̶X̶ ̶=̶ ̶0̶;̶
int offsetX = (size / 2) - ((int) paint.measureText(glyph) / 2);
Haven't tested with other icon packs tho.
Hello @LRNZ09 , can you submit a pull request to that the problem is fixed for everyone?
@marf I don't think @LRNZ09 's solution is correct. It doesn't fix the icon I mentioned in the issue.
@oblador any progress with that?
Same issue here with FA5 icons - works great on iOS, but off-centered or cropped on Android (using RNN bottom tabs).
Has anyone had any luck with a solution yet?
I will try @LRNZ09 's solution in the meantime.
Based on @LRNZ09 's original suggestion, I am using the following change to VectorIconsModule.java:
int textWidth = textBounds.width() + 1;
int textHeight = textBounds.height() + 1;
int width = Math.max(size, textWidth);
int height = Math.max(size, textHeight);
int offsetX = (width / 2) - (textWidth / 2);
int offsetY = height - (int) paint.getFontMetrics().bottom;
Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
canvas.drawText(glyph, offsetX, offsetY, paint);
Haven't spent much time trying to optimize, but this at least allows me to move forward without cropped icons using FA5 for now. Just posting in case it may help others.
Sooooo, guys you can try to rollback this commit.
https://github.com/oblador/react-native-vector-icons/commit/4b3c6ae2babfe63e889a33aead8534243a4bcccf
@3luyka that works perfect for me (again using FA5 Pro). @oblador any chance this could be done? Thanks!
Also seeing good results when rolling back commit: https://github.com/oblador/react-native-vector-icons/commit/4b3c6ae2babfe63e889a33aead8534243a4bcccf
i also have this issue.
I'm also having this issue
Any news?
We ended up using 'patch-package' to effectively roll back the commit previously mentioned at build time. Had to go that route since this issue isn't gaining any traction here. Works fine now.
The rollback of the commit 4b3c6ae does not work for me. Any other ideas?
Any updates on this, guys? I am also experiencing this issue.
The rollback does not resolve the issue for me. any updates?
@hampustagerud any updates on that?
It looks like the fix is finally included in master after the getImageSourceSync PR was merged in early July, so I suppose this pull request can finally be closed.
Better late than never, so thanks guys :+1:
@vrgimael That's not the fix... That's the commit that broke this in the first place...
@vrgimael @ItsNoHax , can canfirm @ItsNoHax words. Reverting patch solves the problem for me
None of the fixes are working for me, I have tried patching to the commit prior to the fix but that seems to be incompatible with the latest RN versions, I don't understand how anyone has patch-packaged (as in other forums) this since the fix lies in Java and not JS . Why is there no attempt to apply and merge the fix? This has been an issue for over 2 years now...
@jwh-hutchison I'm using latest version of package, what I mean by patching is applying patch on postinstall stage. First I have patch file:
74,77c74
< int offsetX = 0;
< int offsetY = size - (int) paint.getFontMetrics().bottom;
<
< Bitmap bitmap = Bitmap.createBitmap(size, size, Bitmap.Config.ARGB_8888);
---
> Bitmap bitmap = Bitmap.createBitmap(textBounds.width(), textBounds.height(), Bitmap.Config.ARGB_8888);
79c76
< canvas.drawText(glyph, offsetX, offsetY, paint);
---
> canvas.drawText(glyph, -textBounds.left, -textBounds.top, paint);
(you can copy and save it as .patch file, I saved it as patches/VectorIconsModule.java.patch)
Then I apply patch on postinstall stage:
patch -s -r /tmp/delete.rej --forward node_modules/react-native-vector-icons/android/src/main/java/com/oblador/vectoricons/VectorIconsModule.java patches/VectorIconsModule.java.patch
Yeah, a bit dirty, but works.