Image orientation issue in android react native - react-native

i'm using CameraRoll.getPhotos for get photos from gallery.
import {
CameraRoll,
} from 'react-native';
CameraRoll.getPhotos(fetchParams).then((data) => {
});
I have a problem with the orientation of the images on some android phones. I have been able to detect what happens in most SAMSUNGs.
It has an orientation depending on the way you take the picture.
portrait with home button in bottom position: 90º
landscape with home button left position: 180º
portrait with home button in top position: 270º
landscape with home button right position: 0º
Related with this issue
Base on CameraRoll Documentation the orientation value is not returned by getPhotos.
I'm try with:
transform: [{ rotateX: '0deg' }, { rotateY: '0deg' }] or rotate: '0deg'
Using react-native-media-meta for get metadata info (not works)
Use another image component instead native Image
but notting works. :(
The problem is that the images appear rotated in my application, but in the native gallery ignores the degree of rotation they have and shows them correctly with 0º.
Example:
In this case the image appear with 90º and it's showed perfectly by native gallery but bad in my app.
- Is there any way to detect the current rotation of the image?
- Can the <Image> component be forced in some way to place the orientation at 0º?
UPDATE:
i found a library this module and its possible get the orientation of image and with that can fix this problem. But this process is very delayed and affect considerably the perfomance.

Related

How can I use react-native-gesture-handler to handle react-native-skia touches inside a ScrollView?

I have a ScrollView containing several graphs made with react-native-skia. The graphs are interactable, i.e. I can touch them and move an indicator on the graph along the x-axis of the graph.
My issue is that the whenever the ScrollView events fire (i.e. we scroll up/down), then the graph touch events are ignored which makes for bad UX.
Demo:
Here's a Snack with a reproducible demo: https://snack.expo.dev/#jorundur/supportive-raisins
FYI: For some reason for me the Canvas disappears after 1 second in the Snack, but if you make any change in the file and save (such add a newline somewhere), then it appears. It's fine if you run this locally. But that's some other problem we can ignore for the purpose of this discussion.
Description:
The demo is a react-native ScrollView large enough to make sure we have to scroll, the top component is a graph using react-native-skia. If we drag the cursor in the graph around, then the UX gets bad pretty quickly as the graph touch events seem to be ignored as soon as any vertical scrolling happens. I've tried playing around with ScrollView from react-native-gesture-handler but without luck.
To me, the expected behaviour would be for the graph to be interactable even while scrolling. I.e. if I'm pressing the graph and move my finger diagonally up/down I would expect the ScrollView to scroll and the graph cursor also to change its position accordingly. (I say diagonally since a straight vertical movement wouldn't change the cursor position in this graph.)
Much appreciated if anyone has any ideas on how to solve this! I couldn't work out how to do it via GestureDetector from react-native-gesture-handler like I've heard suggested.
Possible solution (?):
What I think I need to do is remove the onTouch={touchHandler} which I'm using currently in the react-native-skia Canvas component and instead get those touches via gesture detection from react-native-gesture-handler. I then need to make those gestures work simultaneously with the parent ScrollViews scroll event gestures. I've not had any luck implementing that unfortunately.
The solution was to do the following:
Don't use onTouch on Canvas, instead detect gestures via react-native-gesture-handler
Create a gesture and add a ref to it
Add the simultaneousHandlers prop to the ScrollView and use the ref there
This tells the ScrollView that its events should not be blocked by the touch events from the ref
To reiterate, what I wanted to do was to have the touch events of a ScrollView work simultaneously with touch events from a react-native-skia Canvas child component.
Code (relevant bits):
import * as React from 'react';
import {
GestureHandlerRootView,
ScrollView // Note that this is not imported from react-native
} from 'react-native-gesture-handler';
const App = () => {
// Create ref for the ScrollView to know what other gestures it should work simultaneously with.
// My use case required pan but this can be swapped for other gestures.
const panGestureRef = React.useRef<GestureType>(Gesture.Pan());
// The logic that used to be in `onTouch` on the Canvas is now here
const panGesture = Gesture.Pan()
.onChange((e) => {
// Do stuff, also use the other callbacks available as needed
})
.withRef(panGestureRef);
return (
<GestureHandlerRootView style={{ flex: 1 }}>{/* Don't forget this! It should be at the root of your project. */}
<ScrollView simultaneousHandlers={[panGestureRef]}>
<GestureDetector gesture={panGesture}>
<Canvas style={{ width: 200, height: 200 }}>
{/* Your interactive react-native-skia magic */}
</Canvas>
</GestureDetector>
</ScrollView>
</GestureHandlerRootView>
);
};
export default App;

React native zoomable scale not work in ios?

I am using react-native-photo-view-ex library to zoom in and out the images. After zooming the image I am getting scale size from onScale callback function.After than I saved this picture and when I want to open saved image again for re-edit with same scale size as I saved the image displayed very small.I adjust minZoom = 0.5 and maxZoom = 10.
This code works perfectly in android and when open images for re-edit in android image displayed on accurate position with given scale. Also I have implemented this feature with gesture handler and ScrollView Zoomable but get same results. Can anyone help me?
<PhotoView
source={{uri: selectedData.url}}
scale={imageScale}
minimumZoomScale={0.5}
maximumZoomScale={10}
onScale={e => {
setImage(e.nativeEvent.scale);
}}
onLoad={() => setImageScale(selectedData.scale, false)}
style={
styles.resizeImageWrapper
}
/>

How do I handle scaling issues in a React Native app between tvOS and Android TV?

Native resolution for Apple TV seems to be 1920x1080 (as expected) but for Android TV / Fire TV it seems to be 961.5022957581195x540.8450413639423 (according to Dimensions.get('window')).
So, when I run my app on Apple TV everything looks fine. But when I run it on an Android TV nothing fits on the screen.
Is there a way to force the Android TV to shrink everything? Or do I have to create two different style sheets for the different devices to change font sizes and dimensions of all my components?
We use a different approach, on the base Application class for tv we add this
class TvApplication extends Application {
#Override
protected void attachBaseContext(Context base) {
Configuration configuration = new Configuration(base.getResources().getConfiguration());
configuration.densityDpi = configuration.densityDpi / 2;
Context newContext = base.createConfigurationContext(configuration);
super.attachBaseContext(newContext);
}
}
with this, we have consistent width & height when using dimensions, and we can use the same styling values on all platforms without doing any manipulation on the JS side.
it's not perfect, but it's more convenient when building for multiple platforms
Use Platform.OS to check for platform and use margin property in styles to get the content right on screen in android. This is normal behavior in android tv.
You have PixelRatio and Dimensions for this purpose in React Native. Along with this you need to use a RN module react-native-pixel-perfect, this keeps your app pixel perfect across all devices, quickly and easily
import {PixelRatio, Dimensions} from 'react-native';
import {create} from 'react-native-pixel-perfect';
let displayProps = {
width: PixelRatio.roundToNearestPixel(
Dimensions.get('window').width * PixelRatio.get(),
),
height: PixelRatio.roundToNearestPixel(
Dimensions.get('window').height * PixelRatio.get(),
),
};
let perfectSize = create(displayProps);
Now always pass your size in pixels to this method to get original device pixels based on the devices.
const styles = StyleSheet.create({
container: {
width: perfectSize(500),
height: perfectSize(300)
}
});
Your container will adapt to the devices correctly. Based on their screen resolution.
In case if you have a minimum height x width to support but some devices are less than the minimum screen resolution and you want to still achieve the same results in those devices. Then you can set the minimum screen resolution on this function like below.
let displayProps = {
width: PixelRatio.roundToNearestPixel(
Math.max(1920, Dimensions.get('window').width * PixelRatio.get()),
),
height: PixelRatio.roundToNearestPixel(
Math.max(1080, Dimensions.get('window').height * PixelRatio.get()),
),
};
So in my case if the screen resolution is less than 1920x1080 lets say 720p devices then this will help rendering the UI in 1920x1080.

How to make React-Native "scrollTo" behave identically on Android than on iOS when ScrollView is small

Consider this simple ScrollView.
On iOS, clicking on the text will but the text to the top because scrollTo({ y: 250 }) scrolls even if end of scrollView is reached.
On Android, the text doesn't move.
How to get on Android the same behavior we have on iOS?
You can work around this by adding padding to the contentContainerStyle of the ScrollView. A good starting point would be to add padding equal to the height of the device's screen.
import { Dimensions } from 'react-native';
const ANDROID_SCREEN_HEIGHT_PADDING = Dimensions.get('window').height;
then, when rendering:
<ScrollView
contentContainerStyle={{paddingBottom: ANDROID_SCREEN_HEIGHT_PADDING}}>
...
</ScrollView>
You could use this for necessary extra Android padding in every direction. If you are using horizontal={true}, for example, you could add padding equal to the width of the screen and add it to the paddingLeft style property to get the intended scrolling behavior on Android.
This behavior is due to the underlying implementation of ScrollView on Android in React-Native. See also:
React native Android ScrollView scrollTo not working

Titanium How to push one window to another having push view controller effect ( animation like in iphone)

i am new to titanium. Does anybody know how to push one window to another having push view controller effect (animation like in iphone).since in the documentation most are modal presentation. Is there push view like we have on iphone?Thanks.
We have been using animation to slide windows in on Android, simulating the iOS feature. We ended up making our own window manager to manage the differences, but I have extracted the relevant animation code.
We use windows in a navigation group on iOS, and views on a single window on Android.
We have a single view for the client area called vwBody, which you will see referenced here. This is the client area under our composed navigation header. If you are not simulating the entire navigation group feature then this may just be the main window.
In any case, we compose the incoming view showing just one pixel on the right side of the client area:
// vwBody is preexisting view defining the client area
var newview = Ti.UI.createView( {
name: name,
left: vwBody.size.width - 1,
top: 0,
width: vwBody.size.width,
height: vwBody.size.height } );
// compose the view here
vwBody.add(newView);
newView.addEventListener('postlayout', waitForWindowPaint);
This allows the view to compose correctly, as Android/Ti won't actually start drawing until the view is on-screen. We wait for the postlayout event before proceeding with the animation. Once composition is complete, we animate the view in:
function waitForWindowPaint()
{
newView.animate({ left: 0, duration:300 },
function(){ /* whatever to do post animation */ });
newView.removeEventListener("postlayout", waitForWindowPaint);
}
The view is now ready for user interaction.
When we close the view, we animate it back out:
newView.animate({ left: curWin.size.width, opacity: 0, duration:300 },
function(){ vwBody.remove(newView); });
We hook both the android:back and header back button to close the view.