ImageView changing image slow in tablet - android-imageview

I am writing a keyboard replacement app for Android, and based on the user's touch, a different image is rendered in a specified ImageView. I am running into an issue with two things:
1) With the tablet, I can move my finger quicker, so the onTouch method I am using is losing touch events. For instance, in a quick circle, my touch pattern looks like this:
x: 590.0 y: 178.0
x: 488.0 y: 172.0
x: 233.0 y: 416.0
x: 394.0 y: 451.0
x: 575.0 y: 199.0
x: 450.0 y: 170.0
x: 341.0 y: 193.0
(using Logcat and event.getX(), event.getY())
Is there a better way track events with a tablet to pick up more events?
2) The changing image in the imageview renders slower than in the phone app. Is there a way to fix this, or is it a limitation of the tablet? I change the imageview by:
myImageView.setImageDrawable(image);
Any ideas?

You could try a custom view and onTouch event. You would have to pre-load all your buttons states as bitmaps.
See this example: Make certain area of bitmap transparent on touch

I get much better performance pre-decoding it via BitmapFactory, which should look something like this (untested):
myBitmap=BitmapFactory.decodeResource(myImageView.getContext().getResources(),R.res.drawable.my_image);
//later
myImageView.setImageBitmap(myBitmap);

Related

Crop image using a bounding box react-native-camera

i have a camera view in my app in which there is a resizable bounding box
now after taking the image i want to able to only take the part of the image that was focused so i used ImageEditor from this react-native library
the issue i have i am not getting consistent results on the cropping i currently have th following values
boxX staring X position of the bounding box; boxY staring Y position of the bounding box; boxWidth width of the bounding box; boxHeight height of the bounding box.
i used the following code at first
ImageEditor.cropImage(image.uri,
{
offset: {x: boxX, y: boxY},
size: {width: boxWidth, height: boxHeight},
}
)
this gives a very pixalated and very wrong cropping of the image i dont know why, then i added some calculations to it by adding new variables like the image width and height and also the devices width and height and came up with this code:
ImageEditor.cropImage(data.uri,
{
offset: {x: ((boxX)/deviceWidth)*data.width, y:((boxY)/deviceHeight)*data.height},
size: {width: boxWidth/deviceWidth*imageWidth, height: boxHeight/deviceHeight*imageHeight},
}
)
this is much better but the cropping is still wrong on Android but on iOS this seems to work fine and accurate, my question is how can i achieve this please let me know if there is any calculations i should do to get consistent results.
For image cropping I think you should try:
1) https://github.com/ivpusic/react-native-image-crop-picker
It is more used, looks to be maintained better and could simplify your work.
or
2) a picker and https://github.com/prscX/react-native-photo-editor
if you want more complicated editing.
or
3) if you are satisfied with your current library for iOS, use one of the 2 from above only for android.
Note: this is a known issue of the react-native-image-editor, especially for android. The discussions and possible workarounds that could work on some devices can be found here:
https://github.com/callstack/react-native-image-editor/issues/54#issuecomment-754688978

getUserMedia (Selfie) Full Screen on Mobile

I've the following constraints which are working perfectly fine over Chrome in Desktop (simulating mobile resolution)
const constraints = {
audio: false,
video: {
width: screen.width,
height: screen.height
}
};
navigator.mediaDevices.getUserMedia(constraints).then(stream => {})
However when actually trying this on iPhone / Safari the camera doesn't respects this at all and gets super small or distorted - removing the width / height from the constraints makes it better ratio but not full screen at all, just centralized.
I've also tried with min / max constraints without lucky.
Is there any way to get this working on iPhones?
I have built a few AR Websites which are mobile first. When you request a resolution the web browser sees if the resolution exists, and if it doesn't it then decides if it should emulate the feed for you. Not all browsers do emulation (even though it is part of the spec). This is why it may work in some browsers and not others. Safari won't emulate the resolution you are asking for with the camera you have picked (I presume the front).
You can read more about this here (different problem, but provides a deeper explaination): Why the difference in native camera resolution -vs- getUserMedia on iPad / iOS?
Solution
The way I tackled this is:
Without canvas
Ask for a 720p feed, fallback to 480p feed if 720 gives an over-constrained error. This will work cross-browser.
Have a div element which is 100% width and height, fills the screen, and sets overlay to hidden.
Place the video element connected to the MediaStream inside, make it 100% height of the container. The parent div overlay hidden will in effect crop the sides. There will be no feed distortion.
With canvas
Do not show the video element, use a canvas as the video view. Make the canvas the same size as your screen or the same aspect ratio and use CSS to make it fill the screen (latter is more performant).
Calculate the top, left, width and height variables to draw the video in the canvas (make sure your calculation centers the video). Make sure you do a cover calculation vs fill. The aim is to crop the parts of the video which do not need to be shown (I.e. like the descriptions of various methods in https://css-tricks.com/almanac/properties/o/object-fit) . Example on how to draw video into a canvas here: http://html5doctor.com/video-canvas-magic/
This will give you the same effect of what you are looking for. Production examples of something similar.
https://www.maxfactor.com/vmua/
https://demo.holitionbeauty.com/
P.s. when I get time I can code an example, short on hours this week.
There are a couple of quirks on mobile gUM() you need to know about.
First, if the device is in portrait orientation things work weirdly. You need to swap the width and height. So, let's say you're on a 480x640 device (do those even exist? who cares? it's an example). To get the appropriate size video you need
const constraints = {
audio: false,
video: {
width: screen.height,
height: screen.width
}
};
I can't figure out exactly why it's like this. But it is. On iOS and Android devices.
Second, it's hard to get the cameras to deliver exactly the same resolution as the device screen size. I tweak the width and height to make them divisible by eight and I get a decent result.
Third, I figure the sizes I need by putting a <video ...> tag in my little web app with CSS that makes it fill the browser screen, then querying its size with
const rect = videoElement.getBoundingClientRect()
const width = rect.width > rect.height ? rect.width : rect.height
const height = rect.width > rect.height ? rect.height : rect.width
This makes the mobile browser do the work of figuring out what size you actually need, and adapts nicely to the browser's various toolbars.

Programatically turn screen upside-down in react-native

I am building a two player game.
When player A makes a turn, the screen should turn upside down for player seated on the opposite side.
I tried using transform on a View, but think that only works on text.
So I am looking for a solution to either
a. Keep the device orientation, but turn it upside down by 180 degrees.
b. Rotate the root view on my app by 180 degrees
I would appreciate suggestions.
Correction - turning the view using transform worked for me.
It was merely not working when in storyboard mode (not sure why).
Below works!
const rotateView = {
flex: 1,
transform: [{
rotate: '-180deg'
}],
}
View is rotated by 180 degrees.

How to use image qualifiers in WebView in Windows 8 without specifying height and width

I have a webview in my Windows 8 (Metro) app that I will use to display much of my content. The webview automatically scales any CSS dimensions to 100%, 140%, and 180%. This means that when I specify:
#square {
width:100px;
height:100px;
background-color:white;
}
...we get a nice square that is 100, 140, or 180 device pixels, depending on the display. So far, so good.
Further, if I supply an image that is 100px square, the OS correctly scales it to 140 and 180 as appropriate on higher density screens.
Further still, if I supply versions of the image that are 100px, 140px, and 180px, and I indicate the size as 100px in the CSS, like this:
#my_image {
width:100px;
height:100px;
}
The OS uses an area that is 100 dp square (that is to say, 100, 140, or 180 device pixels square as appropriate) and automatically selects the right image. So far, still good.
The problem occurs when I try to use images with density qualifiers without naming a literal size in CSS. Why would I want to do this? I have lots of images with variable sizes. I'd prefer to just allow the webview to infer the appropriate size based on the dimensions of the images.
So I expect that if I supply 100, 140, and 180 versions of an image, the OS will be smart enough to say, "Ah, this is a 100-dp image that happens to have additional versions available."
What actually happens, however, is this.
I supply images:
square.scale-100.png
square.scale-140.png
square.scale-180.png
The OS picks the appropriate one. On a 180% screen, it picks the version that is 180 device pixels square. Recall, however, that we made it 180 device pixels because it was the 180% version of the 100 dp image. We want it to actually take up only 100x100 dp of space.
However, the OS takes 180 as the size in DP. So it scales it by 180% again.
How can I avoid this double-scaling? Any pointers would be awesome!
We've figured out a solution to this that I'm sharing in case it helps anyone else.
The solution is to include dynamically written CSS that zooms images using a factor that is the inverse of the current scale factor.
The current scale factor is available to app code, but not to Javascript running in a WebView. From the point of view of such Javascript, all dimensions are already scaled. So, for example, window.devicePixelRatio is no good -- it always returns 1.
You can obtain the current scale factor in app code like so:
ResolutionScale scale = DisplayInformation.GetForCurrentView().ResolutionScale;
From this, you can derive a zoom factor like this:
float imageZoomFactor = 1.0F;
switch (DisplayInformation.GetForCurrentView().ResolutionScale)
{
case ResolutionScale.Scale140Percent:
imageZoomFactor = (1.0F / 1.4);
break;
// etc
}
You can pass this into your Javascript in one of several ways. Since we were reading HTML from the app bundle and using WebView.NavigateToString, we created a placeholder in the Javascript that we replace in the string. The Javascript looks like this:
<!-- Scale images so that their sizes map 1:1 to device pixels -->
<script type="text/javascript" language="javascript">
document.write('<style type="text/css">img {zoom:' + HOSTING_CODE_SUPPLIED_ZOOM_FACTOR + ';}</style>');
</script>
Now when you use an image tag without specifying explicit dimensions, it works properly. For example, an image that is 180px x 180px, created for the purpose of being displayed at 100dp x 100dp in 180% mode, is displayed correctly using 180 device pixels.
One caveat is that if you have CSS that explicitly sizes an image, you need to cancel the zoom. So, for example:
#my_explicit_image {
width:200px;
height:200px;
zoom:normal; /* cancel the zoom on img since we're being explicit */
}
If you don't include the last line, the zoom specified on img will apply to the dimensions you specify here.
Hope this helps someone out there!

What's the best way to convert iPad app to handle both view modes?

I have an existing iPad app (XCode 4.6, iOS 6.2, ARC and Storyboards). It is currently in the App Store in Portrait mode only; I have had several requests for landscape mode. Unfortunately, all of the lines, etc are drawn using CG methods, controlled mathematically. This is what it looks like in portrait mode:
and this is what it looks like in landscape mode:
My question is: where can I find some good docs that will give me the basic steps I need to convert this app for both modes, knowing that the drawing is controlled mathematically?
If it is controlled mathematically, the best way is to refer all coordinates to the dimensions of the parent view, specifically to the property self.view.bounds that changes with the rotation of the device.
Then you have to redraw the interface when the orientation has been changed. A good way to do it is inside the method:
-(void)viewWillLayoutSubviews
If did some custom views in the past with CG methods and the best way is to refer everything to the bounds. In that way when you change the screen size, either by rotating or by using it on the iPhone it works without modifications.
update
Imagine that you have a point at (76.8, 512.0) this is precisely in an iPad and portrait orientation, a 10% of the width and a 50% of the height.
So for every pair of coordinates instead of using them with absolute numbers you have to replace them by fractions of the dimensions of the parent view:
// old drawing method
CGPoint oldPoint = CGPointMake(76.8, 512.0);
// new drawing method
CGFloat W = self.view.bounds.size.width;
CGFloat H = self.view.bounds.size.height;
CGPoint newPoint = CGPointMake(0.1 * W, 0.5 * H) // 76.8 = 0.1 * 768; 512 = 0.5 * 1024
In this second case; when you change the orientation so will the bounds change and the coordinate will get new values, but the proprotion will be the same as in the other orientation, 10% in horizontal and 50% in vertical.
You get the idea.