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

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!

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

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.

cytoscape.js: set node label font-size less than one

I find great support for very small edge width and node border width, very useful when we zoom in deeply:
cy.edges().style({"width": 0.01})
cy.nodes().style({“border-width”: 0.01})
but font-size is less malleable: any font-size less than 1 appears to be clamped to 1. Thus the last three of the following commands, executed from the javascript console, produce the same result:
cy.nodes().style({"font-size": 10}) // big font
cy.nodes().style({"font-size": 1}) // much smaller
cy.nodes().style({"font-size": 0.1}) // unchanged
cy.nodes().style({"font-size": 0.01}) // unchanged
In each case (using the last as an example) the font-size property seems to be properly assigned:
cy.nodes().style("font-size”) // “0.01px"
But the rendered node size remains at 1. Any ideas?
Thanks!
Paul
This has been answered on Github. This is an issue that some browsers have, and there's nothing that can be done in the library to change the browser's behaviour
--
Copied from Github : https://github.com/cytoscape/cytoscape.js/issues/1173
This is a limitation of how browsers implement font rendering in canvas. There's nothing we can do in this case on the library side.
The only suggestion I have is to scale up your styles. Multiply your sizes by a factor such that the font size is at least 1px. While font sizes can't scale, the zoom level can scale arbitrarily. Your zoom levels will be different, but zoom is just a relative measure anyway.

How does Safari calculate size of svg objects?

How does Safari determine what size to output an svg in the following scenario;
SVG code
viewBox 0 0 800 800
height 100%
width 100%
css
svg width 100%
containing div width 60%
Safari outputs a much smaller svg than the 60% of screen, ok this is a bug. But what determines the size of this smaller svg, it has no connection to anything I can think of.
Just to give some background info. Safari needs both width and height in px for it to do what you want. % don-t work. But it does output the svg, and so it must make a decision somewhere about its size.
It's not a bug you're seeing. That's the correct behavior. The browser by default scales the SVG viewbox (careful with the terminology now, we're not talking about the browser viewport) to fill the CSS-determined dimensions of the SVG element. The fill behavior is determined by the SVG preserveAspectRatio attribute. By default it's set to meet, which keeps the whole SVG viewable, and the aspect ratio preserved. The alternative is slice which scales the viewbox up to cover the element, even when that means cropping. (slice behaves similarly to background-size:cover in CSS3.)
What you need to do is:
a) Don't declare explicit height or width in the SVG file. If your graphics editor is generating them, just go in by hand and delete them. According to the spec, if no width and height are specified, a value of 100% is assumed, so your pseudocode is redundant at best.
b) Make sure you're setting an explicit height for the svg element in CSS. I recommend developer or Canary builds of Chrome for troubleshooting responsive svg sizing, as there is a bug in Chrome 18 Dev Tools that has since been fixed. Once you've got it working in Chrome, it will almost certainly also work in Safari.
c) Figure out how you want to set preserveAspectRatio and manually edit the svg to put in the declaration.
If you're still having trouble, please post a jsfiddle. It's much easier for other people to comment on.