Crop image using a bounding box react-native-camera - react-native

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

Related

How do you scale images/sprites properly in Godot?

I'm trying to create a 2D cross-platform game (primarily for android & ios in portrait mode, however compatibility with a tablet/desktop would be a bonus) and I'm trying to wrap my head around scaling of my sprites.
I've looked online, and I've ended up setting the following in my Project Settings > Stretch
'Mode' : 2D
'Aspect' : keep-height.
According to https://www.mydevice.io the viewport of my android phone is 360 x 640px (the standard 16:9 ratio for mobiles). But obviously phones/tablet screens come in all sorts of dimensions.
If I wanted to create a sprite with a width exactly 1/3rd of that of my screen/viewport, how should I go about doing this? Should I be creating multiple sprites of various dimensions (in say, GraphicsGale) to account for different screen sizes, or should I be purely doing this scaling in Godot?
I know there's a 'scale' property in Godot, but I can't see a way of setting my image width and height via pixels or by a percentage of the viewport.
Have you tried setting the sprite size depending on the viewport height and width ?
$sprite.size.x = get_viewport().size.x * 0.33
$sprite.size.y = get_viewport().size.y * 0.33
You can check out this reddit post if this is not working.

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.

How to detect if screen has rounded corners in react-native

How can I detect whether device screen has rounded corners and also estimate the radius of the corners (if possible) ?
I want to modify my view more typically cardview to adapt these screens. I have successfully retrieved the screen width and height by using Dimensions
width: Dimensions.get('window').width,
height: Dimensions.get('window').height
I am not able to adapt my parent view according to the curves at 4 corners with above approach. If I give static radius to the parent view it give bad look & feel on rectangular screens and it's not acceptable.
One approach I thought of is generate a list of all devices with rounded corners and apply border radius to only these devices. But it's harder to maintain the list and adapt the list with newcomers in the market.
Can anyone help me with it ? Any sort of approach or guideline will really help me. Thank you in advance
After struggling with it, I came with a much easier solution that why shouldn't I ask user whether he/she has rounded cornered screen when the app starts first time and later giving an option in settings under my app to change whenever user wanted.
I stored user's selection in local storage and modified my view based on that flag. Now I don't have to maintain a list of all devices instead it will cover all use cases.
Currently there is no option to get corner radius from Dimensions. There is only 4 values in Dimensions object given below.
{ width: 384, height: 592, scale: 2, fontScale: 1 }
Even if you have answered and accepted your own answer already, it is not really a solution for the original post.
I think basically all phones with notches have round corners while devices without notches typically do not have round corners. If you have notches, you have an inset in your Safe Area. If you are using react-native-safe-area-context for example, you can get the insets with
const insets = useSafeAreaInsets();
const hasNotch = insets.top || insets.bottom || insets.right || insets.left;

Adobe Animate CC Canvas (CreateJS) vector graphics becomes blurry on scale up

So I am new to this next-gen Flash application they call "Adobe Animate CC" and I am trying to create an interactive map scene... very basic. If you click on the USA it should zoom in. Click again it should zoom out.
The issue I am having is that even though my map was imported from an SVG file -- and from what I can tell when residing in the "Adobe Animate CC" workspace it retains its vector data -- when I apply the scale tween using CreateJS the edges of the graphic become very pixelated.
Here's the code I am using:
var _this = this;
_this.stop();
_this.america.addEventListener("click", zoomMap);
function zoomMap(event) {
createjs.Tween.get(exportRoot.world1).to({scaleX: 10, scaleY: 10, x: 4000, y: 1000}, 1000);
}
And here are some images of the pixelated result:
Even more disconcerting is that that blue-green circle is a native circle object inside a symbol. Not an svg. I would expect that at least that would stay crisp under transformation.
Is this unavoidable? Is the application caching bitmap versions of my vector files on export? Can I stop this? Can I force a re-render of the vector file during and after my tween? Is there any way around this? Does this application even really support vector graphics?
Animate might be exporting as images, but it shouldn't unless you tell it to. What does your library JavaScript look like? Are any images exported? Maybe search the source for .cache to see if Adobe is doing anything funny under the hood.
If the map is an SVG source: Unfortunately, only the only SVG support in EaselJS (which underlays the Animate export) is for svg as a "bitmap source". This means it is being treated as an image of a specific dimensions, and scaling it past "100%" will interpolate the details.
It might be possible to load it as a larger bitmap, and scale it down to start, but that will:
make it much larger in memory
still only let you scale so much
Another option is to import the SVG asset into Adobe Animate, which should convert it to a vector graphic. If it is vector in EaselJS, you can scale it as much as you want, because it uses Canvas vector APIs to draw, instead of an image source.
You mentioned that the green circle is native (I assume a shape in Animate?). Are you sure its not being exported as an image, instead of a shape? Are you caching anything?
Hope that helps!

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!