react-native-vector-icons icon indicating copy to clipboard operation
react-native-vector-icons copied to clipboard

[Bug] Android's getImageSource returning cropped images

Open ItsNoHax opened this issue 4 years ago • 22 comments

  • [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: Selection_018

How it should look like: https://fontawesome.com/icons/inbox?style=regular

ItsNoHax avatar Jul 31 '19 13:07 ItsNoHax

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.

LRNZ09 avatar Jul 31 '19 13:07 LRNZ09

Hello @LRNZ09 , can you submit a pull request to that the problem is fixed for everyone?

marf avatar Aug 08 '19 17:08 marf

@marf I don't think @LRNZ09 's solution is correct. It doesn't fix the icon I mentioned in the issue.

ItsNoHax avatar Aug 09 '19 12:08 ItsNoHax

@oblador any progress with that?

3luyka avatar Aug 23 '19 16:08 3luyka

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.

techericb avatar Sep 04 '19 15:09 techericb

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.

techericb avatar Sep 04 '19 17:09 techericb

Sooooo, guys you can try to rollback this commit.

https://github.com/oblador/react-native-vector-icons/commit/4b3c6ae2babfe63e889a33aead8534243a4bcccf

3luyka avatar Sep 17 '19 16:09 3luyka

@3luyka that works perfect for me (again using FA5 Pro). @oblador any chance this could be done? Thanks!

techericb avatar Sep 17 '19 21:09 techericb

Also seeing good results when rolling back commit: https://github.com/oblador/react-native-vector-icons/commit/4b3c6ae2babfe63e889a33aead8534243a4bcccf

ItsNoHax avatar Sep 18 '19 12:09 ItsNoHax

i also have this issue.

djschilling avatar Oct 10 '19 22:10 djschilling

I'm also having this issue

edferreira avatar Oct 24 '19 21:10 edferreira

Any news?

vrgimael avatar Jan 24 '20 17:01 vrgimael

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.

techericb avatar Jan 24 '20 18:01 techericb

The rollback of the commit 4b3c6ae does not work for me. Any other ideas?

djschilling avatar Mar 23 '20 20:03 djschilling

Any updates on this, guys? I am also experiencing this issue.

SpaghettiC0des avatar Apr 11 '20 14:04 SpaghettiC0des

The rollback does not resolve the issue for me. any updates?

hb12devtn avatar Apr 18 '20 13:04 hb12devtn

@hampustagerud any updates on that?

3luyka avatar Jun 09 '20 09:06 3luyka

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 avatar Aug 01 '20 22:08 vrgimael

@vrgimael That's not the fix... That's the commit that broke this in the first place...

ItsNoHax avatar Aug 06 '20 11:08 ItsNoHax

@vrgimael @ItsNoHax , can canfirm @ItsNoHax words. Reverting patch solves the problem for me

Reeywhaar avatar Nov 27 '20 22:11 Reeywhaar

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 avatar Aug 19 '21 13:08 jwh-hutchison

@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.

Reeywhaar avatar Oct 16 '21 23:10 Reeywhaar